From 135a394e2fba447a788ac3a36818e4cde8b87ac4 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 2 Oct 2023 17:53:45 +0200 Subject: [PATCH] ReflectionSourceStubber - fix enum as default function parameter value --- .../SourceStubber/ReflectionSourceStubber.php | 18 +++++++++++++++++- .../ReflectionSourceStubberTest.php | 11 +++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php b/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php index cd5989ee0..54054c851 100644 --- a/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php +++ b/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php @@ -4,6 +4,7 @@ namespace Roave\BetterReflection\SourceLocator\SourceStubber; +use BackedEnum; use LogicException; use PhpParser\Builder\Class_; use PhpParser\Builder\ClassConst; @@ -46,10 +47,12 @@ use function assert; use function explode; use function function_exists; +use function get_class; use function get_defined_constants; use function implode; use function in_array; use function is_file; +use function is_object; use function is_resource; use function method_exists; use function preg_replace; @@ -579,7 +582,20 @@ private function setParameterDefaultValue(ReflectionParameter $parameterReflecti return; } - $parameterNode->setDefault($parameterReflection->getDefaultValue()); + $defaultValue = $parameterReflection->getDefaultValue(); + if (is_object($defaultValue)) { + $className = get_class($defaultValue); + $isEnum = function_exists('enum_exists') && \enum_exists($className, false); + if ($isEnum && $defaultValue instanceof BackedEnum) { + $parameterNode->setDefault(new Node\Expr\ClassConstFetch( + new FullyQualified($className), + new Node\Identifier($defaultValue->name) + )); + return; + } + } + + $parameterNode->setDefault($defaultValue); } private function formatType(CoreReflectionType $type): Name|NullableType|UnionType|IntersectionType diff --git a/test/unit/SourceLocator/SourceStubber/ReflectionSourceStubberTest.php b/test/unit/SourceLocator/SourceStubber/ReflectionSourceStubberTest.php index ec0c2c71c..f7917c9bb 100644 --- a/test/unit/SourceLocator/SourceStubber/ReflectionSourceStubberTest.php +++ b/test/unit/SourceLocator/SourceStubber/ReflectionSourceStubberTest.php @@ -23,6 +23,7 @@ use Roave\BetterReflection\SourceLocator\SourceStubber\ReflectionSourceStubber; use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator; use Roave\BetterReflectionTest\BetterReflectionSingleton; +use Roave\BetterReflectionTest\Fixture\SomeEnum; use Traversable; use function array_filter; @@ -414,4 +415,14 @@ public function testUnknownConstant(): void { self::assertNull($this->stubber->generateConstantStub('SOME_CONSTANT')); } + + public function testClosureWithEnumParameterDefaultValue(): void + { + require_once __DIR__ . '/../../Fixture/Attributes.php'; + $closure = function ($test = SomeEnum::ONE): void { + + }; + $stub = $this->stubber->generateFunctionStubFromReflection(new CoreReflectionFunction($closure)); + self::assertStringContainsString('$test = \Roave\BetterReflectionTest\Fixture\SomeEnum::ONE', $stub->getStub()); + } }