From 4dbcaa4d7a665eee7a584ba5440707f51a1d5219 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Sat, 23 Nov 2019 20:59:48 +0100 Subject: [PATCH] [Config][ReflectionClassResource] Handle parameters with undefined constant as their default values --- .../Resource/ReflectionClassResource.php | 60 ++++++++++++++++++- .../Resource/ReflectionClassResourceTest.php | 18 +++++- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php index d5e6b829cfeca..bb03cef515438 100644 --- a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php +++ b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php @@ -151,12 +151,66 @@ private function generateSignature(\ReflectionClass $class) } } else { foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) { - yield preg_replace('/^ @@.*/m', '', $m); - $defaults = []; + $parametersWithUndefinedConstants = []; foreach ($m->getParameters() as $p) { - $defaults[$p->name] = $p->isDefaultValueAvailable() ? $p->getDefaultValue() : null; + if (!$p->isDefaultValueAvailable()) { + $defaults[$p->name] = null; + + continue; + } + + if (!$p->isDefaultValueConstant() || \defined($p->getDefaultValueConstantName())) { + $defaults[$p->name] = $p->getDefaultValue(); + + continue; + } + + $defaults[$p->name] = $p->getDefaultValueConstantName(); + $parametersWithUndefinedConstants[$p->name] = true; } + + if (!$parametersWithUndefinedConstants) { + yield preg_replace('/^ @@.*/m', '', $m); + } else { + yield $m->getDocComment(); + yield $m->getName(); + yield (int) $m->isAbstract(); + yield (int) $m->isFinal(); + yield (int) $m->isStatic(); + yield (int) $m->isPublic(); + yield (int) $m->isPrivate(); + yield (int) $m->isProtected(); + yield (int) $m->returnsReference(); + + foreach ($m->getParameters() as $p) { + if (!isset($parametersWithUndefinedConstants[$p->name])) { + yield (string) $p; + } else { + yield (int) $p->isOptional(); + yield (int) ($hasType = \PHP_VERSION_ID >= 70000 && $p->hasType()); + + if ($hasType) { + yield (string) $p->getType(); + } + + yield (int) $p->isPassedByReference(); + + if (\PHP_VERSION_ID >= 56000) { + yield (int) $p->isVariadic(); + } + + yield $p->getName(); + } + } + + yield $hasReturnType = (int) (\PHP_VERSION_ID >= 70000 && $m->hasReturnType()); + + if ($hasReturnType) { + yield (string) $m->getReturnType(); + } + } + yield print_r($defaults, true); } } diff --git a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php index 76cad1433bb20..398696c9752f9 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php @@ -63,8 +63,12 @@ public function testIsFreshForDeletedResources() /** * @dataProvider provideHashedSignature */ - public function testHashedSignature($changeExpected, $changedLine, $changedCode) + public function testHashedSignature($changeExpected, $changedLine, $changedCode, $setContext = null) { + if ($setContext) { + $setContext(); + } + $code = <<<'EOPHP' /* 0*/ /* 1*/ class %s extends ErrorException @@ -82,7 +86,9 @@ public function testHashedSignature($changeExpected, $changedLine, $changedCode) /*13*/ protected function prot($a = []) {} /*14*/ /*15*/ private function priv() {} -/*16*/ } +/*16*/ +/*17*/ public function ccc($bar = A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC) {} +/*18*/ } EOPHP; static $expectedSignature, $generateSignature; @@ -97,7 +103,9 @@ public function testHashedSignature($changeExpected, $changedLine, $changedCode) } $code = explode("\n", $code); - $code[$changedLine] = $changedCode; + if (null !== $changedCode) { + $code[$changedLine] = $changedCode; + } eval(sprintf(implode("\n", $code), $class = 'Foo'.str_replace('.', '_', uniqid('', true)))); $signature = implode("\n", iterator_to_array($generateSignature(new \ReflectionClass($class)))); @@ -145,6 +153,10 @@ public function provideHashedSignature() yield [0, 7, 'protected int $prot;']; yield [0, 9, 'private string $priv;']; } + + yield [1, 17, 'public function ccc($bar = 187) {}']; + yield [1, 17, 'public function ccc($bar = ANOTHER_ONE_THAT_WILL_NEVER_BE_DEFINED_CCCCCCCCC) {}']; + yield [1, 17, null, static function (): void { \define('A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC', 'foo'); }]; } public function testEventSubscriber()