mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
Fix #334 by allowing interfaces as foreach args to be correctly interpreted
This commit is contained in:
parent
c86e73ddb6
commit
18e68a60de
@ -5,6 +5,7 @@ use PhpParser;
|
||||
use Psalm\Checker\ClassChecker;
|
||||
use Psalm\Checker\ClassLikeChecker;
|
||||
use Psalm\Checker\CommentChecker;
|
||||
use Psalm\Checker\InterfaceChecker;
|
||||
use Psalm\Checker\MethodChecker;
|
||||
use Psalm\Checker\Statements\Expression\AssignmentChecker;
|
||||
use Psalm\Checker\Statements\ExpressionChecker;
|
||||
@ -178,7 +179,15 @@ class ForeachChecker
|
||||
$project_checker,
|
||||
$iterator_type->value,
|
||||
'Iterator'
|
||||
)) {
|
||||
) ||
|
||||
(InterfaceChecker::interfaceExists($project_checker, $iterator_type->value)
|
||||
&& InterfaceChecker::interfaceExtends(
|
||||
$project_checker,
|
||||
$iterator_type->value,
|
||||
'Iterator'
|
||||
)
|
||||
)
|
||||
) {
|
||||
$iterator_method = $iterator_type->value . '::current';
|
||||
$iterator_class_type = MethodChecker::getMethodReturnType($project_checker, $iterator_method);
|
||||
|
||||
@ -202,11 +211,20 @@ class ForeachChecker
|
||||
$project_checker,
|
||||
$iterator_type->value,
|
||||
'Traversable'
|
||||
)) {
|
||||
) ||
|
||||
(InterfaceChecker::interfaceExists($project_checker, $iterator_type->value)
|
||||
&& InterfaceChecker::interfaceExtends(
|
||||
$project_checker,
|
||||
$iterator_type->value,
|
||||
'Traversable'
|
||||
)
|
||||
)
|
||||
) {
|
||||
// @todo try and get value type
|
||||
} elseif (!in_array(
|
||||
strtolower($iterator_type->value),
|
||||
['iterator', 'iterable', 'traversable'], true
|
||||
['iterator', 'iterable', 'traversable'],
|
||||
true
|
||||
)) {
|
||||
if (IssueBuffer::accepts(
|
||||
new RawObjectIteration(
|
||||
|
@ -4,6 +4,43 @@ namespace Psalm\Tests;
|
||||
class ForeachTest extends TestCase
|
||||
{
|
||||
use Traits\FileCheckerInvalidCodeParseTestTrait;
|
||||
use Traits\FileCheckerValidCodeParseTestTrait;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerFileCheckerValidCodeParse()
|
||||
{
|
||||
return [
|
||||
'iteratorAggregateIteration' => [
|
||||
'<?php
|
||||
class C implements IteratorAggregate
|
||||
{
|
||||
public function getIterator(): Iterator
|
||||
{
|
||||
return new ArrayIterator([]);
|
||||
}
|
||||
}
|
||||
|
||||
function loopT(Traversable $coll): void
|
||||
{
|
||||
foreach ($coll as $item) {}
|
||||
}
|
||||
|
||||
function loopI(IteratorAggregate $coll): void
|
||||
{
|
||||
foreach ($coll as $item) {}
|
||||
}
|
||||
|
||||
loopT(new C);
|
||||
loopI(new C);',
|
||||
'assignments' => [],
|
||||
'error_levels' => [
|
||||
'MixedAssignment', 'UndefinedThisPropertyAssignment',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
|
Loading…
Reference in New Issue
Block a user