From eb0e9f1674b867dee34ce3f95ab5c22b9a7908ca Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Wed, 25 Mar 2020 17:04:21 +0100 Subject: [PATCH] improve NodeAnnotation reader for multiple annotations of same type at one method --- .../AnnotationReader/NodeAnnotationReader.php | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php b/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php index c58b8b1d38d3..48de1310ab3f 100644 --- a/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php +++ b/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php @@ -29,6 +29,11 @@ final class NodeAnnotationReader */ private $nodeNameResolver; + /** + * @var string[] + */ + private $alreadyProvidedAnnotations = []; + public function __construct(Reader $reader, NodeNameResolver $nodeNameResolver) { $this->reader = $reader; @@ -49,11 +54,30 @@ public function readMethodAnnotation(ClassMethod $classMethod, string $annotatio $reflectionMethod = new ReflectionMethod($className, $methodName); try { - return $this->reader->getMethodAnnotation($reflectionMethod, $annotationClassName); + // covers cases like https://github.com/rectorphp/rector/issues/3046 + + /** @var object[] $methodAnnotations */ + $methodAnnotations = $this->reader->getMethodAnnotations($reflectionMethod); + foreach ($methodAnnotations as $methodAnnotation) { + if (! is_a($methodAnnotation, $annotationClassName, true)) { + continue; + } + + $objectHash = md5(spl_object_hash($classMethod) . serialize($methodAnnotation)); + if (in_array($objectHash, $this->alreadyProvidedAnnotations, true)) { + continue; + } + + $this->alreadyProvidedAnnotations[] = $objectHash; + + return $methodAnnotation; + } } catch (AnnotationException $annotationException) { // unable to laod return null; } + + return null; } /**