From 43eae19abb8ed3d573ff30af00be19a74ddfe0d7 Mon Sep 17 00:00:00 2001 From: kylekatarnls Date: Mon, 20 May 2024 10:54:14 +0200 Subject: [PATCH] Allow to work with global constant without FQCN --- .../Resource/ReflectionClassResource.php | 13 ++++++- .../DependencyInjection/Dumper/Preloader.php | 4 +- .../Tests/Fixtures/includes/foo.php | 5 +++ .../VarDumper/Caster/ConstCaster.php | 38 +++++++++++++++++++ .../VarDumper/Caster/ReflectionCaster.php | 4 +- .../Tests/Caster/ReflectionCasterTest.php | 23 ++++++++++- 6 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 src/Symfony/Component/VarDumper/Caster/ConstCaster.php diff --git a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php index 06f1d766e0e1e..efcd47a38ee13 100644 --- a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php +++ b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php @@ -13,6 +13,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Messenger\Handler\MessageSubscriberInterface; +use Symfony\Component\VarDumper\Caster\ConstCaster; use Symfony\Contracts\Service\ServiceSubscriberInterface; /** @@ -197,13 +198,21 @@ private function generateSignature(\ReflectionClass $class): iterable continue; } - if (!$p->isDefaultValueConstant() || $defined($p->getDefaultValueConstantName())) { + if (!$p->isDefaultValueConstant()) { $defaults[$p->name] = $p->getDefaultValue(); continue; } - $defaults[$p->name] = $p->getDefaultValueConstantName(); + $constantName = ConstCaster::castParameterDefaultValue($p); + + if ($defined($constantName)) { + $defaults[$p->name] = $p->getDefaultValue(); + + continue; + } + + $defaults[$p->name] = $constantName; $parametersWithUndefinedConstants[$p->name] = true; } diff --git a/src/Symfony/Component/DependencyInjection/Dumper/Preloader.php b/src/Symfony/Component/DependencyInjection/Dumper/Preloader.php index c61b08ebc28ef..c883396418dda 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/Preloader.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/Preloader.php @@ -11,6 +11,8 @@ namespace Symfony\Component\DependencyInjection\Dumper; +use Symfony\Component\VarDumper\Caster\ConstCaster; + /** * @author Nicolas Grekas */ @@ -99,7 +101,7 @@ private static function doPreload(string $class, array &$preloaded): void foreach ($r->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) { foreach ($m->getParameters() as $p) { if ($p->isDefaultValueAvailable() && $p->isDefaultValueConstant()) { - $c = $p->getDefaultValueConstantName(); + $c = ConstCaster::castParameterDefaultValue($p); if ($i = strpos($c, '::')) { self::doPreload(substr($c, 0, $i), $preloaded); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php index c8a6b347a0029..ea9af580d1f9b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php @@ -41,4 +41,9 @@ public function setBar($value = null) { $this->bar = $value; } + + public function byPi(float $pi = M_PI): float + { + return $this->bar * $pi; + } } diff --git a/src/Symfony/Component/VarDumper/Caster/ConstCaster.php b/src/Symfony/Component/VarDumper/Caster/ConstCaster.php new file mode 100644 index 0000000000000..5655762d4a13e --- /dev/null +++ b/src/Symfony/Component/VarDumper/Caster/ConstCaster.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +/** + * Get the FQCN of a parameter default constant value. + */ +final class ConstCaster +{ + public static function castParameterDefaultValue(\ReflectionParameter $param): ?string + { + echo (new \Exception())->getTraceAsString() . "\n\n"; + $namespacedConstant = $param->getDefaultValueConstantName(); + var_dump($namespacedConstant); + + if (null !== $namespacedConstant && str_contains($namespacedConstant, '\\') && !\defined($namespacedConstant)) { + $globalConstant = '\\'.preg_replace('/^.*\\\\([^\\\\]+)$/', '$1', $namespacedConstant); + + if (\defined($globalConstant) && $param->getDefaultValue() === \constant($globalConstant)) { + var_dump($globalConstant); + exit; + return $globalConstant; + } + } + + exit; + return $namespacedConstant; + } +} diff --git a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php index 35fd1e8a99b2b..7b4dcf4964552 100644 --- a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php @@ -299,7 +299,7 @@ public static function castParameter(\ReflectionParameter $c, array $a, Stub $st try { $a[$prefix.'default'] = $v = $c->getDefaultValue(); if ($c->isDefaultValueConstant() && !\is_object($v)) { - $a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v); + $a[$prefix.'default'] = new ConstStub(ConstCaster::castParameterDefaultValue($c), $v); } if (null === $v) { unset($a[$prefix.'allowsNull']); @@ -383,7 +383,7 @@ public static function getSignature(array $a) $signature .= ' = '; if ($param->isDefaultValueConstant()) { - $signature .= substr(strrchr('\\'.$param->getDefaultValueConstantName(), '\\'), 1); + $signature .= substr(strrchr('\\'.ConstCaster::castParameterDefaultValue($param), '\\'), 1); } elseif (null === $v) { $signature .= 'null'; } elseif (\is_array($v)) { diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php index e57999182ea89..b6f3d91562578 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php @@ -13,6 +13,9 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\VarDumper\Caster\Caster; +use Symfony\Component\VarDumper\Caster\ConstStub; +use Symfony\Component\VarDumper\Caster\ReflectionCaster; +use Symfony\Component\VarDumper\Cloner\Stub; use Symfony\Component\VarDumper\Test\VarDumperTestTrait; use Symfony\Component\VarDumper\Tests\Fixtures\ExtendsReflectionTypeFixture; use Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo; @@ -95,7 +98,7 @@ public function testClosureCaster() $b: & 123 } file: "%sReflectionCasterTest.php" - line: "88 to 88" + line: "91 to 91" } EOTXT , $var @@ -701,6 +704,24 @@ public function testReflectionClassConstantWithAttribute() , $var); } + public function testGlobalConstantAsDefaultValue() + { + $class = new class() { + public function foo(float $value = M_PI) + { + // Dummy content + } + }; + $method = new \ReflectionMethod($class, 'foo'); + $parameter = $method->getParameters()[0]; + $cast = ReflectionCaster::castParameter($parameter, [], new Stub(), false); + /** @var ConstStub $defaultStub */ + $defaultStub = $cast["\0~\0default"]; + + $this->assertInstanceOf(ConstStub::class, $defaultStub); + $this->assertSame('\\'.\M_PI::class, $defaultStub->class); + } + /** * @requires PHP 8 */