From d8bd4e394cc664450947a0ada9fa68d60545fc60 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Wed, 24 Feb 2021 00:40:31 +0100 Subject: [PATCH] resolve native ClassMethodReflection --- .../AnnotationReader/NodeAnnotationReader.php | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php b/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php index 139c265ec8b6..35d91cd20446 100644 --- a/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php +++ b/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php @@ -17,6 +17,7 @@ use Rector\DoctrineAnnotationGenerated\PhpDocNode\ConstantReferenceIdentifierRestorer; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\Node\AttributeKey; +use ReflectionMethod; use ReflectionProperty; use Symplify\PackageBuilder\Reflection\PrivatesAccessor; use Throwable; @@ -104,7 +105,7 @@ public function readClassAnnotation(Class_ $class, string $annotationClassName): public function readPropertyAnnotation(Property $property, string $annotationClassName): ?object { $propertyReflection = $this->getNativePropertyReflection($property); - if ($propertyReflection === null) { + if (! $propertyReflection instanceof ReflectionProperty) { throw new ShouldNotHappenException(); } @@ -128,20 +129,14 @@ private function readMethodAnnotation(ClassMethod $classMethod, string $annotati /** @var string $methodName */ $methodName = $this->nodeNameResolver->getName($classMethod); - $reflectionClass = $this->reflectionProvider->getClass($className); - $methodReflection = $reflectionClass->getNativeMethod($methodName); - - // @see https://github.com/phpstan/phpstan-src/commit/5fad625b7770b9c5beebb19ccc1a493839308fb4 - $builtinMethodReflection = $this->privatesAccessor->getPrivateProperty($methodReflection, 'reflection'); - if (! $builtinMethodReflection instanceof BuiltinMethodReflection) { - throw new ShouldNotHappenException(); - } + $nativeMethodReflection = $this->resolveNativeClassMethodReflection($className, $methodName); try { // covers cases like https://github.com/rectorphp/rector/issues/3046 /** @var object[] $methodAnnotations */ - $methodAnnotations = $this->reader->getMethodAnnotations($builtinMethodReflection->getReflection()); + $methodAnnotations = $this->reader->getMethodAnnotations($nativeMethodReflection); + foreach ($methodAnnotations as $methodAnnotation) { if (! is_a($methodAnnotation, $annotationClassName, true)) { continue; @@ -227,4 +222,27 @@ private function getNativePropertyReflection(Property $property): ?ReflectionPro return null; } } + + private function resolveNativeClassMethodReflection(string $className, string $methodName): ReflectionMethod + { + if (! $this->reflectionProvider->hasClass($className)) { + throw new ShouldNotHappenException(); + } + + $reflectionClass = $this->reflectionProvider->getClass($className); + $methodReflection = $reflectionClass->getNativeMethod($methodName); + + // @see https://github.com/phpstan/phpstan-src/commit/5fad625b7770b9c5beebb19ccc1a493839308fb4 + $builtinMethodReflection = $this->privatesAccessor->getPrivateProperty($methodReflection, 'reflection'); + if (! $builtinMethodReflection instanceof BuiltinMethodReflection) { + throw new ShouldNotHappenException(); + } + + $nativeMethodReflection = $builtinMethodReflection->getReflection(); + if (! $nativeMethodReflection instanceof ReflectionMethod) { + throw new ShouldNotHappenException(); + } + + return $nativeMethodReflection; + } }