bug #34560 [Config][ReflectionClassResource] Handle parameters with undefined constant as their default values (fancyweb)
This PR was merged into the 3.4 branch.
Discussion
----------
[Config][ReflectionClassResource] Handle parameters with undefined constant as their default values
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | https://github.com/symfony/symfony/issues/34053
| License | MIT
| Doc PR | -
Basically we can fix this bug by "reimplementing" php src way of building the __toString() of the method except that we avoid to call the undefined constant. Obviously we cannot invalidate the resource if the value of the constant changes since we never knew it. However, it's still better than now.
Commits
-------
8de2a226a8
[Config][ReflectionClassResource] Handle parameters with undefined constant as their default values
This commit is contained in:
commit
9eafff5ec0
@ -151,12 +151,56 @@ class ReflectionClassResource implements SelfCheckingResourceInterface, \Seriali
|
||||
}
|
||||
} 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 {
|
||||
$stack = [
|
||||
$m->getDocComment(),
|
||||
$m->getName(),
|
||||
$m->isAbstract(),
|
||||
$m->isFinal(),
|
||||
$m->isStatic(),
|
||||
$m->isPublic(),
|
||||
$m->isPrivate(),
|
||||
$m->isProtected(),
|
||||
$m->returnsReference(),
|
||||
\PHP_VERSION_ID >= 70000 && $m->hasReturnType() ? (\PHP_VERSION_ID >= 70100 ? $m->getReturnType()->getName() : (string) $m->getReturnType()) : '',
|
||||
];
|
||||
|
||||
foreach ($m->getParameters() as $p) {
|
||||
if (!isset($parametersWithUndefinedConstants[$p->name])) {
|
||||
$stack[] = (string) $p;
|
||||
} else {
|
||||
$stack[] = $p->isOptional();
|
||||
$stack[] = \PHP_VERSION_ID >= 70000 && $p->hasType() ? (\PHP_VERSION_ID >= 70100 ? $p->getType()->getName() : (string) $p->getType()) : '';
|
||||
$stack[] = $p->isPassedByReference();
|
||||
$stack[] = \PHP_VERSION_ID >= 50600 ? $p->isVariadic() : '';
|
||||
$stack[] = $p->getName();
|
||||
}
|
||||
}
|
||||
|
||||
yield implode(',', $stack);
|
||||
}
|
||||
|
||||
yield print_r($defaults, true);
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,12 @@ class ReflectionClassResourceTest extends TestCase
|
||||
/**
|
||||
* @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 @@ class ReflectionClassResourceTest extends TestCase
|
||||
/*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 @@ EOPHP;
|
||||
}
|
||||
|
||||
$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 @@ EOPHP;
|
||||
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 () { \define('A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC', 'foo'); }];
|
||||
}
|
||||
|
||||
public function testEventSubscriber()
|
||||
|
Reference in New Issue
Block a user