|
10 | 10 | use PhpParser\Node\Expr; |
11 | 11 | use PhpParser\Node\Expr\Array_; |
12 | 12 | use PhpParser\Node\Expr\ArrayDimFetch; |
| 13 | +use PhpParser\Node\Expr\ArrowFunction; |
13 | 14 | use PhpParser\Node\Expr\Assign; |
14 | 15 | use PhpParser\Node\Expr\AssignOp; |
15 | 16 | use PhpParser\Node\Expr\AssignRef; |
|
20 | 21 | use PhpParser\Node\Expr\Cast; |
21 | 22 | use PhpParser\Node\Expr\ClassConstFetch; |
22 | 23 | use PhpParser\Node\Expr\Clone_; |
| 24 | +use PhpParser\Node\Expr\Closure; |
23 | 25 | use PhpParser\Node\Expr\ConstFetch; |
24 | 26 | use PhpParser\Node\Expr\Empty_; |
25 | 27 | use PhpParser\Node\Expr\ErrorSuppress; |
@@ -378,6 +380,11 @@ private function fillScope(array $stmts, string $filePath, MutatingScope $scope) |
378 | 380 |
|
379 | 381 | return; |
380 | 382 | } |
| 383 | + |
| 384 | + // PHPStan does not process attributes of closures and arrow functions |
| 385 | + if (($node instanceof Closure || $node instanceof ArrowFunction) && $node->attrGroups !== []) { |
| 386 | + $this->processClosureAttributeGroups($node, $mutatingScope, $nodeCallback); |
| 387 | + } |
381 | 388 | }; |
382 | 389 |
|
383 | 390 | try { |
@@ -416,6 +423,32 @@ private function processIssetOrUnset(Isset_|Unset_ $node, MutatingScope $mutatin |
416 | 423 | } |
417 | 424 | } |
418 | 425 |
|
| 426 | + /** |
| 427 | + * @param callable(Node $node, MutatingScope $scope): void $nodeCallback |
| 428 | + */ |
| 429 | + private function processClosureAttributeGroups( |
| 430 | + Closure|ArrowFunction $node, |
| 431 | + MutatingScope $mutatingScope, |
| 432 | + callable $nodeCallback |
| 433 | + ): void { |
| 434 | + $argExpressions = []; |
| 435 | + foreach ($node->attrGroups as $attrGroup) { |
| 436 | + $attrGroup->setAttribute(AttributeKey::SCOPE, $mutatingScope); |
| 437 | + |
| 438 | + foreach ($attrGroup->attrs as $attr) { |
| 439 | + $attr->setAttribute(AttributeKey::SCOPE, $mutatingScope); |
| 440 | + $attr->name->setAttribute(AttributeKey::SCOPE, $mutatingScope); |
| 441 | + |
| 442 | + foreach ($attr->args as $arg) { |
| 443 | + $arg->setAttribute(AttributeKey::SCOPE, $mutatingScope); |
| 444 | + $argExpressions[] = new Expression($arg->value); |
| 445 | + } |
| 446 | + } |
| 447 | + } |
| 448 | + |
| 449 | + $this->nodeScopeResolverProcessNodes($argExpressions, $mutatingScope, $nodeCallback); |
| 450 | + } |
| 451 | + |
419 | 452 | private function processEcho(Echo_ $echo, MutatingScope $mutatingScope): void |
420 | 453 | { |
421 | 454 | foreach ($echo->exprs as $expr) { |
|
0 commit comments