Skip to content

Commit d389ae0

Browse files
authored
Merge branch refs/heads/1.11.x into 1.12.x
2 parents e182c06 + 03626d9 commit d389ae0

File tree

5 files changed

+44
-11
lines changed

5 files changed

+44
-11
lines changed

src/Analyser/NodeScopeResolver.php

+1-2
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;
@@ -857,7 +856,7 @@ private function processStmtNode(
857856
if ($stmt->name === null) {
858857
throw new ShouldNotHappenException();
859858
}
860-
if ($stmt->getAttribute(AnonymousClassVisitor::ATTRIBUTE_ANONYMOUS_CLASS, false) === false) {
859+
if (!$stmt->isAnonymous()) {
861860
$classReflection = $this->reflectionProvider->getClass($stmt->name->toString());
862861
} else {
863862
$classReflection = $this->reflectionProvider->getAnonymousClassReflection($stmt, $scope);

src/Node/AnonymousClassNode.php

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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 static function createFromClassNode(Class_ $node): self
14+
{
15+
$subNodes = [];
16+
foreach ($node->getSubNodeNames() as $subNodeName) {
17+
$subNodes[$subNodeName] = $node->$subNodeName;
18+
}
19+
20+
return new AnonymousClassNode(
21+
$node->name,
22+
$subNodes,
23+
$node->getAttributes(),
24+
);
25+
}
26+
27+
public function isAnonymous(): bool
28+
{
29+
return true;
30+
}
31+
32+
}

src/Parser/AnonymousClassVisitor.php

+5-4
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
final 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,11 @@ public function enterNode(Node $node): ?Node
2727
return null;
2828
}
2929

30-
$node->setAttribute(self::ATTRIBUTE_ANONYMOUS_CLASS, true);
30+
$node = AnonymousClassNode::createFromClassNode($node);
31+
$node->setAttribute('anonymousClass', true); // We keep this for backward compatibility
3132
$this->nodesPerLine[$node->getStartLine()][] = $node;
3233

33-
return null;
34+
return $node;
3435
}
3536

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

src/Type/FileTypeMapper.php

+2-3
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

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
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;
11+
use PHPUnit\Framework\Assert;
1212
use function implode;
1313
use function sprintf;
1414

@@ -36,10 +36,12 @@ public function getNodeType(): string
3636

3737
public function processNode(Node $node, Scope $scope): array
3838
{
39-
if (!(bool) $node->getAttribute(AnonymousClassVisitor::ATTRIBUTE_ANONYMOUS_CLASS)) {
39+
if (!$node->isAnonymous()) {
4040
return [];
4141
}
4242

43+
Assert::assertTrue($node->getAttribute('anonymousClass'));
44+
4345
$classReflection = $this->reflectionProvider->getAnonymousClassReflection($node, $scope);
4446

4547
return [

0 commit comments

Comments
 (0)