Skip to content

Commit b8a841b

Browse files
committed
Repair PhpParser\Node\Stmt\Class_::isAnonymous()
1 parent 8f19e31 commit b8a841b

File tree

5 files changed

+36
-11
lines changed

5 files changed

+36
-11
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@
117117
use PHPStan\Node\UnreachableStatementNode;
118118
use PHPStan\Node\VariableAssignNode;
119119
use PHPStan\Node\VarTagChangedExpressionTypeNode;
120-
use PHPStan\Parser\AnonymousClassVisitor;
121120
use PHPStan\Parser\ArrowFunctionArgVisitor;
122121
use PHPStan\Parser\ClosureArgVisitor;
123122
use PHPStan\Parser\Parser;
@@ -856,7 +855,7 @@ private function processStmtNode(
856855
if ($stmt->name === null) {
857856
throw new ShouldNotHappenException();
858857
}
859-
if ($stmt->getAttribute(AnonymousClassVisitor::ATTRIBUTE_ANONYMOUS_CLASS, false) === false) {
858+
if (!$stmt->isAnonymous()) {
860859
$classReflection = $this->reflectionProvider->getClass($stmt->name->toString());
861860
} else {
862861
$classReflection = $this->reflectionProvider->getAnonymousClassReflection($stmt, $scope);

src/Node/AnonymousClassNode.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Node;
4+
5+
use PhpParser\Node\Stmt\Class_;
6+
7+
/**
8+
* The only purpose of this is to fix {@see Class_::isAnonymous()}, broken by us giving anonymous classes a name.
9+
*/
10+
final class AnonymousClassNode extends Class_
11+
{
12+
13+
public function isAnonymous(): bool
14+
{
15+
return true;
16+
}
17+
18+
}

src/Parser/AnonymousClassVisitor.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55
use PhpParser\Node;
66
use PhpParser\NodeVisitorAbstract;
7+
use PHPStan\Node\AnonymousClassNode;
78
use function count;
89

910
class AnonymousClassVisitor extends NodeVisitorAbstract
1011
{
1112

12-
public const ATTRIBUTE_ANONYMOUS_CLASS = 'anonymousClass';
1313
public const ATTRIBUTE_LINE_INDEX = 'anonymousClassLineIndex';
1414

15-
/** @var array<int, non-empty-list<Node\Stmt\Class_>> */
15+
/** @var array<int, non-empty-list<AnonymousClassNode>> */
1616
private array $nodesPerLine = [];
1717

1818
public function beforeTraverse(array $nodes): ?array
@@ -27,10 +27,20 @@ public function enterNode(Node $node): ?Node
2727
return null;
2828
}
2929

30-
$node->setAttribute(self::ATTRIBUTE_ANONYMOUS_CLASS, true);
30+
$node = new AnonymousClassNode(
31+
$node->name,
32+
[
33+
'flags' => $node->flags,
34+
'extends' => $node->extends,
35+
'implements' => $node->implements,
36+
'stmts' => $node->stmts,
37+
'attrGroups' => $node->attrGroups,
38+
],
39+
$node->getAttributes(),
40+
);
3141
$this->nodesPerLine[$node->getStartLine()][] = $node;
3242

33-
return null;
43+
return $node;
3444
}
3545

3646
public function afterTraverse(array $nodes): ?array

src/Type/FileTypeMapper.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use PHPStan\BetterReflection\Util\GetLastDocComment;
99
use PHPStan\Broker\AnonymousClassNameHelper;
1010
use PHPStan\File\FileHelper;
11-
use PHPStan\Parser\AnonymousClassVisitor;
1211
use PHPStan\Parser\Parser;
1312
use PHPStan\PhpDoc\PhpDocNodeResolver;
1413
use PHPStan\PhpDoc\PhpDocStringResolver;
@@ -261,7 +260,7 @@ function (Node $node) use ($fileName, $lookForTrait, &$traitFound, $traitMethodA
261260
}
262261

263262
$className = $this->anonymousClassNameHelper->getAnonymousClassName($node, $fileName);
264-
} elseif ((bool) $node->getAttribute(AnonymousClassVisitor::ATTRIBUTE_ANONYMOUS_CLASS, false)) {
263+
} elseif ($node instanceof Node\Stmt\Class_ && $node->isAnonymous()) {
265264
$className = $node->name->name;
266265
} else {
267266
if ($traitFound) {
@@ -452,7 +451,7 @@ function (Node $node) use ($fileName, $lookForTrait, $phpDocNodeMap, &$traitFoun
452451
}
453452

454453
$className = $this->anonymousClassNameHelper->getAnonymousClassName($node, $fileName);
455-
} elseif ((bool) $node->getAttribute(AnonymousClassVisitor::ATTRIBUTE_ANONYMOUS_CLASS, false)) {
454+
} elseif ($node instanceof Node\Stmt\Class_ && $node->isAnonymous()) {
456455
$className = $node->name->name;
457456
} else {
458457
if ($traitFound) {

tests/PHPStan/Reflection/AnonymousClassReflectionTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use PhpParser\Node;
66
use PhpParser\Node\Stmt\Class_;
77
use PHPStan\Analyser\Scope;
8-
use PHPStan\Parser\AnonymousClassVisitor;
98
use PHPStan\Rules\Rule;
109
use PHPStan\Rules\RuleErrorBuilder;
1110
use PHPStan\Testing\RuleTestCase;
@@ -36,7 +35,7 @@ public function getNodeType(): string
3635

3736
public function processNode(Node $node, Scope $scope): array
3837
{
39-
if (!(bool) $node->getAttribute(AnonymousClassVisitor::ATTRIBUTE_ANONYMOUS_CLASS)) {
38+
if (!$node->isAnonymous()) {
4039
return [];
4140
}
4241

0 commit comments

Comments
 (0)