1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 04:45:20 +01:00

Fix #4982 - ensure destructuring assignments are seen inside a loop

This commit is contained in:
Matt Brown 2021-01-11 12:46:02 -05:00
parent 104647745b
commit 951afcf4af
2 changed files with 38 additions and 5 deletions

View File

@ -27,15 +27,32 @@ class AssignmentMapVisitor extends PhpParser\NodeVisitorAbstract
public function enterNode(PhpParser\Node $node): ?int public function enterNode(PhpParser\Node $node): ?int
{ {
if ($node instanceof PhpParser\Node\Expr\Assign) { if ($node instanceof PhpParser\Node\Expr\Assign) {
$left_var_id = ExpressionIdentifier::getRootVarId($node->var, $this->this_class_name);
$right_var_id = ExpressionIdentifier::getRootVarId($node->expr, $this->this_class_name); $right_var_id = ExpressionIdentifier::getRootVarId($node->expr, $this->this_class_name);
if ($node->var instanceof PhpParser\Node\Expr\List_
|| $node->var instanceof PhpParser\Node\Expr\Array_
) {
foreach ($node->var->items as $assign_item) {
if ($assign_item) {
$left_var_id = ExpressionIdentifier::getRootVarId($assign_item->value, $this->this_class_name);
if ($left_var_id) { if ($left_var_id) {
$this->assignment_map[$left_var_id][$right_var_id ?: 'isset'] = true; $this->assignment_map[$left_var_id][$right_var_id ?: 'isset'] = true;
} }
}
}
} else {
$left_var_id = ExpressionIdentifier::getRootVarId($node->var, $this->this_class_name);
if ($left_var_id) {
$this->assignment_map[$left_var_id][$right_var_id ?: 'isset'] = true;
}
}
return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN; return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN;
} elseif ($node instanceof PhpParser\Node\Expr\PostInc }
if ($node instanceof PhpParser\Node\Expr\PostInc
|| $node instanceof PhpParser\Node\Expr\PostDec || $node instanceof PhpParser\Node\Expr\PostDec
|| $node instanceof PhpParser\Node\Expr\PreInc || $node instanceof PhpParser\Node\Expr\PreInc
|| $node instanceof PhpParser\Node\Expr\PreDec || $node instanceof PhpParser\Node\Expr\PreDec
@ -48,7 +65,9 @@ class AssignmentMapVisitor extends PhpParser\NodeVisitorAbstract
} }
return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN; return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN;
} elseif ($node instanceof PhpParser\Node\Expr\FuncCall) { }
if ($node instanceof PhpParser\Node\Expr\FuncCall) {
foreach ($node->args as $arg) { foreach ($node->args as $arg) {
$arg_var_id = ExpressionIdentifier::getRootVarId($arg->value, $this->this_class_name); $arg_var_id = ExpressionIdentifier::getRootVarId($arg->value, $this->this_class_name);

View File

@ -343,6 +343,20 @@ class DoTest extends \Psalm\Tests\TestCase
if ($b) {}' if ($b) {}'
], ],
'regularAssignmentInsideDo' => [
'<?php
do {
$code = rand(0, 1);
echo "here";
} while ($code === 1);'
],
'destructuringAssignmentInsideDo' => [
'<?php
do {
[$code] = [rand(0, 1)];
echo "here";
} while ($code === 1);'
],
]; ];
} }