1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Make foreach var annotation use more cautious

This commit is contained in:
Matthew Brown 2019-01-20 11:49:13 -05:00
parent af19ca4bd5
commit 5eb0bb8126
2 changed files with 73 additions and 0 deletions

View File

@ -66,11 +66,42 @@ class ForeachAnalyzer
}
}
$safe_var_ids = [];
if ($stmt->keyVar instanceof PhpParser\Node\Expr\Variable && is_string($stmt->keyVar->name)) {
$safe_var_ids['$' . $stmt->keyVar->name] = true;
}
if ($stmt->valueVar instanceof PhpParser\Node\Expr\Variable && is_string($stmt->valueVar->name)) {
$safe_var_ids['$' . $stmt->valueVar->name] = true;
} elseif ($stmt->valueVar instanceof PhpParser\Node\Expr\List_) {
foreach ($stmt->valueVar->items as $list_item) {
if (!$list_item) {
continue;
}
$list_item_key = $list_item->key;
$list_item_value = $list_item->value;
if ($list_item_value instanceof PhpParser\Node\Expr\Variable && is_string($list_item_value->name)) {
$safe_var_ids['$' . $list_item_value->name] = true;
}
if ($list_item_key instanceof PhpParser\Node\Expr\Variable && is_string($list_item_key->name)) {
$safe_var_ids['$' . $list_item_key->name] = true;
}
}
}
foreach ($var_comments as $var_comment) {
if (!$var_comment->var_id) {
continue;
}
if (isset($safe_var_ids[$var_comment->var_id])) {
continue;
}
$comment_type = ExpressionAnalyzer::fleshOutType(
$codebase,
$var_comment->type,

View File

@ -797,6 +797,48 @@ class AnnotationTest extends TestCase
echo strlen($a);',
],
'annotationOnForeachItems' => [
'<?php
function foo(array $arr) : void {
$item = null;
/** @var string $item */
foreach ($arr as $item) {}
if (is_null($item)) {}
}
function bar(array $arr) : void {
$item = null;
/** @var string $item */
foreach ($arr as $item => $_) {}
if (is_null($item)) {}
}
function bat(array $arr) : void {
$item = null;
/** @var string $item */
foreach ($arr as list($item)) {}
if (is_null($item)) {}
}
function baz(array $arr) : void {
$item = null;
/** @var string $item */
foreach ($arr as list($item => $_)) {}
if (is_null($item)) {}
}',
[],
[
'MixedAssignment'
]
],
];
}