1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Add a closure in scope just in time for analysis

This commit is contained in:
Brown 2018-10-04 16:42:40 -04:00
parent 0352babece
commit 9ea2009cd2
2 changed files with 32 additions and 8 deletions

View File

@ -128,17 +128,31 @@ class AssignmentChecker
}
}
if ($assign_value && ExpressionChecker::analyze($statements_checker, $assign_value, $context) === false) {
if ($var_id) {
if ($array_var_id) {
$context->removeDescendents($array_var_id, null, $assign_value_type);
if ($assign_value) {
if ($var_id && $assign_value instanceof PhpParser\Node\Expr\Closure) {
foreach ($assign_value->uses as $closure_use) {
if ($closure_use->byRef
&& is_string($closure_use->var->name)
&& $var_id === '$' . $closure_use->var->name
) {
$context->vars_in_scope[$var_id] = Type::getClosure();
$context->vars_possibly_in_scope[$var_id] = true;
}
}
// if we're not exiting immediately, make everything mixed
$context->vars_in_scope[$var_id] = $comment_type ?: Type::getMixed();
}
return false;
if (ExpressionChecker::analyze($statements_checker, $assign_value, $context) === false) {
if ($var_id) {
if ($array_var_id) {
$context->removeDescendents($array_var_id, null, $assign_value_type);
}
// if we're not exiting immediately, make everything mixed
$context->vars_in_scope[$var_id] = $comment_type ?: Type::getMixed();
}
return false;
}
}
if ($comment_type) {

View File

@ -855,6 +855,16 @@ class UnusedVariableTest extends TestCase
} while (--$i > 0);
echo $i;',
],
'callableReferencesItself' => [
'<?php
/** @psalm-suppress UnusedParam */
function foo(callable $c) : void {}
$listener = function () use (&$listener) : void {
/** @psalm-suppress MixedArgument */
foo($listener);
};
foo($listener);',
],
];
}