Skip to content

Commit

Permalink
WrongVariableNameInVarTagRule - fix iteratee variable above foreach
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Feb 8, 2021
1 parent 8b2bc59 commit 3d365fc
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 9 deletions.
3 changes: 3 additions & 0 deletions src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -2897,6 +2897,9 @@ private function processVarAnnotation(MutatingScope $scope, array $variableNames

private function enterForeach(MutatingScope $scope, Foreach_ $stmt): MutatingScope
{
if ($stmt->expr instanceof Variable && is_string($stmt->expr->name)) {
$scope = $this->processVarAnnotation($scope, [$stmt->expr->name], $stmt);
}
$iterateeType = $scope->getType($stmt->expr);
$vars = [];
if ($stmt->valueVar instanceof Variable && is_string($stmt->valueVar->name)) {
Expand Down
7 changes: 5 additions & 2 deletions src/Rules/PhpDoc/WrongVariableNameInVarTagRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function processNode(Node $node, Scope $scope): array
}

if ($node instanceof Node\Stmt\Foreach_) {
return $this->processForeach($node->keyVar, $node->valueVar, $varTags);
return $this->processForeach($node->expr, $node->keyVar, $node->valueVar, $varTags);
}

if ($node instanceof Node\Stmt\Static_) {
Expand Down Expand Up @@ -168,9 +168,12 @@ private function getAssignedVariables(Expr $expr): array
* @param \PHPStan\PhpDoc\Tag\VarTag[] $varTags
* @return \PHPStan\Rules\RuleError[]
*/
private function processForeach(?Node\Expr $keyVar, Node\Expr $valueVar, array $varTags): array
private function processForeach(Node\Expr $iterateeExpr, ?Node\Expr $keyVar, Node\Expr $valueVar, array $varTags): array
{
$variableNames = [];
if ($iterateeExpr instanceof Node\Expr\Variable && is_string($iterateeExpr->name)) {
$variableNames[] = $iterateeExpr->name;
}
if ($keyVar instanceof Node\Expr\Variable && is_string($keyVar->name)) {
$variableNames[] = $keyVar->name;
}
Expand Down
8 changes: 7 additions & 1 deletion tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4776,7 +4776,7 @@ public function dataForeachArrayType(): array
],
[
__DIR__ . '/data/foreach/type-in-comment-no-variable-2.php',
'mixed',
'*ERROR*',
'$value',
],
[
Expand Down Expand Up @@ -10758,6 +10758,11 @@ public function dataBug4500(): array
return $this->gatherAssertTypes(__DIR__ . '/data/bug-4500.php');
}

public function dataBug4504(): array
{
return $this->gatherAssertTypes(__DIR__ . '/data/bug-4504.php');
}

/**
* @param string $file
* @return array<string, mixed[]>
Expand Down Expand Up @@ -10972,6 +10977,7 @@ private function gatherAssertTypes(string $file): array
* @dataProvider dataBug4415
* @dataProvider dataCompact
* @dataProvider dataBug4500
* @dataProvider dataBug4504
* @param string $assertType
* @param string $file
* @param mixed ...$args
Expand Down
21 changes: 21 additions & 0 deletions tests/PHPStan/Analyser/data/bug-4504.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Bug4504TypeInference;

use function PHPStan\Analyser\assertType;

class Foo
{

public function sayHello($models): void
{
/** @var \Iterator<A> $models */
foreach ($models as $k => $v) {
assertType('Bug4504TypeInference\A', $v);
}

assertType('array()|Iterator<mixed, Bug4504TypeInference\A>', $models);
}

}

15 changes: 10 additions & 5 deletions tests/PHPStan/Rules/PhpDoc/WrongVariableNameInVarTagRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@ public function testRule(): void
23,
],
[
'Variable $list in PHPDoc tag @var does not match any variable in the foreach loop: $key, $var',
29,
],
[
'Variable $foo in PHPDoc tag @var does not match any variable in the foreach loop: $key, $val',
'Variable $foo in PHPDoc tag @var does not match any variable in the foreach loop: $list, $key, $val',
66,
],
[
Expand Down Expand Up @@ -86,6 +82,10 @@ public function testRule(): void
'Variable $foo in PHPDoc tag @var does not exist.',
210,
],
[
'PHPDoc tag @var above foreach loop does not specify variable name.',
234,
],
[
'Variable $foo in PHPDoc tag @var does not exist.',
248,
Expand Down Expand Up @@ -151,4 +151,9 @@ public function testBug4500(): void
]);
}

public function testBug4504(): void
{
$this->analyse([__DIR__ . '/data/bug-4504.php'], []);
}

}
16 changes: 16 additions & 0 deletions tests/PHPStan/Rules/PhpDoc/data/bug-4504.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Bug4504;

class Foo
{

public function sayHello($models): void
{
/** @var \Iterator<A> $models */
foreach ($models as $k => $v) {

}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function doFoo()
public function doBar(array $list)
{
/** @var int[] $list */
foreach ($list as $key => $var) { // ERROR
foreach ($list as $key => $var) {

}

Expand Down

0 comments on commit 3d365fc

Please sign in to comment.