Skip to content

Commit ce3ffbd

Browse files
ruudkondrejmirtes
authored andcommitted
Use argument types as parameter types for inline closures when assigned
The functionality was introduced in #1628. It works. But as soon as you use an inline assign expression it breaks. Let's support this case too. Sometimes, you want to call something inline and also use the callback later.
1 parent 8dd41e9 commit ce3ffbd

File tree

4 files changed

+46
-10
lines changed

4 files changed

+46
-10
lines changed

src/Parser/ArrowFunctionArgVisitor.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,28 @@ final class ArrowFunctionArgVisitor extends NodeVisitorAbstract
1313

1414
public function enterNode(Node $node): ?Node
1515
{
16-
if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Expr\ArrowFunction && !$node->isFirstClassCallable()) {
17-
$args = $node->getArgs();
16+
if (!$node instanceof Node\Expr\FuncCall) {
17+
return null;
18+
}
19+
20+
if ($node->isFirstClassCallable()) {
21+
return null;
22+
}
1823

19-
if (count($args) > 0) {
20-
$node->name->setAttribute(self::ATTRIBUTE_NAME, $args);
21-
}
24+
if ($node->name instanceof Node\Expr\Assign && $node->name->expr instanceof Node\Expr\ArrowFunction) {
25+
$arrow = $node->name->expr;
26+
} elseif ($node->name instanceof Node\Expr\ArrowFunction) {
27+
$arrow = $node->name;
28+
} else {
29+
return null;
2230
}
31+
32+
$args = $node->getArgs();
33+
34+
if (count($args) > 0) {
35+
$arrow->setAttribute(self::ATTRIBUTE_NAME, $args);
36+
}
37+
2338
return null;
2439
}
2540

src/Parser/ClosureArgVisitor.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,28 @@ final class ClosureArgVisitor extends NodeVisitorAbstract
1313

1414
public function enterNode(Node $node): ?Node
1515
{
16-
if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Expr\Closure && !$node->isFirstClassCallable()) {
17-
$args = $node->getArgs();
16+
if (!$node instanceof Node\Expr\FuncCall) {
17+
return null;
18+
}
19+
20+
if ($node->isFirstClassCallable()) {
21+
return null;
22+
}
1823

19-
if (count($args) > 0) {
20-
$node->name->setAttribute(self::ATTRIBUTE_NAME, $args);
21-
}
24+
if ($node->name instanceof Node\Expr\Assign && $node->name->expr instanceof Node\Expr\Closure) {
25+
$closure = $node->name->expr;
26+
} elseif ($node->name instanceof Node\Expr\Closure) {
27+
$closure = $node->name;
28+
} else {
29+
return null;
2230
}
31+
32+
$args = $node->getArgs();
33+
34+
if (count($args) > 0) {
35+
$closure->setAttribute(self::ATTRIBUTE_NAME, $args);
36+
}
37+
2338
return null;
2439
}
2540

tests/PHPStan/Analyser/nsrt/arrow-function-argument-type.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public function doFoo(int $integer, array $array, ?string $nullableString)
2121
(fn($a, $b, $c) => assertType('array{int, array{a: int}, string|null}', [$a, $b, $c]))($integer, $array, $nullableString);
2222

2323
(fn($a, $b, $c = null) => assertType('array{int, array{a: int}, mixed}', [$a, $b, $c]))($integer, $array);
24+
25+
($callback = fn($context) => assertType('int', $context))($integer);
2426
}
2527

2628
}

tests/PHPStan/Analyser/nsrt/closure-argument-type.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ public function doFoo(int $integer, array $array, ?string $nullableString)
3535
assertType('array{a: int}', $context2);
3636
assertType('mixed', $context3);
3737
})($integer, $array);
38+
39+
($callback = function($context) {
40+
assertType('int', $context);
41+
})($integer);
3842
}
3943

4044
}

0 commit comments

Comments
 (0)