Skip to content

Commit

Permalink
Fix newInstance on ReflectionAttribute adapter with enum argument
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jun 21, 2023
1 parent 49b6bb9 commit 277b960
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/NodeCompiler/CompileNodeToValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@ private function getClassConstantValue(Node\Expr\ClassConstFetch $node, string|n

$classContext = $context->getClass();
$classReflection = $classContext !== null && $classContext->getName() === $className ? $classContext : $context->getReflector()->reflectClass($className);
if ($classReflection instanceof ReflectionEnum) {
if ($classReflection->hasCase($constantName)) {
return constant(sprintf('%s::%s', $className, $constantName));
}
}

$reflectionConstant = $classReflection->getConstant($constantName);

Expand Down
25 changes: 25 additions & 0 deletions test/unit/Fixture/Attributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,28 @@ enum EnumWithAttributes
#[AnotherAttr]
case CASE_WITH_ATTRIBUTES;
}

enum SomeEnum: int
{

case ONE = 1;
case TWO = 2;

}

#[Attribute]
class AttributeThatAcceptsArgument
{

public function __construct(public SomeEnum $e)
{

}

}

#[AttributeThatAcceptsArgument(e: SomeEnum::ONE)]
class ClassWithAttributeThatAcceptsArgument
{

}
30 changes: 30 additions & 0 deletions test/unit/Reflection/Adapter/ReflectionAttributeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,24 @@
use Roave\BetterReflection\Reflection\Adapter\ReflectionAttribute as ReflectionAttributeAdapter;
use Roave\BetterReflection\Reflection\ReflectionAttribute as BetterReflectionAttribute;

use Roave\BetterReflection\Reflector\DefaultReflector;
use Roave\BetterReflection\Reflector\Reflector;
use Roave\BetterReflection\SourceLocator\Ast\Locator;
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\SingleFileSourceLocator;
use Roave\BetterReflectionTest\BetterReflectionSingleton;
use Roave\BetterReflectionTest\Fixture\AttributeThatAcceptsArgument;
use Roave\BetterReflectionTest\Fixture\ClassWithAttributeThatAcceptsArgument;
use Roave\BetterReflectionTest\Fixture\SomeEnum;
use function array_combine;
use function array_map;
use function get_class_methods;

#[CoversClass(ReflectionAttributeAdapter::class)]
class ReflectionAttributeTest extends TestCase
{

/** @return array<string, array{0: string}> */
public static function coreReflectionMethodNamesProvider(): array
{
Expand Down Expand Up @@ -68,4 +79,23 @@ public function testAdapterMethods(string $methodName, string|null $expectedExce
$adapter = new ReflectionAttributeAdapter($reflectionStub);
$adapter->{$methodName}(...$args);
}

public function testNewInstanceWithEnum(): void
{
$astLocator = BetterReflectionSingleton::instance()->astLocator();
$path = __DIR__ . '/../../Fixture/Attributes.php';
require_once($path);

$betterReflection = BetterReflectionSingleton::instance();
$reflector = new DefaultReflector(new AggregateSourceLocator([new SingleFileSourceLocator($path, $astLocator), new PhpInternalSourceLocator($astLocator, $betterReflection->sourceStubber())]));
$reflection = $reflector->reflectClass(ClassWithAttributeThatAcceptsArgument::class);
$attributes = $reflection->getAttributesByName(AttributeThatAcceptsArgument::class);
$this->assertCount(1, $attributes);
$adapter = new ReflectionAttributeAdapter($attributes[0]);
$instance = $adapter->newInstance();
$this->assertInstanceOf(AttributeThatAcceptsArgument::class, $instance);
$this->assertInstanceOf(SomeEnum::class, $instance->e);
$this->assertSame('ONE', $instance->e->name);
$this->assertSame(1, $instance->e->value);
}
}

0 comments on commit 277b960

Please sign in to comment.