Skip to content

Commit

Permalink
bug #34560 [Config][ReflectionClassResource] Handle parameters with u…
Browse files Browse the repository at this point in the history
…ndefined 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       | #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
-------

8de2a22 [Config][ReflectionClassResource] Handle parameters with undefined constant as their default values
  • Loading branch information
nicolas-grekas committed Nov 29, 2019
2 parents 2d2dd62 + 8de2a22 commit 9eafff5
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 6 deletions.
50 changes: 47 additions & 3 deletions src/Symfony/Component/Config/Resource/ReflectionClassResource.php
Expand Up @@ -151,12 +151,56 @@ 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 {
$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);
}
}
Expand Down
Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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))));

Expand Down Expand Up @@ -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 () { \define('A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC', 'foo'); }];
}

public function testEventSubscriber()
Expand Down

0 comments on commit 9eafff5

Please sign in to comment.