Skip to content

Commit

Permalink
Fixed issue with foreach variable
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jan 21, 2018
1 parent 3785449 commit 236bb9b
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/Analyser/NodeScopeResolver.php
Expand Up @@ -1033,7 +1033,10 @@ private function lookForAssigns(
$initialScope = $scope;
$scope = $this->enterForeach($scope, $node);
$statements = [
new StatementList($scope, $node->stmts),
new StatementList($scope, array_merge(
[new Node\Stmt\Nop],
$node->stmts
)),
new StatementList($scope, []), // in order not to add variables existing only inside the for loop
];
$scope = $this->lookForAssignsInBranches($initialScope, $statements, LookForAssignsSettings::afterLoop());
Expand Down
37 changes: 37 additions & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Expand Up @@ -3889,8 +3889,45 @@ public function dataLoopVariables(): array
];
}

public function dataForeachLoopVariables(): array
{
return [
[
'int',
'$val',
"'begin';",
],
[
'int',
'$key',
"'begin';",
],
[
'int|null',
'$val',
"'afterLoop';",
],
[
'int|null',
'$key',
"'afterLoop';",
],
[
'int|null',
'$emptyForeachVal',
"'afterLoop';",
],
[
'int|null',
'$emptyForeachKey',
"'afterLoop';",
],
];
}

/**
* @dataProvider dataLoopVariables
* @dataProvider dataForeachLoopVariables
* @param string $description
* @param string $expression
* @param string $evaluatedPointExpression
Expand Down
10 changes: 9 additions & 1 deletion tests/PHPStan/Analyser/data/foreach-loop-variables.php
Expand Up @@ -4,7 +4,9 @@

function () {
$foo = null;
foreach ([] as $val) {
$key = null;
$val = null;
foreach ([1, 2, 3] as $key => $val) {
'begin';
$foo = new Foo();
'afterAssign';
Expand All @@ -25,5 +27,11 @@ function () {
'end';
}

$emptyForeachKey = null;
$emptyForeachVal = null;
foreach ([1, 2, 3] as $emptyForeachKey => $emptyForeachVal) {

}

'afterLoop';
};
8 changes: 8 additions & 0 deletions tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php
Expand Up @@ -243,6 +243,10 @@ public function testCallMethods()
'Parameter #1 $i of method Test\TernaryEvaluation::doBar() expects int, false given.',
568,
],
[
'Parameter #1 $s of method Test\ForeachSituation::takesInt() expects int|null, string|null given.',
595,
],
]);
}

Expand Down Expand Up @@ -372,6 +376,10 @@ public function testCallMethodsOnThisOnly()
'Parameter #1 $i of method Test\TernaryEvaluation::doBar() expects int, false given.',
568,
],
[
'Parameter #1 $s of method Test\ForeachSituation::takesInt() expects int|null, string|null given.',
595,
],
]);
}

Expand Down
22 changes: 22 additions & 0 deletions tests/PHPStan/Rules/Methods/data/call-methods.php
Expand Up @@ -574,3 +574,25 @@ public function doBar(int $i)
}

}

class ForeachSituation
{

public function takesInt(?int $s)
{

}

/**
* @param string[] $letters
*/
public function takesStringArray(array $letters)
{
$letter = null;
foreach ($letters as $letter) {

}
$this->takesInt($letter);
}

}

0 comments on commit 236bb9b

Please sign in to comment.