1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 13:51:54 +01:00

flag impure calls made through __callstatic

This commit is contained in:
orklah 2021-10-24 09:55:40 +02:00
parent 307635fca5
commit a0681a4498
2 changed files with 57 additions and 0 deletions

View File

@ -17,6 +17,7 @@ use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Issue\DeprecatedClass;
use Psalm\Issue\ImpureMethodCall;
use Psalm\Issue\InternalClass;
use Psalm\Issue\InvalidStringClass;
use Psalm\Issue\MixedMethodCall;
@ -514,6 +515,40 @@ class AtomicStaticCallAnalyzer
return false;
}
if (!$context->inside_throw) {
if ($context->pure && !$pseudo_method_storage->pure) {
if (IssueBuffer::accepts(
new ImpureMethodCall(
'Cannot call an impure method from a pure context',
new CodeLocation($statements_analyzer, $stmt_name)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
} elseif ($context->mutation_free && !$pseudo_method_storage->mutation_free) {
if (IssueBuffer::accepts(
new ImpureMethodCall(
'Cannot call a possibly-mutating method from a mutation-free context',
new CodeLocation($statements_analyzer, $stmt_name)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
} elseif ($statements_analyzer->getSource()
instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer
&& $statements_analyzer->getSource()->track_mutations
&& !$pseudo_method_storage->pure
) {
if (!$pseudo_method_storage->mutation_free) {
$statements_analyzer->getSource()->inferred_has_mutation = true;
}
$statements_analyzer->getSource()->inferred_impure = true;
}
}
if ($pseudo_method_storage->return_type) {
return true;
}

View File

@ -804,6 +804,28 @@ class PureAnnotationTest extends TestCase
}',
'error_message' => 'ImpureMethodCall',
],
'impureThroughCallStatic' => [
'<?php
/**
* @method static void test()
*/
final class Impure
{
public static function __callStatic(string $name, array $arguments)
{
}
}
/**
* @psalm-pure
*/
function testImpure(): void
{
Impure::test();
}
',
'error_message' => 'ImpureMethodCall',
],
];
}
}