diff --git a/src/ReflectionAttribute.php b/src/ReflectionAttribute.php index deef828..48e3071 100644 --- a/src/ReflectionAttribute.php +++ b/src/ReflectionAttribute.php @@ -15,6 +15,11 @@ use Go\ParserReflection\Traits\InternalPropertiesEmulationTrait; use ReflectionAttribute as BaseReflectionAttribute; use PhpParser\Node; +use PhpParser\Node\Stmt\Class_; +use PhpParser\Node\Stmt\ClassConst; +use PhpParser\Node\Stmt\ClassMethod; +use PhpParser\Node\Stmt\Function_; +use PhpParser\Node\Stmt\Property; use Reflector; /** @@ -23,19 +28,22 @@ class ReflectionAttribute extends BaseReflectionAttribute { public function __construct( - string $attributeName, - private ?Node\Attribute $attributeNode = null + private string $attributeName, + int $flags = 0, + private Class_|ClassMethod|Function_|ClassConst|Property $attributeHolder ) { - $this->attributeNode ??= ReflectionEngine::parseAttribute($attributeName); - } - - public function __debugInfo(): array - { - return []; } public function getNode(): Node\Attribute { - return $this->attributeNode; + foreach ($this->attributeHolder->attrGroups as $attrGroup) { + foreach ($attrGroup->attrs as $attr) { + if ($attr->name->toString() === $this->attributeName) { + return $attr; + } + } + } + + throw new ReflectionException(sprintf('attribute %s not exists', $this->attributeName)); } } diff --git a/src/ReflectionEngine.php b/src/ReflectionEngine.php index 1626476..3c86346 100644 --- a/src/ReflectionEngine.php +++ b/src/ReflectionEngine.php @@ -142,11 +142,6 @@ public static function parseClass(string $fullClassName): ClassLike throw new InvalidArgumentException("Class $fullClassName was not found in the $classFileName"); } - public static function parseAttribute(string $attributeName): Node\Attribute - { - throw new Exception('to be implemented'); - } - /** * Loop through an array and find a ClassLike statement by the given class name. * diff --git a/src/Traits/AttributeResolverTrait.php b/src/Traits/AttributeResolverTrait.php index c33c585..e3f31a8 100644 --- a/src/Traits/AttributeResolverTrait.php +++ b/src/Traits/AttributeResolverTrait.php @@ -14,11 +14,17 @@ use Go\ParserReflection\ReflectionAttribute; use Go\ParserReflection\ReflectionClass; +use Go\ParserReflection\ReflectionClassConstant; use Go\ParserReflection\ReflectionException; use Go\ParserReflection\ReflectionFunction; use Go\ParserReflection\ReflectionMethod; use Go\ParserReflection\ReflectionProperty; -use ReflectionClassConstant; +use PhpParser\Node\Stmt; +use PhpParser\Node\Stmt\ClassConst; +use PhpParser\Node\Stmt\ClassLike; +use PhpParser\Node\Stmt\ClassMethod; +use PhpParser\Node\Stmt\Function_; +use PhpParser\Node\Stmt\Property; trait AttributeResolverTrait { @@ -27,22 +33,44 @@ trait AttributeResolverTrait */ public function getAttributes(?string $name = null, int $flags = 0): array { - if ( - $this instanceof ReflectionClass || - $this instanceof ReflectionFunction || - $this instanceof ReflectionMethod || - $this instanceof ReflectionProperty || - $this instanceof ReflectionClassConstant - ) { - $attributes = $this->getAttributes($name, $flags); - $reflectionAttributes = []; - foreach ($attributes as $attribute) { - $reflectionAttributes[] = new ReflectionAttribute($attribute->getName()); - } + /** @var ClassLike|ClassMethod|Property|ClassConst|Function_|null $attributeHolder */ + $attributeHolder = null; + + if ($this instanceof ReflectionClass) { + $attributeHolder = $this->classLikeNode; + } + + if ($this instanceof ReflectionMethod) { + $attributeHolder = $this->classMethodNode; + } + + if ($this instanceof ReflectionProperty) { + $attributeHolder = $this->propertyNode; + } - return $reflectionAttributes; + if ($this instanceof ReflectionClassConstant) { + $attributeHolder = $this->classConstNode; + } + + if ($this instanceof ReflectionFunction) { + $attributeHolder = $this->functionNode; + } + + if ($attributeHolder === null) { + throw new ReflectionException(sprintf('Attribute on %s not supported yet'), $this::class); + } + + $attributes = []; + foreach ($attributeHolder->attrGroups as $attrGroup) { + foreach ($attrGroup->attrs as $attr) { + if ($name !== null) { + return [new ReflectionAttribute($name, $flags, $attributeHolder)]; + } + + $attributes[] = new ReflectionAttribute($attr->toString(), $flags, $attributeHolder); + } } - throw new ReflectionException('not yet supported'); + return $attributes; } }