From d097ba331dab54fc55c8a34da6ca612ea7e48cdb Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 17 Jan 2022 15:05:07 +0100 Subject: [PATCH] Fix missing properties for UnitEnum and BackedEnum interfaces --- src/Reflection/ReflectionClass.php | 26 +++++++++++++++----- test/unit/Reflection/ReflectionClassTest.php | 10 +++++++- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/Reflection/ReflectionClass.php b/src/Reflection/ReflectionClass.php index 181339b9f..283f24d57 100644 --- a/src/Reflection/ReflectionClass.php +++ b/src/Reflection/ReflectionClass.php @@ -804,11 +804,7 @@ public function getImmediateProperties(?int $filter = null): array */ private function addEnumProperties(array $properties): array { - if (! $this->node instanceof EnumNode) { - return $properties; - } - - $createProperty = function (string $name, string|Node\Identifier $type): ReflectionProperty { + $createProperty = function (string $name, string|Node\Identifier|Node\UnionType $type): ReflectionProperty { $propertyNode = new Node\Stmt\Property( ClassNode::MODIFIER_PUBLIC | ClassNode::MODIFIER_READONLY, [new Node\Stmt\PropertyProperty($name)], @@ -826,6 +822,24 @@ private function addEnumProperties(array $properties): array ); }; + if (! $this->node instanceof EnumNode) { + if ($this->node instanceof Node\Stmt\Interface_) { + $interfaceName = $this->getName(); + if ($interfaceName === 'UnitEnum') { + $properties['name'] = $createProperty('name', 'string'); + } + + if ($interfaceName === 'BackedEnum') { + $properties['value'] = $createProperty('value', new Node\UnionType([ + new Node\Identifier('int'), + new Node\Identifier('string'), + ])); + } + } + + return $properties; + } + $properties['name'] = $createProperty('name', 'string'); if ($this->node->scalarType !== null) { @@ -863,7 +877,7 @@ static function (ReflectionClass $ancestor) use ($filter): array { static fn (ReflectionProperty $property): bool => ! $property->isPrivate(), ); }, - array_filter([$this->getParentClass()]), + array_merge(array_filter([$this->getParentClass()]), array_values($this->getInterfaces())), ), ...array_map( function (ReflectionClass $trait) use ($filter) { diff --git a/test/unit/Reflection/ReflectionClassTest.php b/test/unit/Reflection/ReflectionClassTest.php index 0436b2dfb..7e28d90de 100644 --- a/test/unit/Reflection/ReflectionClassTest.php +++ b/test/unit/Reflection/ReflectionClassTest.php @@ -580,6 +580,14 @@ public function dataGetPropertiesForBackedEnum(): array IntEnum::class, ['name' => 'string', 'value' => 'int'], ], + [ + UnitEnum::class, + ['name' => 'string'], + ], + [ + BackedEnum::class, + ['name' => 'string', 'value' => 'int|string'], + ], ]; } @@ -596,7 +604,7 @@ public function testGetPropertiesForBackedEnum(string $className, array $propert ])); $classInfo = $reflector->reflectClass($className); - $properties = $classInfo->getImmediateProperties(); + $properties = $classInfo->getProperties(); foreach ($propertiesData as $propertyName => $propertyType) { $fullPropertyName = sprintf('%s::$%s', $className, $propertyName);