Skip to content

Commit

Permalink
[PhpParser] Remove parent lookup on ValueResolver (#4337)
Browse files Browse the repository at this point in the history
* [PhpParser] Remove parent lookup on ValueResolver

* Fix

* Trigger build

* typo fix

* fix test

* reduce complexity
  • Loading branch information
samsonasik committed Jun 24, 2023
1 parent fe0f45e commit 3f8c7e9
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 24 deletions.
56 changes: 34 additions & 22 deletions src/PhpParser/Node/Value/ValueResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@
use PhpParser\ConstExprEvaluationException;
use PhpParser\ConstExprEvaluator;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\BinaryOp\Concat;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\MagicConst\Dir;
use PhpParser\Node\Scalar\MagicConst\File;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\ConstantScalarType;
use PHPStan\Type\TypeWithClassName;
use Rector\Core\Enum\ObjectReference;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeAnalyzer\ConstFetchAnalyzer;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\Provider\CurrentFileProvider;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\Util\Reflection\PrivatesAccessor;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\NodeTypeResolver;

Expand All @@ -42,7 +42,8 @@ public function __construct(
private readonly ConstFetchAnalyzer $constFetchAnalyzer,
private readonly ReflectionProvider $reflectionProvider,
private readonly CurrentFileProvider $currentFileProvider,
private readonly BetterNodeFinder $betterNodeFinder
private readonly ReflectionResolver $reflectionResolver,
private readonly PrivatesAccessor $privatesAccessor
) {
}

Expand All @@ -61,10 +62,9 @@ public function getValue(Expr $expr, bool $resolvedClassReference = false): mixe
$class = $this->nodeNameResolver->getName($expr->class);

if (in_array($class, [ObjectReference::SELF, ObjectReference::STATIC], true)) {
// @todo scope is needed
$classLike = $this->betterNodeFinder->findParentType($expr, ClassLike::class);
if ($classLike instanceof ClassLike) {
return (string) $this->nodeNameResolver->getName($classLike);
$classReflection = $this->reflectionResolver->resolveClassReflection($expr);
if ($classReflection instanceof ClassReflection) {
return $classReflection->getName();
}
}

Expand All @@ -73,6 +73,10 @@ public function getValue(Expr $expr, bool $resolvedClassReference = false): mixe
}
}

if ($expr instanceof ArrayDimFetch) {
return null;
}

$value = $this->resolveExprValueForConst($expr);

if ($value !== null) {
Expand Down Expand Up @@ -307,27 +311,35 @@ private function resolveClassConstFetch(ClassConstFetch $classConstFetch)

private function resolveClassFromSelfStaticParent(ClassConstFetch $classConstFetch, string $class): string
{
$classLike = $this->betterNodeFinder->findParentType($classConstFetch, ClassLike::class);
if (! $classLike instanceof ClassLike) {
$classReflection = $this->reflectionResolver->resolveClassReflection($classConstFetch);
if (! $classReflection instanceof ClassReflection) {
throw new ShouldNotHappenException(
'Complete class parent node for to class const fetch, so "self" or "static" references is resolvable to a class name'
);
}

if ($class === ObjectReference::PARENT) {
if (! $classLike instanceof Class_) {
throw new ShouldNotHappenException(
'Complete class parent node for to class const fetch, so "parent" references is resolvable to lookup parent class'
);
}
if ($class !== ObjectReference::PARENT) {
return $classReflection->getName();
}

if (! $classLike->extends instanceof FullyQualified) {
throw new ShouldNotHappenException();
}
if (! $classReflection->isClass()) {
throw new ShouldNotHappenException(
'Complete class parent node for to class const fetch, so "parent" references is resolvable to lookup parent class'
);
}

return $classLike->extends->toString();
// ensure parent class name still resolved even not autoloaded
$nativeReflection = $classReflection->getNativeReflection();
$betterReflectionClass = $this->privatesAccessor->getPrivateProperty(
$nativeReflection,
'betterReflectionClass'
);
$parentClassName = $this->privatesAccessor->getPrivateProperty($betterReflectionClass, 'parentClassName');

if ($parentClassName === null) {
throw new ShouldNotHappenException();
}

return (string) $this->nodeNameResolver->getName($classLike);
return $parentClassName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Symfony\Rector\ClassMethod\ReplaceSensioRouteAnnotationWithSymfonyRector;
use Rector\Symfony\Symfony34\Rector\ClassMethod\ReplaceSensioRouteAnnotationWithSymfonyRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->importNames(true, false);
Expand Down
2 changes: 1 addition & 1 deletion tests/Issues/Issue6496/config/configure_rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Symfony\Rector\ClassMethod\ReplaceSensioRouteAnnotationWithSymfonyRector;
use Rector\Symfony\Symfony34\Rector\ClassMethod\ReplaceSensioRouteAnnotationWithSymfonyRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->importNames();
Expand Down

0 comments on commit 3f8c7e9

Please sign in to comment.