-
-
Notifications
You must be signed in to change notification settings - Fork 947
Feature request: Carry types into invoked callable/closure #7798
Copy link
Copy link
Closed
Labels
Description
Feature request
It would be nice if PhpStan could use the types of the arguments passed to a closure for the parameters of that closure.
Discussed in #7797
Originally posted by leongersen August 15, 2022
I'm trying to analyse some generated code.
Is there a way to have PhpStan "carry" the known types into an (inline) function invocation?
$context = ['a' => 3];
\PHPStan\dumpType($context['a']); // 3
(function($context) {
\PHPStan\dumpType($context['a']); // mixed
})($context);I tried giving this a shot, but I got stuck in the details of NodeScopeResolver.
I got towards something along the type lines of:
// When processing FuncCall
if ($expr->name instanceof Expr\Closure) {
$args = $expr->getArgs();
$params = $nameType->getParams();
foreach ($args as $index => $arg) {
$paramExpr = $params[$index]->var;
$argType = $scope->getType($arg->value);
$scope = $scope->assignExpression($paramExpr, $argType);
}
}I don't really understand the internals well enough to continue. (Especially around ParametersAcceptorSelector. I'm not sure if I need to extend NodeScopeResolver::processArgs to set the parameter types).
A start to the testcase for NodeScopeResolverTest:
namespace ClosureArgumentType;
use function PHPStan\Testing\assertType;
class Foo
{
/**
* @param array{a: int} $array
*/
public function doFoo(int $integer, array $array, ?string $nullableString)
{
(function($context) {
assertType('int', $context);
})($integer);
(function($context) {
assertType('array{a: int}', $context);
})($array);
(function($context) {
assertType('?string', $context);
})($nullableString);
(function($context1, $context2, $context3) {
assertType('int', $context1);
assertType('array{a: int}', $context2);
assertType('?string', $context3);
})($integer, $array, $nullableString);
// Cases where arguments are unpacked should be added
}
}Reactions are currently unavailable