mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 04:45:20 +01:00
Fix #4052 - foreach over an iterable is impure
This commit is contained in:
parent
3f50fbc116
commit
2b060b75d3
@ -16,6 +16,7 @@ use Psalm\Internal\FileManipulation\FileManipulationBuffer;
|
||||
use Psalm\CodeLocation;
|
||||
use Psalm\Context;
|
||||
use Psalm\Exception\DocblockParseException;
|
||||
use Psalm\Issue\ImpureMethodCall;
|
||||
use Psalm\Issue\InvalidDocblock;
|
||||
use Psalm\Issue\InvalidIterator;
|
||||
use Psalm\Issue\NullIterator;
|
||||
@ -563,6 +564,30 @@ class ForeachAnalyzer
|
||||
}
|
||||
|
||||
$has_valid_iterator = true;
|
||||
|
||||
if (!$context->pure) {
|
||||
$project_analyzer = $statements_analyzer->getProjectAnalyzer();
|
||||
|
||||
if ($codebase->alter_code
|
||||
&& (isset($project_analyzer->getIssuesToFix()['MissingPureAnnotation'])
|
||||
|| isset($project_analyzer->getIssuesToFix()['MissingImmutableAnnotation']))
|
||||
&& $statements_analyzer->getSource()
|
||||
instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer
|
||||
) {
|
||||
$statements_analyzer->getSource()->inferred_has_mutation = true;
|
||||
$statements_analyzer->getSource()->inferred_impure = true;
|
||||
}
|
||||
} else {
|
||||
if (IssueBuffer::accepts(
|
||||
new ImpureMethodCall(
|
||||
'Cannot call a possibly-mutating Traversable::getIterator from a pure context',
|
||||
new CodeLocation($statements_analyzer, $stmt)
|
||||
),
|
||||
$statements_analyzer->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
} elseif ($iterator_atomic_type instanceof Type\Atomic\TNamedObject) {
|
||||
if ($iterator_atomic_type->value !== 'Traversable' &&
|
||||
$iterator_atomic_type->value !== $statements_analyzer->getClassName()
|
||||
|
@ -732,6 +732,25 @@ class PureAnnotationTest extends TestCase
|
||||
}',
|
||||
'error_message' => 'ImpureVariable',
|
||||
],
|
||||
'iterableIsNotPure' => [
|
||||
'<?php
|
||||
namespace Test;
|
||||
|
||||
/**
|
||||
* @param iterable<string> $pieces
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
function foo(iterable $pieces): string
|
||||
{
|
||||
foreach ($pieces as $piece) {
|
||||
return $piece;
|
||||
}
|
||||
|
||||
return "jello";
|
||||
}',
|
||||
'error_message' => 'ImpureMethodCall',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user