Skip to content

Commit

Permalink
resolve native ClassMethodReflection
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Feb 23, 2021
1 parent eb0bcef commit d8bd4e3
Showing 1 changed file with 28 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}

Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
}

0 comments on commit d8bd4e3

Please sign in to comment.