Skip to content

Commit f06b41b

Browse files
committed
Add bound class scope to node attribute
1 parent 599ac2b commit f06b41b

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

src/Parser/ClosureBindArgVisitor.php

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

55
use Override;
66
use PhpParser\Node;
7+
use PhpParser\Node\Expr;
78
use PhpParser\Node\Identifier;
9+
use PhpParser\Node\Name;
810
use PhpParser\NodeVisitorAbstract;
911
use PHPStan\DependencyInjection\AutowiredService;
12+
use function array_key_exists;
13+
use function array_shift;
14+
use function array_unshift;
1015
use function count;
1116

1217
#[AutowiredService]
@@ -15,6 +20,11 @@ final class ClosureBindArgVisitor extends NodeVisitorAbstract
1520

1621
public const ATTRIBUTE_NAME = 'closureBindArg';
1722

23+
public const SCOPE_ATTRIBUTE_NAME = 'closureBindScope';
24+
25+
/** @var list<?Expr> */
26+
private array $scopeStack = [];
27+
1828
#[Override]
1929
public function enterNode(Node $node): ?Node
2030
{
@@ -30,7 +40,35 @@ public function enterNode(Node $node): ?Node
3040
if (count($args) > 1) {
3141
$args[0]->setAttribute(self::ATTRIBUTE_NAME, true);
3242
}
43+
44+
// null means default scope "static"
45+
array_unshift($this->scopeStack, $args[2]->value ?? null);
46+
}
47+
48+
if ($node instanceof Name
49+
&& array_key_exists(0, $this->scopeStack)
50+
&& $node->isSpecialClassName()
51+
) {
52+
$node->setAttribute(self::SCOPE_ATTRIBUTE_NAME, $this->scopeStack[0]);
53+
}
54+
55+
return null;
56+
}
57+
58+
#[Override]
59+
public function leaveNode(Node $node): ?Node
60+
{
61+
if (
62+
$node instanceof Node\Expr\StaticCall
63+
&& $node->class instanceof Node\Name
64+
&& $node->class->toLowerString() === 'closure'
65+
&& $node->name instanceof Identifier
66+
&& $node->name->toLowerString() === 'bind'
67+
&& !$node->isFirstClassCallable()
68+
) {
69+
array_shift($this->scopeStack);
3370
}
71+
3472
return null;
3573
}
3674

0 commit comments

Comments
 (0)