|
3 | 3 | namespace PHPStan\Rules\PHPUnit; |
4 | 4 |
|
5 | 5 | use PhpParser\Node; |
| 6 | +use PhpParser\NodeTraverser; |
| 7 | +use PhpParser\NodeVisitor; |
| 8 | +use PhpParser\NodeVisitorAbstract; |
6 | 9 | use PHPStan\Analyser\Scope; |
7 | 10 | use PHPStan\Node\InClassMethodNode; |
8 | 11 | use PHPStan\Rules\Rule; |
@@ -66,43 +69,52 @@ public function processNode(Node $node, Scope $scope): array |
66 | 69 |
|
67 | 70 | /** |
68 | 71 | * @param Node\Stmt[]|null $stmts |
69 | | - * |
70 | 72 | */ |
71 | 73 | private function hasParentClassCall(?array $stmts, string $methodName): bool |
72 | 74 | { |
73 | 75 | if ($stmts === null) { |
74 | 76 | return false; |
75 | 77 | } |
76 | 78 |
|
77 | | - foreach ($stmts as $stmt) { |
78 | | - if (! $stmt instanceof Node\Stmt\Expression) { |
79 | | - continue; |
80 | | - } |
81 | | - |
82 | | - if (! $stmt->expr instanceof Node\Expr\StaticCall) { |
83 | | - continue; |
84 | | - } |
| 79 | + $visitor = new class ($methodName) extends NodeVisitorAbstract { |
85 | 80 |
|
86 | | - if (! $stmt->expr->class instanceof Node\Name) { |
87 | | - continue; |
88 | | - } |
| 81 | + private string $methodName; |
89 | 82 |
|
90 | | - $class = (string) $stmt->expr->class; |
| 83 | + public bool $found = false; |
91 | 84 |
|
92 | | - if (strtolower($class) !== 'parent') { |
93 | | - continue; |
| 85 | + public function __construct(string $methodName) |
| 86 | + { |
| 87 | + $this->methodName = $methodName; |
94 | 88 | } |
95 | 89 |
|
96 | | - if (! $stmt->expr->name instanceof Node\Identifier) { |
97 | | - continue; |
| 90 | + public function enterNode(Node $node): ?int |
| 91 | + { |
| 92 | + if ($node instanceof Node\FunctionLike || $node instanceof Node\Stmt\ClassLike) { |
| 93 | + return NodeVisitor::DONT_TRAVERSE_CHILDREN; |
| 94 | + } |
| 95 | + |
| 96 | + if ( |
| 97 | + $node instanceof Node\Expr\StaticCall |
| 98 | + && !$node->isFirstClassCallable() |
| 99 | + && $node->class instanceof Node\Name |
| 100 | + && $node->class->toLowerString() === 'parent' |
| 101 | + && $node->name instanceof Node\Identifier |
| 102 | + && $node->name->toLowerString() === $this->methodName |
| 103 | + ) { |
| 104 | + $this->found = true; |
| 105 | + |
| 106 | + return NodeVisitor::STOP_TRAVERSAL; |
| 107 | + } |
| 108 | + |
| 109 | + return null; |
98 | 110 | } |
99 | 111 |
|
100 | | - if ($stmt->expr->name->toLowerString() === $methodName) { |
101 | | - return true; |
102 | | - } |
103 | | - } |
| 112 | + }; |
| 113 | + |
| 114 | + $traverser = new NodeTraverser($visitor); |
| 115 | + $traverser->traverse($stmts); |
104 | 116 |
|
105 | | - return false; |
| 117 | + return $visitor->found; |
106 | 118 | } |
107 | 119 |
|
108 | 120 | } |
0 commit comments