Skip to content

Commit 07bb938

Browse files
committed
resolve self/static class name via node type instead of scope reflection
1 parent 5a93f7f commit 07bb938

4 files changed

Lines changed: 28 additions & 43 deletions

File tree

‎phpstan.neon‎

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,25 +84,15 @@ parameters:
8484
-
8585
identifier: rector.getClassReflectionOnScope
8686
paths:
87-
- rules/CodeQuality/Rector/Class_/ConvertStaticToSelfRector.php
8887
- rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php
8988
- rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php
9089
- rules/Php55/Rector/FuncCall/GetCalledClassToStaticClassRector.php
91-
- rules/Php70/Rector/ClassMethod/Php4ConstructorRector.php
92-
- rules/Php70/Rector/MethodCall/ThisCallOnStaticMethodToStaticCallRector.php
9390
- rules/Php81/Rector/Array_/ArrayToFirstClassCallableRector.php
94-
- rules/Php81/Rector/FuncCall/NullToStrictIntPregSlitFuncCallLimitArgRector.php
95-
- rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php
9691
- rules/Php81/Rector/New_/MyCLabsConstructorCallToEnumFromRector.php
97-
- rules/Php82/NodeManipulator/ReadonlyClassManipulator.php
98-
- rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php
9992
- rules/Renaming/Rector/MethodCall/RenameMethodRector.php
10093
- rules/TypeDeclaration/PHPStan/ObjectTypeSpecifier.php
101-
- rules/TypeDeclaration/Rector/ClassMethod/AddVoidReturnTypeWhereNoReturnRector.php
102-
- rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector.php
10394
- rules/TypeDeclaration/Rector/Closure/ClosureReturnTypeFromAssertInstanceOfRector.php
10495
- src/Application/ChangedNodeScopeRefresher.php
105-
- src/NodeCollector/ScopeResolver/ParentClassScopeResolver.php
10696
- src/NodeTypeResolver/NodeTypeResolver.php
10797
- src/NodeTypeResolver/NodeTypeResolver/ClassAndInterfaceTypeResolver.php
10898
- src/NodeTypeResolver/NodeTypeResolver/NameTypeResolver.php

‎rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector.php‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use PhpParser\Node\Stmt\ClassMethod;
1313
use PhpParser\Node\Stmt\Function_;
1414
use PhpParser\Node\Stmt\Return_;
15-
use PHPStan\Reflection\ClassReflection;
1615
use PHPStan\Reflection\ReflectionProvider;
1716
use PHPStan\Type\ObjectType;
1817
use PHPStan\Type\ObjectWithoutClassType;
@@ -27,9 +26,9 @@
2726
use Rector\PHPStan\ScopeFetcher;
2827
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
2928
use Rector\Rector\AbstractRector;
30-
use Rector\Reflection\ReflectionResolver;
3129
use Rector\RuleDoc\CodeSample\CodeSample;
3230
use Rector\RuleDoc\RuleDefinition;
31+
use Rector\StaticTypeMapper\Resolver\ClassNameFromObjectTypeResolver;
3332
use Rector\StaticTypeMapper\StaticTypeMapper;
3433
use Rector\StaticTypeMapper\ValueObject\Type\SelfStaticType;
3534
use Rector\Symfony\CodeQuality\Enum\ResponseClass;
@@ -48,7 +47,6 @@ final class ReturnTypeFromReturnNewRector extends AbstractRector implements MinP
4847
public function __construct(
4948
private readonly TypeFactory $typeFactory,
5049
private readonly ReflectionProvider $reflectionProvider,
51-
private readonly ReflectionResolver $reflectionResolver,
5250
private readonly StrictReturnNewAnalyzer $strictReturnNewAnalyzer,
5351
private readonly ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard,
5452
private readonly ClassAnalyzer $classAnalyzer,
@@ -156,11 +154,14 @@ private function createObjectTypeFromNew(New_ $new): ObjectType|ObjectWithoutCla
156154

157155
$className = $this->getName($new->class);
158156
if ($className === ObjectReference::STATIC || $className === ObjectReference::SELF) {
159-
$classReflection = $this->reflectionResolver->resolveClassReflection($new);
160-
if (! $classReflection instanceof ClassReflection) {
157+
$classType = $this->nodeTypeResolver->getType($new->class);
158+
$resolvedClassName = ClassNameFromObjectTypeResolver::resolve($classType);
159+
if ($resolvedClassName === null || ! $this->reflectionProvider->hasClass($resolvedClassName)) {
161160
throw new ShouldNotHappenException();
162161
}
163162

163+
$classReflection = $this->reflectionProvider->getClass($resolvedClassName);
164+
164165
if ($className === ObjectReference::SELF) {
165166
return new SelfStaticType($classReflection);
166167
}

‎src/NodeTypeResolver/NodeTypeResolver/ClassAndInterfaceTypeResolver.php‎

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,11 @@
77
use PhpParser\Node;
88
use PhpParser\Node\Stmt\Class_;
99
use PhpParser\Node\Stmt\Interface_;
10-
use PHPStan\Analyser\Scope;
11-
use PHPStan\Reflection\ClassReflection;
12-
use PHPStan\Type\MixedType;
10+
use PHPStan\Reflection\ReflectionProvider;
1311
use PHPStan\Type\ObjectType;
1412
use PHPStan\Type\Type;
1513
use Rector\NodeNameResolver\NodeNameResolver;
1614
use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
17-
use Rector\NodeTypeResolver\Node\AttributeKey;
1815

1916
/**
2017
* @see \Rector\Tests\NodeTypeResolver\PerNodeTypeResolver\ClassAndInterfaceTypeResolver\ClassTypeResolverTest
@@ -25,7 +22,8 @@
2522
final readonly class ClassAndInterfaceTypeResolver implements NodeTypeResolverInterface
2623
{
2724
public function __construct(
28-
private NodeNameResolver $nodeNameResolver
25+
private NodeNameResolver $nodeNameResolver,
26+
private ReflectionProvider $reflectionProvider,
2927
) {
3028
}
3129

@@ -42,18 +40,11 @@ public function getNodeClasses(): array
4240
*/
4341
public function resolve(Node $node): Type
4442
{
45-
$scope = $node->getAttribute(AttributeKey::SCOPE);
46-
47-
if (! $scope instanceof Scope) {
48-
// new node probably
49-
return new MixedType();
50-
}
51-
52-
$classReflection = $scope->getClassReflection();
53-
if (! $classReflection instanceof ClassReflection) {
54-
return new ObjectType((string) $this->nodeNameResolver->getName($node));
43+
$className = $this->nodeNameResolver->getName($node);
44+
if ($className === null || ! $this->reflectionProvider->hasClass($className)) {
45+
return new ObjectType((string) $className);
5546
}
5647

57-
return new ObjectType($classReflection->getName(), null, $classReflection);
48+
return new ObjectType($className, null, $this->reflectionProvider->getClass($className));
5849
}
5950
}

‎src/PhpParser/Node/Value/ValueResolver.php‎

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,10 @@ public function getValue(Arg|Expr|InterpolatedStringPart $expr, bool $resolvedCl
7474
$class = $this->nodeNameResolver->getName($expr->class);
7575

7676
if (in_array($class, [ObjectReference::SELF, ObjectReference::STATIC], true)) {
77-
$classReflection = $this->reflectionResolver->resolveClassReflection($expr);
78-
if ($classReflection instanceof ClassReflection) {
79-
return $classReflection->getName();
77+
$classType = $this->nodeTypeResolver->getType($expr->class);
78+
$className = ClassNameFromObjectTypeResolver::resolve($classType);
79+
if ($className !== null) {
80+
return $className;
8081
}
8182
}
8283

@@ -333,18 +334,20 @@ private function resolveClassFromSelfStaticParent(ClassConstFetch $classConstFet
333334
return '';
334335
}
335336

336-
$classReflection = $this->reflectionResolver->resolveClassReflection($classConstFetch);
337-
if (! $classReflection instanceof ClassReflection) {
338-
throw new ShouldNotHappenException(
339-
'Complete class parent node for to class const fetch, so "self" or "static" references is resolvable to a class name'
340-
);
341-
}
342-
343337
if ($class !== ObjectReference::PARENT) {
344-
return $classReflection->getName();
338+
$classType = $this->nodeTypeResolver->getType($classConstFetch->class);
339+
$className = ClassNameFromObjectTypeResolver::resolve($classType);
340+
if ($className === null) {
341+
throw new ShouldNotHappenException(
342+
'Complete class parent node for to class const fetch, so "self" or "static" references is resolvable to a class name'
343+
);
344+
}
345+
346+
return $className;
345347
}
346348

347-
if (! $classReflection->isClass()) {
349+
$classReflection = $this->reflectionResolver->resolveClassReflection($classConstFetch);
350+
if (! $classReflection instanceof ClassReflection || ! $classReflection->isClass()) {
348351
throw new ShouldNotHappenException(
349352
'Complete class parent node for to class const fetch, so "parent" references is resolvable to lookup parent class'
350353
);

0 commit comments

Comments
 (0)