1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Fix #1249 - allow iterator_to_array to respect getIterator method

This commit is contained in:
Matthew Brown 2019-01-27 14:50:05 -05:00
parent 60e7587c2d
commit cd4d2027d0
2 changed files with 34 additions and 17 deletions

View File

@ -322,19 +322,23 @@ class FunctionAnalyzer extends FunctionLikeAnalyzer
$codebase = $statements_analyzer->getCodebase();
foreach ($call_args[0]->value->inferredType->getTypes() as $call_arg_atomic_type) {
if ($call_arg_atomic_type instanceof Type\Atomic\TIterable
|| ($call_arg_atomic_type instanceof Type\Atomic\TGenericObject
&& (strtolower($call_arg_atomic_type->value) === 'traversable'
|| $codebase->classImplements(
$call_arg_atomic_type->value,
'Traversable'
)))
) {
ForeachAnalyzer::getKeyValueParamsForTraversableObject(
$call_arg_atomic_type,
if ($call_arg_atomic_type instanceof Type\Atomic\TNamedObject
&& TypeAnalyzer::isAtomicContainedBy(
$codebase,
$call_arg_atomic_type,
new Type\Atomic\TIterable([Type::getMixed(), Type::getMixed()])
)
) {
$has_valid_iterator = true;
ForeachAnalyzer::handleIterable(
$statements_analyzer,
$call_arg_atomic_type,
$call_args[0]->value,
$codebase,
$context,
$key_type,
$value_type
$value_type,
$has_valid_iterator
);
}
}

View File

@ -894,12 +894,25 @@ class FunctionCallTest extends TestCase
yield new stdClass;
}
/**
* @return array<stdClass>
*/
function foo(callable $filter): array {
return array_filter(iterator_to_array(generator()), $filter);
}'
$a = iterator_to_array(generator());',
'assertions' => [
'$a' => 'array<mixed, stdClass>',
],
],
'iteratorToArrayWithGetIterator' => [
'<?php
class C implements IteratorAggregate {
/**
* @return Traversable<int,string>
*/
public function getIterator() {
yield 1 => "1";
}
}
$a = iterator_to_array(new C);',
'assertions' => [
'$a' => 'array<int, string>',
],
],
'arrayColumnInference' => [
'<?php