Skip to content

Commit 4cad0c6

Browse files
committed
Fix anonymous class that extends the outer class
1 parent 5958c29 commit 4cad0c6

File tree

13 files changed

+67
-70
lines changed

13 files changed

+67
-70
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,8 @@ jobs:
439439
extensions: ""
440440
- script: "bin/phpstan analyse -l 8 -c tests/e2e/magic-setter/test.neon tests/e2e/magic-setter/test.php"
441441
extensions: ""
442+
- script: "bin/phpstan analyse -l 8 tests/e2e/anon-class/Granularity.php"
443+
extensions: ""
442444

443445
steps:
444446
- name: "Checkout"

build.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@
180180
<arg value="--encoding=utf-8"/>
181181
<arg value="--tab-width=4"/>
182182
<arg value="--cache=tmp/cache/phpcs"/>
183-
<arg value="--ignore=tests/*/data,tests/*/traits,tests/notAutoloaded,tests/*/cache,src/Reflection/SignatureMap/functionMap.php,tests/e2e/magic-setter"/>
183+
<arg value="--ignore=tests/*/data,tests/*/traits,tests/notAutoloaded,tests/*/cache,src/Reflection/SignatureMap/functionMap.php,tests/e2e/magic-setter,tests/e2e/anon-class"/>
184184
<arg value="-sp"/>
185185
<arg path="src"/>
186186
<arg path="tests"/>
@@ -201,6 +201,7 @@
201201
<arg value="--extensions=php"/>
202202
<arg value="--encoding=utf-8"/>
203203
<arg value="--tab-width=4"/>
204+
<arg value="--ignore=tests/*/data,tests/*/traits,tests/notAutoloaded,tests/*/cache,src/Reflection/SignatureMap/functionMap.php,tests/e2e/magic-setter,tests/e2e/anon-class"/>
204205
<arg value="-sp"/>
205206
<arg path="src"/>
206207
<arg path="tests"/>

build/baseline-7.4.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,6 @@ parameters:
9494
count: 1
9595
path: ../src/Reflection/ReflectionProvider/SetterReflectionProviderProvider.php
9696
-
97-
message: "#^Class class@anonymous/src/Testing/TestCase\\.php\\:262 has an uninitialized property \\$reflectionProvider\\. Give it default value or assign it in the constructor\\.$#"
97+
message: "#^Class class@anonymous/src/Testing/TestCase\\.php\\:258 has an uninitialized property \\$reflectionProvider\\. Give it default value or assign it in the constructor\\.$#"
9898
count: 1
9999
path: ../src/Testing/TestCase.php

src/Broker/Broker.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ public function getClassName(string $className): string
7373
return $this->reflectionProvider->getClassName($className);
7474
}
7575

76+
public function supportsAnonymousClasses(): bool
77+
{
78+
return $this->reflectionProvider->supportsAnonymousClasses();
79+
}
80+
7681
public function getAnonymousClassReflection(\PhpParser\Node\Stmt\Class_ $classNode, Scope $scope): ClassReflection
7782
{
7883
return $this->reflectionProvider->getAnonymousClassReflection($classNode, $scope);

src/Reflection/BetterReflection/BetterReflectionProvider.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ public function getClassName(string $className): string
167167
return $reflectionClass->getName();
168168
}
169169

170+
public function supportsAnonymousClasses(): bool
171+
{
172+
return true;
173+
}
174+
170175
public function getAnonymousClassReflection(\PhpParser\Node\Stmt\Class_ $classNode, Scope $scope): ClassReflection
171176
{
172177
if (isset($classNode->namespacedName)) {

src/Reflection/ReflectionProvider.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public function getClass(string $className): ClassReflection;
1313

1414
public function getClassName(string $className): string;
1515

16+
public function supportsAnonymousClasses(): bool;
17+
1618
public function getAnonymousClassReflection(
1719
\PhpParser\Node\Stmt\Class_ $classNode,
1820
Scope $scope

src/Reflection/ReflectionProvider/ChainReflectionProvider.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,26 @@ public function getClassName(string $className): string
6363
throw new \PHPStan\Broker\ClassNotFoundException($className);
6464
}
6565

66+
public function supportsAnonymousClasses(): bool
67+
{
68+
foreach ($this->providers as $provider) {
69+
if (!$provider->supportsAnonymousClasses()) {
70+
continue;
71+
}
72+
73+
return true;
74+
}
75+
76+
return false;
77+
}
78+
6679
public function getAnonymousClassReflection(\PhpParser\Node\Stmt\Class_ $classNode, Scope $scope): ClassReflection
6780
{
6881
foreach ($this->providers as $provider) {
82+
if (!$provider->supportsAnonymousClasses()) {
83+
continue;
84+
}
85+
6986
return $provider->getAnonymousClassReflection($classNode, $scope);
7087
}
7188

src/Reflection/ReflectionProvider/ClassBlacklistReflectionProvider.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,14 @@ public function getClassName(string $className): string
117117
return $this->reflectionProvider->getClassName($className);
118118
}
119119

120+
public function supportsAnonymousClasses(): bool
121+
{
122+
return false;
123+
}
124+
120125
public function getAnonymousClassReflection(\PhpParser\Node\Stmt\Class_ $classNode, Scope $scope): ClassReflection
121126
{
122-
return $this->reflectionProvider->getAnonymousClassReflection($classNode, $scope);
127+
throw new \PHPStan\ShouldNotHappenException();
123128
}
124129

125130
public function hasFunction(\PhpParser\Node\Name $nameNode, ?Scope $scope): bool

src/Reflection/ReflectionProvider/MemoizingReflectionProvider.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ public function getClassName(string $className): string
5757
return $this->classNames[$lowerClassName] = $this->provider->getClassName($className);
5858
}
5959

60+
public function supportsAnonymousClasses(): bool
61+
{
62+
return $this->provider->supportsAnonymousClasses();
63+
}
64+
6065
public function getAnonymousClassReflection(\PhpParser\Node\Stmt\Class_ $classNode, Scope $scope): ClassReflection
6166
{
6267
return $this->provider->getAnonymousClassReflection($classNode, $scope);

src/Reflection/Runtime/RuntimeReflectionProvider.php

Lines changed: 6 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@
44

55
use PhpParser\Node;
66
use PHPStan\Analyser\Scope;
7-
use PHPStan\Broker\AnonymousClassNameHelper;
87
use PHPStan\DependencyInjection\Reflection\ClassReflectionExtensionRegistryProvider;
9-
use PHPStan\File\FileHelper;
10-
use PHPStan\File\RelativePathHelper;
118
use PHPStan\PhpDoc\StubPhpDocProvider;
129
use PHPStan\PhpDoc\Tag\ParamTag;
1310
use PHPStan\Reflection\ClassReflection;
@@ -38,14 +35,6 @@ class RuntimeReflectionProvider implements ReflectionProvider
3835

3936
private \PHPStan\Reflection\SignatureMap\NativeFunctionReflectionProvider $nativeFunctionReflectionProvider;
4037

41-
private \PhpParser\PrettyPrinter\Standard $printer;
42-
43-
private AnonymousClassNameHelper $anonymousClassNameHelper;
44-
45-
private \PHPStan\File\FileHelper $fileHelper;
46-
47-
private RelativePathHelper $relativePathHelper;
48-
4938
private StubPhpDocProvider $stubPhpDocProvider;
5039

5140
/** @var \PHPStan\Reflection\FunctionReflection[] */
@@ -66,10 +55,6 @@ public function __construct(
6655
FunctionReflectionFactory $functionReflectionFactory,
6756
FileTypeMapper $fileTypeMapper,
6857
NativeFunctionReflectionProvider $nativeFunctionReflectionProvider,
69-
\PhpParser\PrettyPrinter\Standard $printer,
70-
AnonymousClassNameHelper $anonymousClassNameHelper,
71-
FileHelper $fileHelper,
72-
RelativePathHelper $relativePathHelper,
7358
StubPhpDocProvider $stubPhpDocProvider
7459
)
7560
{
@@ -78,10 +63,6 @@ public function __construct(
7863
$this->functionReflectionFactory = $functionReflectionFactory;
7964
$this->fileTypeMapper = $fileTypeMapper;
8065
$this->nativeFunctionReflectionProvider = $nativeFunctionReflectionProvider;
81-
$this->printer = $printer;
82-
$this->anonymousClassNameHelper = $anonymousClassNameHelper;
83-
$this->fileHelper = $fileHelper;
84-
$this->relativePathHelper = $relativePathHelper;
8566
$this->stubPhpDocProvider = $stubPhpDocProvider;
8667
}
8768

@@ -137,50 +118,17 @@ public function getClassName(string $className): string
137118
return $realName;
138119
}
139120

121+
public function supportsAnonymousClasses(): bool
122+
{
123+
return false;
124+
}
125+
140126
public function getAnonymousClassReflection(
141127
\PhpParser\Node\Stmt\Class_ $classNode,
142128
Scope $scope
143129
): ClassReflection
144130
{
145-
if (isset($classNode->namespacedName)) {
146-
throw new \PHPStan\ShouldNotHappenException();
147-
}
148-
149-
if (!$scope->isInTrait()) {
150-
$scopeFile = $scope->getFile();
151-
} else {
152-
$scopeFile = $scope->getTraitReflection()->getFileName();
153-
if ($scopeFile === false) {
154-
$scopeFile = $scope->getFile();
155-
}
156-
}
157-
158-
$filename = $this->fileHelper->normalizePath($this->relativePathHelper->getRelativePath($scopeFile), '/');
159-
160-
$className = $this->anonymousClassNameHelper->getAnonymousClassName(
161-
$classNode,
162-
$scopeFile
163-
);
164-
$classNode->name = new \PhpParser\Node\Identifier($className);
165-
$classNode->setAttribute('anonymousClass', true);
166-
167-
if (isset(self::$anonymousClasses[$className])) {
168-
return self::$anonymousClasses[$className];
169-
}
170-
171-
eval($this->printer->prettyPrint([$classNode]));
172-
173-
/** @var class-string $className */
174-
$className = $className;
175-
176-
self::$anonymousClasses[$className] = $this->getClassFromReflection(
177-
new \ReflectionClass($className),
178-
sprintf('class@anonymous/%s:%s', $filename, $classNode->getLine()),
179-
$scopeFile
180-
);
181-
$this->classReflections[$className] = self::$anonymousClasses[$className];
182-
183-
return self::$anonymousClasses[$className];
131+
throw new \PHPStan\ShouldNotHappenException();
184132
}
185133

186134
/**

0 commit comments

Comments
 (0)