Compare commits

...

41 Commits

Author SHA1 Message Date
Nicolas Grekas
19090917b8 Merge branch '3.4' into 4.1
* 3.4:
  Fixed typo
  Fix ini_get() for boolean values
  SCA: fixed broken tests
  SCA: applied code style as per guidelines
  SCA: minor code tweaks
2018-10-31 10:09:42 +01:00
Nicolas Grekas
fe9793af00 Merge branch '2.8' into 3.4
* 2.8:
  Fixed typo
  Fix ini_get() for boolean values
2018-10-31 10:06:03 +01:00
François-Xavier de Guillebon
6a198c52b6 Fix ini_get() for boolean values 2018-10-30 17:24:01 +01:00
Nicolas Grekas
e3f76ce619 Merge branch '3.4' into 4.1
* 3.4:
  CS fix
  [Debug] fix compat with PHP 7.3
2018-10-02 18:36:10 +02:00
Nicolas Grekas
0a612e9dfb Merge branch '2.8' into 3.4
* 2.8:
  CS fix
  [Debug] fix compat with PHP 7.3
2018-10-02 18:33:53 +02:00
Nicolas Grekas
087890e02f [Debug] fix compat with PHP 7.3 2018-10-02 18:22:14 +02:00
Gabriel Caruso
65d41d1696 [CS] Enforces null type hint on last position in phpDocs 2018-10-02 00:12:00 -03:00
Nicolas Grekas
b4a0b67dee Merge branch '3.4' into 4.1
* 3.4:
  [Debug] Fix false-positive "MicroKernelTrait::loadRoutes()" method is considered internal"
  [Console] Fixed boxed table style with colspan
  parse numbers terminated with decimal separator
  fail reverse transforming invalid RFC 3339 dates
2018-09-22 21:04:12 +02:00
Nicolas Grekas
b70cfaae39 [Debug] Fix false-positive "MicroKernelTrait::loadRoutes()" method is considered internal" 2018-09-22 20:25:03 +02:00
Nicolas Grekas
a037ae518a Merge branch '3.4' into 4.1
* 3.4:
  Fix CS
  Allow reuse of Session between requests
  [MonologBridge] Re-add option option to ignore empty context and extra data
  [Lock] remove useless code
  [PhpUnitBridge] fix disabling DeprecationErrorHandler using phpunit.xml file
  Provide debug_backtrace with proper args
  [DI] fix infinite loop involving self-references in decorated services
  forward false label option to nested types
  forward the invalid_message option in date types
2018-09-21 14:49:42 +02:00
Nicolas Grekas
d7b459ba7b Merge branch '2.8' into 3.4
* 2.8:
  Fix CS
  Allow reuse of Session between requests
  Provide debug_backtrace with proper args
  forward false label option to nested types
  forward the invalid_message option in date types
2018-09-21 14:47:54 +02:00
Nicolas Grekas
4fd77efcd4 Fix CS 2018-09-21 14:46:38 +02:00
Nicolas Grekas
ede2c4b8fd Merge branch '3.4' into 4.1
* 3.4:
  [Debug] fix detecting overriden final/internal methods implemented using traits
  [Controller][ServiceValueResolver] Making method access case insensitive
2018-09-09 11:23:09 +02:00
Nicolas Grekas
87cecce74b [Debug] fix detecting overriden final/internal methods implemented using traits 2018-09-09 11:07:24 +02:00
Nicolas Grekas
47ead688f1 Merge branch '3.4' into 4.1
* 3.4:
  [travis] fix CI for sigchild+Process
  fix merge
  [travis] merge "same Symfony version" jobs in one
  fix merge
  Remove the Expires header when calling Response::expire()
  Allow multidimensional collection in property info
  Allow multidimensional collection in property info
2018-08-03 13:13:38 +02:00
Nicolas Grekas
c4625e7534 Merge branch '2.8' into 3.4
* 2.8:
  [travis] merge "same Symfony version" jobs in one
2018-08-03 12:42:44 +02:00
Nicolas Grekas
cbb8a5f212 [travis] merge "same Symfony version" jobs in one 2018-08-03 11:45:57 +02:00
Nicolas Grekas
9316545571 Merge branch '4.0' into 4.1
* 4.0:
  Enable native_constant_invocation CS fixer
2018-07-26 13:24:31 +02:00
Nicolas Grekas
8d5462cfbc Merge branch '3.4' into 4.0
* 3.4:
  Enable native_constant_invocation CS fixer
2018-07-26 13:22:46 +02:00
Nicolas Grekas
d5a058ff6e Merge branch '2.8' into 3.4
* 2.8:
  Enable native_constant_invocation CS fixer
2018-07-26 13:19:56 +02:00
Nicolas Grekas
d985c8546d Enable native_constant_invocation CS fixer 2018-07-26 13:13:39 +02:00
Nicolas Grekas
38b2f7a11a Merge branch '4.0' into 4.1
* 4.0:
  Alpha-ordering for "use" statements
2018-07-26 11:10:45 +02:00
Nicolas Grekas
eba30e3a78 Merge branch '3.4' into 4.0
* 3.4:
  Alpha-ordering for "use" statements
2018-07-26 11:08:35 +02:00
Nicolas Grekas
13041d84e3 Merge branch '2.8' into 3.4
* 2.8:
  Alpha-ordering for "use" statements
2018-07-26 11:06:28 +02:00
Nicolas Grekas
2f42aa269a Alpha-ordering for "use" statements 2018-07-26 11:03:18 +02:00
Nicolas Grekas
fa0b714b55 Merge branch '4.0' into 4.1
* 4.0:
  Fix Clidumper tests
  Enable the fixer enforcing fully-qualified calls for compiler-optimized functions
  Apply fixers
  Disable the native_constant_invocation fixer until it can be scoped
  Update the list of excluded files for the CS fixer
2018-07-26 10:55:25 +02:00
Nicolas Grekas
fce13776fb Merge branch '3.4' into 4.0
* 3.4:
  Fix Clidumper tests
  Enable the fixer enforcing fully-qualified calls for compiler-optimized functions
  Apply fixers
  Disable the native_constant_invocation fixer until it can be scoped
  Update the list of excluded files for the CS fixer
2018-07-26 10:51:09 +02:00
Nicolas Grekas
34bdb1c801 Merge branch '2.8' into 3.4
* 2.8:
  Fix Clidumper tests
  Enable the fixer enforcing fully-qualified calls for compiler-optimized functions
  Apply fixers
  Disable the native_constant_invocation fixer until it can be scoped
  Update the list of excluded files for the CS fixer
2018-07-26 10:45:46 +02:00
Christophe Coevoet
d070fc2e64 Enable the fixer enforcing fully-qualified calls for compiler-optimized functions 2018-07-24 12:05:38 +02:00
Christian Flothmann
a1f2118ced improve deprecation messages 2018-07-06 16:52:28 +02:00
Nicolas Grekas
46f848122e Merge branch '4.0' into 4.1
* 4.0:
  Bump ext-mongodb to 1.5 on Travis
  Redesign the Debug error page in prod
  [DI] fix dumping deprecated service in yaml
  bumped Symfony version to 4.0.13
  updated VERSION for 4.0.12
  updated CHANGELOG for 4.0.12
  bumped Symfony version to 3.4.13
  updated VERSION for 3.4.12
  updated CHANGELOG for 3.4.12
  bumped Symfony version to 2.8.43
  updated VERSION for 2.8.42
  update CONTRIBUTORS for 2.8.42
  updated CHANGELOG for 2.8.42
2018-06-27 23:05:46 +02:00
Nicolas Grekas
8c2d96aff8 Merge branch '3.4' into 4.0
* 3.4:
  Bump ext-mongodb to 1.5 on Travis
  Redesign the Debug error page in prod
  [DI] fix dumping deprecated service in yaml
  bumped Symfony version to 3.4.13
  updated VERSION for 3.4.12
  updated CHANGELOG for 3.4.12
  bumped Symfony version to 2.8.43
  updated VERSION for 2.8.42
  update CONTRIBUTORS for 2.8.42
  updated CHANGELOG for 2.8.42
2018-06-27 23:04:32 +02:00
Javier Eguiluz
0e3ca9cbde Redesign the Debug error page in prod 2018-06-26 10:45:54 +02:00
Fabien Potencier
47e6788c5b Merge branch '2.8' into 3.4
* 2.8:
  Add note about changed form processing when using PUT requests
  The debug class loader is always loaded by Debug::enable().
  [Intl] Update ICU data to 62.1
2018-06-25 13:10:40 +02:00
Alexander M. Turek
a26ddce7fe The debug class loader is always loaded by Debug::enable(). 2018-06-22 17:01:26 +02:00
Nicolas Grekas
dbe0fad880 Merge branch '4.0' into 4.1
* 4.0:
  [Cache][Security] Use Throwable where possible
  revert #27545
  Update Finder.php
  [FrameworkBundle] remove dead code in CachePoolClearerPass
  Fix security-core cross-dependencies, fixes #27507
  Pass previous exception to FatalErrorException
2018-06-08 11:39:36 +02:00
Nicolas Grekas
ef0abb7ca3 Merge branch '3.4' into 4.0
* 3.4:
  revert #27545
  Update Finder.php
  [FrameworkBundle] remove dead code in CachePoolClearerPass
  Fix security-core cross-dependencies, fixes #27507
  Pass previous exception to FatalErrorException
2018-06-08 11:39:19 +02:00
Nicolas Grekas
a7e8068943 Merge branch '2.8' into 3.4
* 2.8:
  revert #27545
  Update Finder.php
  Fix security-core cross-dependencies, fixes #27507
  Pass previous exception to FatalErrorException
2018-06-08 11:38:38 +02:00
Pascal Montoya
5d48e9c0f8 Pass previous exception to FatalErrorException 2018-06-06 10:34:52 +02:00
Nicolas Grekas
b28fd73fef bug #27281 [HttpKernel] Fix dealing with self/parent in ArgumentMetadataFactory (fabpot)
This PR was merged into the 3.4 branch.

Discussion
----------

[HttpKernel] Fix dealing with self/parent in ArgumentMetadataFactory

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

Applies CS fixes that where merged on 4.0 to 3.4, embeds a fix in ArgumentMetadataFactory, which couldn't deal with self/parent type hints.

Commits
-------

ba5cb1a245 fixed CS
2018-05-16 16:03:39 +02:00
Fabien Potencier
c7d48cc12e fixed CS 2018-05-16 14:49:49 +02:00
27 changed files with 410 additions and 316 deletions

View File

@@ -42,10 +42,10 @@ class Debug
error_reporting(E_ALL);
}
if (!\in_array(PHP_SAPI, array('cli', 'phpdbg'), true)) {
if (!\in_array(\PHP_SAPI, array('cli', 'phpdbg'), true)) {
ini_set('display_errors', 0);
ExceptionHandler::register();
} elseif ($displayErrors && (!ini_get('log_errors') || ini_get('error_log'))) {
} elseif ($displayErrors && (!filter_var(ini_get('log_errors'), FILTER_VALIDATE_BOOLEAN) || ini_get('error_log'))) {
// CLI - display errors only if they're not already logged to STDERR
ini_set('display_errors', 1);
}

View File

@@ -39,11 +39,11 @@ class DebugClassLoader
public function __construct(callable $classLoader)
{
$this->classLoader = $classLoader;
$this->isFinder = is_array($classLoader) && method_exists($classLoader[0], 'findFile');
$this->isFinder = \is_array($classLoader) && method_exists($classLoader[0], 'findFile');
if (!isset(self::$caseCheck)) {
$file = file_exists(__FILE__) ? __FILE__ : rtrim(realpath('.'), DIRECTORY_SEPARATOR);
$i = strrpos($file, DIRECTORY_SEPARATOR);
$file = file_exists(__FILE__) ? __FILE__ : rtrim(realpath('.'), \DIRECTORY_SEPARATOR);
$i = strrpos($file, \DIRECTORY_SEPARATOR);
$dir = substr($file, 0, 1 + $i);
$file = substr($file, 1 + $i);
$test = strtoupper($file) === $file ? strtolower($file) : strtoupper($file);
@@ -52,7 +52,7 @@ class DebugClassLoader
if (false === $test || false === $i) {
// filesystem is case sensitive
self::$caseCheck = 0;
} elseif (substr($test, -strlen($file)) === $file) {
} elseif (substr($test, -\strlen($file)) === $file) {
// filesystem is case insensitive and realpath() normalizes the case of characters
self::$caseCheck = 1;
} elseif (false !== stripos(PHP_OS, 'darwin')) {
@@ -84,7 +84,7 @@ class DebugClassLoader
class_exists('Symfony\Component\Debug\ErrorHandler');
class_exists('Psr\Log\LogLevel');
if (!is_array($functions = spl_autoload_functions())) {
if (!\is_array($functions = spl_autoload_functions())) {
return;
}
@@ -93,7 +93,7 @@ class DebugClassLoader
}
foreach ($functions as $function) {
if (!is_array($function) || !$function[0] instanceof self) {
if (!\is_array($function) || !$function[0] instanceof self) {
$function = array(new static($function), 'loadClass');
}
@@ -106,7 +106,7 @@ class DebugClassLoader
*/
public static function disable()
{
if (!is_array($functions = spl_autoload_functions())) {
if (!\is_array($functions = spl_autoload_functions())) {
return;
}
@@ -115,7 +115,7 @@ class DebugClassLoader
}
foreach ($functions as $function) {
if (is_array($function) && $function[0] instanceof self) {
if (\is_array($function) && $function[0] instanceof self) {
$function = $function[0]->getClassLoader();
}
@@ -128,8 +128,6 @@ class DebugClassLoader
*
* @param string $class The name of the class
*
* @return bool|null True, if loaded
*
* @throws \RuntimeException
*/
public function loadClass($class)
@@ -149,7 +147,7 @@ class DebugClassLoader
}
}
} else {
call_user_func($this->classLoader, $class);
\call_user_func($this->classLoader, $class);
$file = false;
}
} finally {
@@ -183,196 +181,223 @@ class DebugClassLoader
throw new \RuntimeException(sprintf('Case mismatch between loaded and declared class names: "%s" vs "%s".', $class, $name));
}
// Don't trigger deprecations for classes in the same vendor
if (2 > $len = 1 + (\strpos($name, '\\') ?: \strpos($name, '_'))) {
$len = 0;
$ns = '';
$deprecations = $this->checkAnnotations($refl, $name);
foreach ($deprecations as $message) {
@trigger_error($message, E_USER_DEPRECATED);
}
}
if (!$file) {
return;
}
if (!$exists) {
if (false !== strpos($class, '/')) {
throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class));
}
throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
}
if (self::$caseCheck && $message = $this->checkCase($refl, $file, $class)) {
throw new \RuntimeException(sprintf('Case mismatch between class and real file names: "%s" vs "%s" in "%s".', $message[0], $message[1], $message[2]));
}
}
public function checkAnnotations(\ReflectionClass $refl, $class)
{
$deprecations = array();
// Don't trigger deprecations for classes in the same vendor
if (2 > $len = 1 + (\strpos($class, '\\') ?: \strpos($class, '_'))) {
$len = 0;
$ns = '';
} else {
$ns = \substr($class, 0, $len);
}
// Detect annotations on the class
if (false !== $doc = $refl->getDocComment()) {
foreach (array('final', 'deprecated', 'internal') as $annotation) {
if (false !== \strpos($doc, $annotation) && preg_match('#\n \* @'.$annotation.'(?:( .+?)\.?)?\r?\n \*(?: @|/$)#s', $doc, $notice)) {
self::${$annotation}[$class] = isset($notice[1]) ? preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]) : '';
}
}
}
$parent = \get_parent_class($class);
$parentAndOwnInterfaces = $this->getOwnInterfaces($class, $parent);
if ($parent) {
$parentAndOwnInterfaces[$parent] = $parent;
if (!isset(self::$checkedClasses[$parent])) {
$this->checkClass($parent);
}
if (isset(self::$final[$parent])) {
$deprecations[] = sprintf('The "%s" class is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $parent, self::$final[$parent], $class);
}
}
// Detect if the parent is annotated
foreach ($parentAndOwnInterfaces + \class_uses($class, false) as $use) {
if (!isset(self::$checkedClasses[$use])) {
$this->checkClass($use);
}
if (isset(self::$deprecated[$use]) && \strncmp($ns, $use, $len)) {
$type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait');
$verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses');
$deprecations[] = sprintf('The "%s" %s %s "%s" that is deprecated%s.', $class, $type, $verb, $use, self::$deprecated[$use]);
}
if (isset(self::$internal[$use]) && \strncmp($ns, $use, $len)) {
$deprecations[] = sprintf('The "%s" %s is considered internal%s. It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $class);
}
}
if (\trait_exists($class)) {
return $deprecations;
}
// Inherit @final and @internal annotations for methods
self::$finalMethods[$class] = array();
self::$internalMethods[$class] = array();
foreach ($parentAndOwnInterfaces as $use) {
foreach (array('finalMethods', 'internalMethods') as $property) {
if (isset(self::${$property}[$use])) {
self::${$property}[$class] = self::${$property}[$class] ? self::${$property}[$use] + self::${$property}[$class] : self::${$property}[$use];
}
}
}
foreach ($refl->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $method) {
if ($method->class !== $class) {
continue;
}
if ($parent && isset(self::$finalMethods[$parent][$method->name])) {
list($declaringClass, $message) = self::$finalMethods[$parent][$method->name];
$deprecations[] = sprintf('The "%s::%s()" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $class);
}
if (isset(self::$internalMethods[$class][$method->name])) {
list($declaringClass, $message) = self::$internalMethods[$class][$method->name];
if (\strncmp($ns, $declaringClass, $len)) {
$deprecations[] = sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $class);
}
}
// Detect method annotations
if (false === $doc = $method->getDocComment()) {
continue;
}
foreach (array('final', 'internal') as $annotation) {
if (false !== \strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$)#s', $doc, $notice)) {
$message = isset($notice[1]) ? preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]) : '';
self::${$annotation.'Methods'}[$class][$method->name] = array($class, $message);
}
}
}
return $deprecations;
}
public function checkCase(\ReflectionClass $refl, $file, $class)
{
$real = explode('\\', $class.strrchr($file, '.'));
$tail = explode(\DIRECTORY_SEPARATOR, str_replace('/', \DIRECTORY_SEPARATOR, $file));
$i = \count($tail) - 1;
$j = \count($real) - 1;
while (isset($tail[$i], $real[$j]) && $tail[$i] === $real[$j]) {
--$i;
--$j;
}
array_splice($tail, 0, $i + 1);
if (!$tail) {
return;
}
$tail = \DIRECTORY_SEPARATOR.implode(\DIRECTORY_SEPARATOR, $tail);
$tailLen = \strlen($tail);
$real = $refl->getFileName();
if (2 === self::$caseCheck) {
$real = $this->darwinRealpath($real);
}
if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true)
&& 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false)
) {
return array(substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1));
}
}
/**
* `realpath` on MacOSX doesn't normalize the case of characters.
*/
private function darwinRealpath($real)
{
$i = 1 + strrpos($real, '/');
$file = substr($real, $i);
$real = substr($real, 0, $i);
if (isset(self::$darwinCache[$real])) {
$kDir = $real;
} else {
$kDir = strtolower($real);
if (isset(self::$darwinCache[$kDir])) {
$real = self::$darwinCache[$kDir][0];
} else {
$ns = \substr($name, 0, $len);
}
$dir = getcwd();
chdir($real);
$real = getcwd().'/';
chdir($dir);
// Detect annotations on the class
if (false !== $doc = $refl->getDocComment()) {
foreach (array('final', 'deprecated', 'internal') as $annotation) {
if (false !== \strpos($doc, $annotation) && preg_match('#\n \* @'.$annotation.'(?:( .+?)\.?)?\r?\n \*(?: @|/$)#s', $doc, $notice)) {
self::${$annotation}[$name] = isset($notice[1]) ? preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]) : '';
}
}
}
$parentAndTraits = \class_uses($name, false);
if ($parent = \get_parent_class($class)) {
$parentAndTraits[] = $parent;
if (!isset(self::$checkedClasses[$parent])) {
$this->checkClass($parent);
}
if (isset(self::$final[$parent])) {
@trigger_error(sprintf('The "%s" class is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $parent, self::$final[$parent], $name), E_USER_DEPRECATED);
}
}
// Detect if the parent is annotated
foreach ($parentAndTraits + $this->getOwnInterfaces($name, $parent) as $use) {
if (!isset(self::$checkedClasses[$use])) {
$this->checkClass($use);
}
if (isset(self::$deprecated[$use]) && \strncmp($ns, $use, $len)) {
$type = class_exists($name, false) ? 'class' : (interface_exists($name, false) ? 'interface' : 'trait');
$verb = class_exists($use, false) || interface_exists($name, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses');
@trigger_error(sprintf('The "%s" %s %s "%s" that is deprecated%s.', $name, $type, $verb, $use, self::$deprecated[$use]), E_USER_DEPRECATED);
}
if (isset(self::$internal[$use]) && \strncmp($ns, $use, $len)) {
@trigger_error(sprintf('The "%s" %s is considered internal%s. It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $name), E_USER_DEPRECATED);
}
}
// Inherit @final and @internal annotations for methods
self::$finalMethods[$name] = array();
self::$internalMethods[$name] = array();
foreach ($parentAndTraits as $use) {
foreach (array('finalMethods', 'internalMethods') as $property) {
if (isset(self::${$property}[$use])) {
self::${$property}[$name] = self::${$property}[$name] ? self::${$property}[$use] + self::${$property}[$name] : self::${$property}[$use];
}
}
}
$isClass = \class_exists($name, false);
foreach ($refl->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $method) {
if ($method->class !== $name) {
continue;
}
// Method from a trait
if ($method->getFilename() !== $refl->getFileName()) {
continue;
}
if ($isClass && $parent && isset(self::$finalMethods[$parent][$method->name])) {
list($declaringClass, $message) = self::$finalMethods[$parent][$method->name];
@trigger_error(sprintf('The "%s::%s()" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $name), E_USER_DEPRECATED);
}
foreach ($parentAndTraits as $use) {
if (isset(self::$internalMethods[$use][$method->name])) {
list($declaringClass, $message) = self::$internalMethods[$use][$method->name];
if (\strncmp($ns, $declaringClass, $len)) {
@trigger_error(sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $name), E_USER_DEPRECATED);
}
}
}
// Detect method annotations
if (false === $doc = $method->getDocComment()) {
continue;
}
foreach (array('final', 'internal') as $annotation) {
if (false !== \strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$)#s', $doc, $notice)) {
$message = isset($notice[1]) ? preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]) : '';
self::${$annotation.'Methods'}[$name][$method->name] = array($name, $message);
$dir = $real;
$k = $kDir;
$i = \strlen($dir) - 1;
while (!isset(self::$darwinCache[$k])) {
self::$darwinCache[$k] = array($dir, array());
self::$darwinCache[$dir] = &self::$darwinCache[$k];
while ('/' !== $dir[--$i]) {
}
$k = substr($k, 0, ++$i);
$dir = substr($dir, 0, $i--);
}
}
}
if ($file) {
if (!$exists) {
if (false !== strpos($class, '/')) {
throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class));
}
$dirFiles = self::$darwinCache[$kDir][1];
throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
}
if (self::$caseCheck) {
$real = explode('\\', $class.strrchr($file, '.'));
$tail = explode(DIRECTORY_SEPARATOR, str_replace('/', DIRECTORY_SEPARATOR, $file));
$i = count($tail) - 1;
$j = count($real) - 1;
while (isset($tail[$i], $real[$j]) && $tail[$i] === $real[$j]) {
--$i;
--$j;
}
array_splice($tail, 0, $i + 1);
}
if (self::$caseCheck && $tail) {
$tail = DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $tail);
$tailLen = strlen($tail);
$real = $refl->getFileName();
if (2 === self::$caseCheck) {
// realpath() on MacOSX doesn't normalize the case of characters
$i = 1 + strrpos($real, '/');
$file = substr($real, $i);
$real = substr($real, 0, $i);
if (isset(self::$darwinCache[$real])) {
$kDir = $real;
} else {
$kDir = strtolower($real);
if (isset(self::$darwinCache[$kDir])) {
$real = self::$darwinCache[$kDir][0];
} else {
$dir = getcwd();
chdir($real);
$real = getcwd().'/';
chdir($dir);
$dir = $real;
$k = $kDir;
$i = strlen($dir) - 1;
while (!isset(self::$darwinCache[$k])) {
self::$darwinCache[$k] = array($dir, array());
self::$darwinCache[$dir] = &self::$darwinCache[$k];
while ('/' !== $dir[--$i]) {
}
$k = substr($k, 0, ++$i);
$dir = substr($dir, 0, $i--);
}
}
}
$dirFiles = self::$darwinCache[$kDir][1];
if (isset($dirFiles[$file])) {
$kFile = $file;
} else {
$kFile = strtolower($file);
if (!isset($dirFiles[$kFile])) {
foreach (scandir($real, 2) as $f) {
if ('.' !== $f[0]) {
$dirFiles[$f] = $f;
if ($f === $file) {
$kFile = $k = $file;
} elseif ($f !== $k = strtolower($f)) {
$dirFiles[$k] = $f;
}
}
}
self::$darwinCache[$kDir][1] = $dirFiles;
}
}
$real .= $dirFiles[$kFile];
}
if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true)
&& 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false)
) {
throw new \RuntimeException(sprintf('Case mismatch between class and real file names: "%s" vs "%s" in "%s".', substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1)));
}
}
if (isset($dirFiles[$file])) {
return $real .= $dirFiles[$file];
}
$kFile = strtolower($file);
if (!isset($dirFiles[$kFile])) {
foreach (scandir($real, 2) as $f) {
if ('.' !== $f[0]) {
$dirFiles[$f] = $f;
if ($f === $file) {
$kFile = $k = $file;
} elseif ($f !== $k = strtolower($f)) {
$dirFiles[$k] = $f;
}
}
}
self::$darwinCache[$kDir][1] = $dirFiles;
}
return $real .= $dirFiles[$kFile];
}
/**

View File

@@ -11,16 +11,16 @@
namespace Symfony\Component\Debug;
use Psr\Log\LogLevel;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\Debug\Exception\OutOfMemoryException;
use Symfony\Component\Debug\Exception\SilencedErrorContext;
use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;
use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
use Symfony\Component\Debug\FatalErrorHandler\FatalErrorHandlerInterface;
use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;
use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
/**
* A generic ErrorHandler for the PHP engine.
@@ -127,17 +127,17 @@ class ErrorHandler
$handler->isRoot = true;
}
if ($handlerIsNew && is_array($prev) && $prev[0] instanceof self) {
if ($handlerIsNew && \is_array($prev) && $prev[0] instanceof self) {
$handler = $prev[0];
$replace = false;
}
if (!$replace && $prev) {
restore_error_handler();
$handlerIsRegistered = is_array($prev) && $handler === $prev[0];
$handlerIsRegistered = \is_array($prev) && $handler === $prev[0];
} else {
$handlerIsRegistered = true;
}
if (is_array($prev = set_exception_handler(array($handler, 'handleException'))) && $prev[0] instanceof self) {
if (\is_array($prev = set_exception_handler(array($handler, 'handleException'))) && $prev[0] instanceof self) {
restore_exception_handler();
if (!$handlerIsRegistered) {
$handler = $prev[0];
@@ -177,7 +177,7 @@ class ErrorHandler
{
$loggers = array();
if (is_array($levels)) {
if (\is_array($levels)) {
foreach ($levels as $type => $logLevel) {
if (empty($this->loggers[$type][0]) || $replace || $this->loggers[$type][0] === $this->bootstrappingLogger) {
$loggers[$type] = array($logger, $logLevel);
@@ -217,7 +217,7 @@ class ErrorHandler
if (!isset($prev[$type])) {
throw new \InvalidArgumentException('Unknown error type: '.$type);
}
if (!is_array($log)) {
if (!\is_array($log)) {
$log = array($log);
} elseif (!array_key_exists(0, $log)) {
throw new \InvalidArgumentException('No logger provided');
@@ -350,7 +350,7 @@ class ErrorHandler
{
if ($prev !== $this->thrownErrors | $this->loggedErrors) {
$handler = set_error_handler('var_dump');
$handler = is_array($handler) ? $handler[0] : null;
$handler = \is_array($handler) ? $handler[0] : null;
restore_error_handler();
if ($handler === $this) {
restore_error_handler();
@@ -393,7 +393,7 @@ class ErrorHandler
}
$scope = $this->scopedErrors & $type;
if (4 < $numArgs = func_num_args()) {
if (4 < $numArgs = \func_num_args()) {
$context = $scope ? (func_get_arg(4) ?: array()) : array();
} else {
$context = array();
@@ -583,7 +583,7 @@ class ErrorHandler
$previousHandler = null;
$sameHandlerLimit = 10;
while (!is_array($handler) || !$handler[0] instanceof self) {
while (!\is_array($handler) || !$handler[0] instanceof self) {
$handler = set_exception_handler('var_dump');
restore_exception_handler();
@@ -667,7 +667,7 @@ class ErrorHandler
for ($i = 0; isset($backtrace[$i]); ++$i) {
if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {
$lightTrace = array_slice($lightTrace, 1 + $i);
$lightTrace = \array_slice($lightTrace, 1 + $i);
break;
}
}

View File

@@ -26,6 +26,9 @@ class ClassNotFoundException extends FatalErrorException
$previous->getSeverity(),
$previous->getFile(),
$previous->getLine(),
null,
true,
null,
$previous->getPrevious()
);
$this->setTrace($previous->getTrace());

View File

@@ -18,9 +18,9 @@ namespace Symfony\Component\Debug\Exception;
*/
class FatalErrorException extends \ErrorException
{
public function __construct(string $message, int $code, int $severity, string $filename, int $lineno, int $traceOffset = null, bool $traceArgs = true, array $trace = null)
public function __construct(string $message, int $code, int $severity, string $filename, int $lineno, int $traceOffset = null, bool $traceArgs = true, array $trace = null, \Throwable $previous = null)
{
parent::__construct($message, $code, $severity, $filename, $lineno);
parent::__construct($message, $code, $severity, $filename, $lineno, $previous);
if (null !== $trace) {
if (!$traceArgs) {
@@ -31,7 +31,7 @@ class FatalErrorException extends \ErrorException
$this->setTrace($trace);
} elseif (null !== $traceOffset) {
if (function_exists('xdebug_get_function_stack')) {
if (\function_exists('xdebug_get_function_stack')) {
$trace = xdebug_get_function_stack();
if (0 < $traceOffset) {
array_splice($trace, -$traceOffset);

View File

@@ -186,7 +186,7 @@ class FlattenException
*/
public function setTraceFromException(\Exception $exception)
{
@trigger_error(sprintf('"%s" is deprecated since Symfony 4.1, use "setTraceFromThrowable()" instead.', __METHOD__), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use "setTraceFromThrowable()" instead.', __METHOD__), E_USER_DEPRECATED);
$this->setTraceFromThrowable($exception);
}
@@ -241,9 +241,9 @@ class FlattenException
if ($value instanceof \__PHP_Incomplete_Class) {
// is_object() returns false on PHP<=7.1
$result[$key] = array('incomplete-object', $this->getClassNameFromIncomplete($value));
} elseif (is_object($value)) {
$result[$key] = array('object', get_class($value));
} elseif (is_array($value)) {
} elseif (\is_object($value)) {
$result[$key] = array('object', \get_class($value));
} elseif (\is_array($value)) {
if ($level > 10) {
$result[$key] = array('array', '*DEEP NESTED ARRAY*');
} else {
@@ -251,13 +251,13 @@ class FlattenException
}
} elseif (null === $value) {
$result[$key] = array('null', null);
} elseif (is_bool($value)) {
} elseif (\is_bool($value)) {
$result[$key] = array('boolean', $value);
} elseif (is_int($value)) {
} elseif (\is_int($value)) {
$result[$key] = array('integer', $value);
} elseif (is_float($value)) {
} elseif (\is_float($value)) {
$result[$key] = array('float', $value);
} elseif (is_resource($value)) {
} elseif (\is_resource($value)) {
$result[$key] = array('resource', get_resource_type($value));
} else {
$result[$key] = array('string', (string) $value);

View File

@@ -26,6 +26,9 @@ class UndefinedFunctionException extends FatalErrorException
$previous->getSeverity(),
$previous->getFile(),
$previous->getLine(),
null,
true,
null,
$previous->getPrevious()
);
$this->setTrace($previous->getTrace());

View File

@@ -26,6 +26,9 @@ class UndefinedMethodException extends FatalErrorException
$previous->getSeverity(),
$previous->getFile(),
$previous->getLine(),
null,
true,
null,
$previous->getPrevious()
);
$this->setTrace($previous->getTrace());

View File

@@ -57,7 +57,7 @@ class ExceptionHandler
$handler = new static($debug, $charset, $fileLinkFormat);
$prev = set_exception_handler(array($handler, 'handle'));
if (is_array($prev) && $prev[0] instanceof ErrorHandler) {
if (\is_array($prev) && $prev[0] instanceof ErrorHandler) {
restore_exception_handler();
$prev[0]->setExceptionHandler(array($handler, 'handle'));
}
@@ -142,7 +142,7 @@ class ExceptionHandler
$this->caughtBuffer = null;
try {
call_user_func($this->handler, $exception);
\call_user_func($this->handler, $exception);
$this->caughtLength = $caughtLength;
} catch (\Exception $e) {
if (!$caughtLength) {
@@ -208,48 +208,54 @@ class ExceptionHandler
$title = 'Whoops, looks like something went wrong.';
}
$content = '';
if ($this->debug) {
try {
$count = count($exception->getAllPrevious());
$total = $count + 1;
foreach ($exception->toArray() as $position => $e) {
$ind = $count - $position + 1;
$class = $this->formatClass($e['class']);
$message = nl2br($this->escapeHtml($e['message']));
$content .= sprintf(<<<'EOF'
<div class="trace trace-as-html">
<table class="trace-details">
<thead class="trace-head"><tr><th>
<h3 class="trace-class">
<span class="text-muted">(%d/%d)</span>
<span class="exception_title">%s</span>
</h3>
<p class="break-long-words trace-message">%s</p>
</th></tr></thead>
<tbody>
EOF
, $ind, $total, $class, $message);
foreach ($e['trace'] as $trace) {
$content .= '<tr><td>';
if ($trace['function']) {
$content .= sprintf('at <span class="trace-class">%s</span><span class="trace-type">%s</span><span class="trace-method">%s</span>(<span class="trace-arguments">%s</span>)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
}
if (isset($trace['file']) && isset($trace['line'])) {
$content .= $this->formatPath($trace['file'], $trace['line']);
}
$content .= "</td></tr>\n";
}
if (!$this->debug) {
return <<<EOF
<div class="container">
<h1>$title</h1>
</div>
EOF;
}
$content .= "</tbody>\n</table>\n</div>\n";
}
} catch (\Exception $e) {
// something nasty happened and we cannot throw an exception anymore
if ($this->debug) {
$title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $this->escapeHtml($e->getMessage()));
} else {
$title = 'Whoops, looks like something went wrong.';
$content = '';
try {
$count = \count($exception->getAllPrevious());
$total = $count + 1;
foreach ($exception->toArray() as $position => $e) {
$ind = $count - $position + 1;
$class = $this->formatClass($e['class']);
$message = nl2br($this->escapeHtml($e['message']));
$content .= sprintf(<<<'EOF'
<div class="trace trace-as-html">
<table class="trace-details">
<thead class="trace-head"><tr><th>
<h3 class="trace-class">
<span class="text-muted">(%d/%d)</span>
<span class="exception_title">%s</span>
</h3>
<p class="break-long-words trace-message">%s</p>
</th></tr></thead>
<tbody>
EOF
, $ind, $total, $class, $message);
foreach ($e['trace'] as $trace) {
$content .= '<tr><td>';
if ($trace['function']) {
$content .= sprintf('at <span class="trace-class">%s</span><span class="trace-type">%s</span><span class="trace-method">%s</span>(<span class="trace-arguments">%s</span>)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
}
if (isset($trace['file']) && isset($trace['line'])) {
$content .= $this->formatPath($trace['file'], $trace['line']);
}
$content .= "</td></tr>\n";
}
$content .= "</tbody>\n</table>\n</div>\n";
}
} catch (\Exception $e) {
// something nasty happened and we cannot throw an exception anymore
if ($this->debug) {
$title = sprintf('Exception thrown when handling an exception (%s: %s)', \get_class($e), $this->escapeHtml($e->getMessage()));
} else {
$title = 'Whoops, looks like something went wrong.';
}
}
@@ -278,6 +284,14 @@ EOF;
*/
public function getStylesheet(FlattenException $exception)
{
if (!$this->debug) {
return <<<'EOF'
body { background-color: #fff; color: #222; font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 0; }
.container { margin: 30px; max-width: 600px; }
h1 { color: #dc3545; font-size: 24px; }
EOF;
}
return <<<'EOF'
body { background-color: #F9F9F9; color: #222; font: 14px/1.4 Helvetica, Arial, sans-serif; margin: 0; padding-bottom: 45px; }
@@ -362,12 +376,12 @@ EOF;
}
if (\is_string($fmt)) {
$i = strpos($f = $fmt, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: strlen($f);
$i = strpos($f = $fmt, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: \strlen($f);
$fmt = array(substr($f, 0, $i)) + preg_split('/&([^>]++)>/', substr($f, $i), -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i = 1; isset($fmt[$i]); ++$i) {
if (0 === strpos($path, $k = $fmt[$i++])) {
$path = substr_replace($path, $fmt[$i], 0, strlen($k));
$path = substr_replace($path, $fmt[$i], 0, \strlen($k));
break;
}
}
@@ -394,7 +408,7 @@ EOF;
if ('object' === $item[0]) {
$formattedValue = sprintf('<em>object</em>(%s)', $this->formatClass($item[1]));
} elseif ('array' === $item[0]) {
$formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
$formattedValue = sprintf('<em>array</em>(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
} elseif ('null' === $item[0]) {
$formattedValue = '<em>null</em>';
} elseif ('boolean' === $item[0]) {
@@ -405,7 +419,7 @@ EOF;
$formattedValue = str_replace("\n", '', $this->escapeHtml(var_export($item[1], true)));
}
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $this->escapeHtml($key), $formattedValue);
$result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", $this->escapeHtml($key), $formattedValue);
}
return implode(', ', $result);

View File

@@ -11,11 +11,11 @@
namespace Symfony\Component\Debug\FatalErrorHandler;
use Symfony\Component\Debug\Exception\ClassNotFoundException;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\DebugClassLoader;
use Composer\Autoload\ClassLoader as ComposerClassLoader;
use Symfony\Component\ClassLoader\ClassLoader as SymfonyClassLoader;
use Symfony\Component\Debug\DebugClassLoader;
use Symfony\Component\Debug\Exception\ClassNotFoundException;
use Symfony\Component\Debug\Exception\FatalErrorException;
/**
* ErrorHandler for classes that do not exist.
@@ -29,9 +29,9 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
*/
public function handleError(array $error, FatalErrorException $exception)
{
$messageLen = strlen($error['message']);
$messageLen = \strlen($error['message']);
$notFoundSuffix = '\' not found';
$notFoundSuffixLen = strlen($notFoundSuffix);
$notFoundSuffixLen = \strlen($notFoundSuffix);
if ($notFoundSuffixLen > $messageLen) {
return;
}
@@ -42,7 +42,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
foreach (array('class', 'interface', 'trait') as $typeName) {
$prefix = ucfirst($typeName).' \'';
$prefixLen = strlen($prefix);
$prefixLen = \strlen($prefix);
if (0 !== strpos($error['message'], $prefix)) {
continue;
}
@@ -85,7 +85,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
*/
private function getClassCandidates(string $class): array
{
if (!is_array($functions = spl_autoload_functions())) {
if (!\is_array($functions = spl_autoload_functions())) {
return array();
}
@@ -93,14 +93,14 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
$classes = array();
foreach ($functions as $function) {
if (!is_array($function)) {
if (!\is_array($function)) {
continue;
}
// get class loaders wrapped by DebugClassLoader
if ($function[0] instanceof DebugClassLoader) {
$function = $function[0]->getClassLoader();
if (!is_array($function)) {
if (!\is_array($function)) {
continue;
}
}
@@ -126,7 +126,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
private function findClassInPath(string $path, string $class, string $prefix): array
{
if (!$path = realpath($path.'/'.strtr($prefix, '\\_', '//')) ?: realpath($path.'/'.dirname(strtr($prefix, '\\_', '//'))) ?: realpath($path)) {
if (!$path = realpath($path.'/'.strtr($prefix, '\\_', '//')) ?: realpath($path.'/'.\dirname(strtr($prefix, '\\_', '//'))) ?: realpath($path)) {
return array();
}
@@ -145,7 +145,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
{
$candidates = array(
// namespaced class
$namespacedClass = str_replace(array($path.DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file),
$namespacedClass = str_replace(array($path.\DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file),
// namespaced class (with target dir)
$prefix.$namespacedClass,
// namespaced class (with target dir and separator)

View File

@@ -11,8 +11,8 @@
namespace Symfony\Component\Debug\FatalErrorHandler;
use Symfony\Component\Debug\Exception\UndefinedFunctionException;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\Exception\UndefinedFunctionException;
/**
* ErrorHandler for undefined functions.
@@ -26,9 +26,9 @@ class UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface
*/
public function handleError(array $error, FatalErrorException $exception)
{
$messageLen = strlen($error['message']);
$messageLen = \strlen($error['message']);
$notFoundSuffix = '()';
$notFoundSuffixLen = strlen($notFoundSuffix);
$notFoundSuffixLen = \strlen($notFoundSuffix);
if ($notFoundSuffixLen > $messageLen) {
return;
}
@@ -38,7 +38,7 @@ class UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface
}
$prefix = 'Call to undefined function ';
$prefixLen = strlen($prefix);
$prefixLen = \strlen($prefix);
if (0 !== strpos($error['message'], $prefix)) {
return;
}

View File

@@ -44,7 +44,7 @@ class UndefinedMethodFatalErrorHandler implements FatalErrorHandlerInterface
$candidates = array();
foreach ($methods as $definedMethodName) {
$lev = levenshtein($methodName, $definedMethodName);
if ($lev <= strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) {
if ($lev <= \strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) {
$candidates[] = $definedMethodName;
}
}

View File

@@ -220,24 +220,21 @@ class DebugClassLoaderTest extends TestCase
public function testExtendedFinalMethod()
{
set_error_handler(function () { return false; });
$e = error_reporting(0);
trigger_error('', E_USER_NOTICE);
$deprecations = array();
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
class_exists(__NAMESPACE__.'\\Fixtures\\ExtendedFinalMethod', true);
error_reporting($e);
restore_error_handler();
$lastError = error_get_last();
unset($lastError['file'], $lastError['line']);
$xError = array(
'type' => E_USER_DEPRECATED,
'message' => 'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".',
'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".',
'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod2()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".',
);
$this->assertSame($xError, $lastError);
$this->assertSame($xError, $deprecations);
}
public function testExtendedDeprecatedMethodDoesntTriggerAnyNotice()
@@ -269,12 +266,26 @@ class DebugClassLoaderTest extends TestCase
restore_error_handler();
$this->assertSame($deprecations, array(
'The "Symfony\Component\Debug\Tests\Fixtures\InternalClass" class is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternalsParent".',
'The "Symfony\Component\Debug\Tests\Fixtures\InternalInterface" interface is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternalsParent".',
'The "Symfony\Component\Debug\Tests\Fixtures\InternalClass" class is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternalsParent".',
'The "Symfony\Component\Debug\Tests\Fixtures\InternalTrait" trait is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".',
'The "Symfony\Component\Debug\Tests\Fixtures\InternalTrait2::internalMethod()" method is considered internal. It may change without further notice. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".',
'The "Symfony\Component\Debug\Tests\Fixtures\InternalClass::internalMethod()" method is considered internal. It may change without further notice. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".',
));
}
public function testUseTraitWithInternalMethod()
{
$deprecations = array();
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
class_exists('Test\\'.__NAMESPACE__.'\\UseTraitWithInternalMethod', true);
error_reporting($e);
restore_error_handler();
$this->assertSame(array(), $deprecations);
}
}
class ClassLoader
@@ -328,6 +339,8 @@ class ClassLoader
}');
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsInternalsParent' === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsInternalsParent extends \\'.__NAMESPACE__.'\Fixtures\InternalClass implements \\'.__NAMESPACE__.'\Fixtures\InternalInterface { }');
} elseif ('Test\\'.__NAMESPACE__.'\UseTraitWithInternalMethod' === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class UseTraitWithInternalMethod { use \\'.__NAMESPACE__.'\Fixtures\TraitWithInternalMethod; }');
}
}
}

View File

@@ -480,7 +480,7 @@ class ErrorHandlerTest extends TestCase
$handler = new ErrorHandler();
$handler->setExceptionHandler(function () use (&$args) {
$args = func_get_args();
$args = \func_get_args();
});
$handler->handleException($exception);

View File

@@ -15,19 +15,19 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
use Symfony\Component\HttpKernel\Exception\GoneHttpException;
use Symfony\Component\HttpKernel\Exception\LengthRequiredHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
use Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
class FlattenExceptionTest extends TestCase

View File

@@ -12,10 +12,10 @@
namespace Symfony\Component\Debug\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Debug\ExceptionHandler;
use Symfony\Component\Debug\Exception\OutOfMemoryException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Debug\ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
require_once __DIR__.'/HeaderMock.php';

View File

@@ -11,18 +11,18 @@
namespace Symfony\Component\Debug\Tests\FatalErrorHandler;
use Composer\Autoload\ClassLoader as ComposerClassLoader;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Debug\DebugClassLoader;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
use Symfony\Component\Debug\DebugClassLoader;
use Composer\Autoload\ClassLoader as ComposerClassLoader;
class ClassNotFoundFatalErrorHandlerTest extends TestCase
{
public static function setUpBeforeClass()
{
foreach (spl_autoload_functions() as $function) {
if (!is_array($function)) {
if (!\is_array($function)) {
continue;
}
@@ -32,7 +32,7 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
}
if ($function[0] instanceof ComposerClassLoader) {
$function[0]->add('Symfony_Component_Debug_Tests_Fixtures', dirname(dirname(dirname(dirname(dirname(__DIR__))))));
$function[0]->add('Symfony_Component_Debug_Tests_Fixtures', \dirname(\dirname(\dirname(\dirname(\dirname(__DIR__))))));
break;
}
}

View File

@@ -64,10 +64,10 @@ class UndefinedMethodFatalErrorHandlerTest extends TestCase
),
array(
array(
'type' => 1,
'message' => 'Call to undefined method class@anonymous::test()',
'file' => '/home/possum/work/symfony/test.php',
'line' => 11,
'type' => 1,
'message' => 'Call to undefined method class@anonymous::test()',
'file' => '/home/possum/work/symfony/test.php',
'line' => 11,
),
'Attempted to call an undefined method named "test" of class "class@anonymous".',
),

View File

@@ -4,6 +4,8 @@ namespace Symfony\Component\Debug\Tests\Fixtures;
class ExtendedFinalMethod extends FinalMethod
{
use FinalMethod2Trait;
/**
* {@inheritdoc}
*/

View File

@@ -11,6 +11,13 @@ class FinalMethod
{
}
/**
* @final
*/
public function finalMethod2()
{
}
public function anotherMethod()
{
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Symfony\Component\Debug\Tests\Fixtures;
trait FinalMethod2Trait
{
public function finalMethod2()
{
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Symfony\Component\Debug\Tests\Fixtures;
trait TraitWithInternalMethod
{
/**
* @internal
*/
public function foo()
{
}
}

View File

@@ -27,12 +27,12 @@ function testHeader()
{
static $headers = array();
if (!$h = func_get_args()) {
if (!$h = \func_get_args()) {
$h = $headers;
$headers = array();
return $h;
}
$headers[] = func_get_args();
$headers[] = \func_get_args();
}

View File

@@ -9,7 +9,7 @@ use Symfony\Component\Debug\DebugClassLoader;
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
$vendor = \dirname($vendor);
}
require $vendor.'/vendor/autoload.php';
@@ -24,3 +24,4 @@ class_exists(ExtendedFinalMethod::class);
?>
--EXPECTF--
The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".
The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod2()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".

View File

@@ -1,5 +1,7 @@
--TEST--
Test catching fatal errors when handlers are nested
--INI--
display_errors=0
--FILE--
<?php
@@ -7,7 +9,7 @@ namespace Symfony\Component\Debug;
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
$vendor = \dirname($vendor);
}
require $vendor.'/vendor/autoload.php';
@@ -24,7 +26,6 @@ if (true) {
?>
--EXPECTF--
Fatal error: Class 'Symfony\Component\Debug\missing' not found in %s on line %d
object(Symfony\Component\Debug\Exception\ClassNotFoundException)#%d (8) {
["message":protected]=>
string(131) "Attempted to load class "missing" from namespace "Symfony\Component\Debug".
@@ -38,8 +39,7 @@ Did you forget a "use" statement for another namespace?"
["line":protected]=>
int(%d)
["trace":"Exception":private]=>
array(0) {
}
array(%d) {%A}
["previous":"Exception":private]=>
NULL
["severity":protected]=>

View File

@@ -7,7 +7,7 @@ namespace Symfony\Component\Debug;
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
$vendor = \dirname($vendor);
}
require $vendor.'/vendor/autoload.php';

View File

@@ -7,7 +7,7 @@ namespace Symfony\Component\Debug;
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
$vendor = \dirname($vendor);
}
require $vendor.'/vendor/autoload.php';