From 487bcc6200ee8dc88bac2ee1cf80975a9504d562 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 22 Jan 2020 19:52:26 +0100 Subject: [PATCH] Improve displaying anonymous classes --- src/Symfony/Component/Console/Application.php | 4 ++-- src/Symfony/Component/ErrorHandler/DebugClassLoader.php | 2 +- src/Symfony/Component/ErrorHandler/ErrorHandler.php | 2 +- .../Component/ErrorHandler/Exception/FlattenException.php | 4 ++-- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- .../Component/Messenger/Middleware/TraceableMiddleware.php | 2 +- src/Symfony/Component/VarDumper/Caster/Caster.php | 2 +- src/Symfony/Component/VarDumper/Caster/ClassStub.php | 2 +- src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php | 4 ++-- src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php | 2 +- src/Symfony/Component/VarDumper/Tests/Caster/CasterTest.php | 4 ++-- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index dbbdabd5d9..667d5f99f2 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -776,7 +776,7 @@ class Application implements ResetInterface $message = trim($e->getMessage()); if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { $class = \get_class($e); - $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; + $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class))).'@anonymous' : $class; $title = sprintf(' [%s%s] ', $class, 0 !== ($code = $e->getCode()) ? ' ('.$code.')' : ''); $len = Helper::strlen($title); } else { @@ -785,7 +785,7 @@ class Application implements ResetInterface if (false !== strpos($message, "class@anonymous\0")) { $message = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { - return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0]))).'@anonymous' : $m[0]; }, $message); } diff --git a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php index a9ce96efda..84e93fbb54 100644 --- a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php +++ b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php @@ -406,7 +406,7 @@ class DebugClassLoader } $deprecations = []; - $className = isset($class[15]) && "\0" === $class[15] && 0 === strpos($class, "class@anonymous\x00") ? get_parent_class($class).'@anonymous' : $class; + $className = isset($class[15]) && "\0" === $class[15] && 0 === strpos($class, "class@anonymous\x00") ? (get_parent_class($class) ?: key(class_implements($class))).'@anonymous' : $class; // Don't trigger deprecations for classes in the same vendor if ($class !== $className) { diff --git a/src/Symfony/Component/ErrorHandler/ErrorHandler.php b/src/Symfony/Component/ErrorHandler/ErrorHandler.php index 44e6bc5e59..a2fdf37dee 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorHandler.php +++ b/src/Symfony/Component/ErrorHandler/ErrorHandler.php @@ -762,7 +762,7 @@ class ErrorHandler private function parseAnonymousClass(string $message): string { return preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', static function ($m) { - return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0]))).'@anonymous' : $m[0]; }, $message); } } diff --git a/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php b/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php index b6843e71ab..331bfd2f53 100644 --- a/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php +++ b/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php @@ -142,7 +142,7 @@ class FlattenException */ public function setClass($class): self { - $this->class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; + $this->class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class))).'@anonymous' : $class; return $this; } @@ -201,7 +201,7 @@ class FlattenException { if (false !== strpos($message, "class@anonymous\0")) { $message = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { - return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0]))).'@anonymous' : $m[0]; }, $message); } diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 69ccc569a7..7357b99cb6 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -219,7 +219,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl { if (!isset($this->bundles[$name])) { $class = \get_class($this); - $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; + $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class))).'@anonymous' : $class; throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() method of your %s.php file?', $name, $class)); } @@ -394,7 +394,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl protected function getContainerClass() { $class = \get_class($this); - $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).str_replace('.', '_', ContainerBuilder::hash($class)) : $class; + $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class))).str_replace('.', '_', ContainerBuilder::hash($class)) : $class; $class = str_replace('\\', '_', $class).ucfirst($this->environment).($this->debug ? 'Debug' : '').'Container'; if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $class)) { throw new \InvalidArgumentException(sprintf('The environment "%s" contains invalid characters, it can only contain characters allowed in PHP class names.', $this->environment)); diff --git a/src/Symfony/Component/Messenger/Middleware/TraceableMiddleware.php b/src/Symfony/Component/Messenger/Middleware/TraceableMiddleware.php index f0400c3cb6..c073ba761e 100644 --- a/src/Symfony/Component/Messenger/Middleware/TraceableMiddleware.php +++ b/src/Symfony/Component/Messenger/Middleware/TraceableMiddleware.php @@ -79,7 +79,7 @@ class TraceableStack implements StackInterface $this->currentEvent = 'Tail'; } else { $class = \get_class($nextMiddleware); - $this->currentEvent = sprintf('"%s"', 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class); + $this->currentEvent = sprintf('"%s"', 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class))).'@anonymous' : $class); } $this->currentEvent .= sprintf(' on "%s"', $this->busName); diff --git a/src/Symfony/Component/VarDumper/Caster/Caster.php b/src/Symfony/Component/VarDumper/Caster/Caster.php index 5f3550fd08..bac696defc 100644 --- a/src/Symfony/Component/VarDumper/Caster/Caster.php +++ b/src/Symfony/Component/VarDumper/Caster/Caster.php @@ -77,7 +77,7 @@ class Caster $prefixedKeys[$i] = self::PREFIX_DYNAMIC.$k; } } elseif (isset($k[16]) && "\0" === $k[16] && 0 === strpos($k, "\0class@anonymous\0")) { - $prefixedKeys[$i] = "\0".get_parent_class($class).'@anonymous'.strrchr($k, "\0"); + $prefixedKeys[$i] = "\0".(get_parent_class($class) ?: key(class_implements($class))).'@anonymous'.strrchr($k, "\0"); } ++$i; } diff --git a/src/Symfony/Component/VarDumper/Caster/ClassStub.php b/src/Symfony/Component/VarDumper/Caster/ClassStub.php index c998b49f2c..cc3351da40 100644 --- a/src/Symfony/Component/VarDumper/Caster/ClassStub.php +++ b/src/Symfony/Component/VarDumper/Caster/ClassStub.php @@ -57,7 +57,7 @@ class ClassStub extends ConstStub if (false !== strpos($identifier, "class@anonymous\0")) { $this->value = $identifier = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { - return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0]))).'@anonymous' : $m[0]; }, $identifier); } diff --git a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php index 9229bdd6b7..c1fa9a8885 100644 --- a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php @@ -74,7 +74,7 @@ class ExceptionCaster if (isset($a[$xPrefix.'previous'], $a[$trace]) && $a[$xPrefix.'previous'] instanceof \Exception) { $b = (array) $a[$xPrefix.'previous']; $class = \get_class($a[$xPrefix.'previous']); - $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; + $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class))).'@anonymous' : $class; self::traceUnshift($b[$xPrefix.'trace'], $class, $b[$prefix.'file'], $b[$prefix.'line']); $a[$trace] = new TraceStub($b[$xPrefix.'trace'], false, 0, -\count($a[$trace]->value)); } @@ -284,7 +284,7 @@ class ExceptionCaster if (isset($a[Caster::PREFIX_PROTECTED.'message']) && false !== strpos($a[Caster::PREFIX_PROTECTED.'message'], "class@anonymous\0")) { $a[Caster::PREFIX_PROTECTED.'message'] = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { - return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0]))).'@anonymous' : $m[0]; }, $a[Caster::PREFIX_PROTECTED.'message']); } diff --git a/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php b/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php index 56b2384079..9e548caae3 100644 --- a/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php +++ b/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php @@ -286,7 +286,7 @@ abstract class AbstractCloner implements ClonerInterface $class = $stub->class; if (isset($class[15]) && "\0" === $class[15] && 0 === strpos($class, "class@anonymous\x00")) { - $stub->class = get_parent_class($class).'@anonymous'; + $stub->class = (get_parent_class($class) ?: key(class_implements($class))).'@anonymous'; } if (isset($this->classInfo[$class])) { list($i, $parents, $hasDebugInfo, $fileInfo) = $this->classInfo[$class]; diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/CasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/CasterTest.php index 2c2189c8b5..f0a1fbbe8b 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/CasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/CasterTest.php @@ -164,11 +164,11 @@ EOTXT , $c ); - $c = eval('return new class { private $foo = "foo"; };'); + $c = eval('return new class implements \Countable { private $foo = "foo"; public function count() { return 0; } };'); $this->assertDumpMatchesFormat( <<<'EOTXT' -@anonymous { +Countable@anonymous { -foo: "foo" } EOTXT