Skip to content

Commit

Permalink
Merge pull request #6953 from orklah/callstatic-pure
Browse files Browse the repository at this point in the history
check __callStatic purity instead of the pseudoMethod purity
  • Loading branch information
orklah committed Nov 21, 2021
2 parents 912079e + 3e56e85 commit 79fa7f5
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
Expand Up @@ -34,6 +34,7 @@

use function array_filter;
use function array_map;
use function assert;
use function count;
use function in_array;
use function strtolower;
Expand Down Expand Up @@ -469,6 +470,9 @@ private static function handleNamedCall(
true,
$context->insideUse()
)) {
$callstatic_appearing_id = $codebase->methods->getAppearingMethodId($callstatic_id);
assert($callstatic_appearing_id !== null);
$callstatic_storage = $codebase->methods->getStorage($callstatic_appearing_id);
if ($codebase->methods->return_type_provider->has($fq_class_name)) {
$return_type_candidate = $codebase->methods->return_type_provider->getReturnType(
$statements_analyzer,
Expand Down Expand Up @@ -516,7 +520,7 @@ private static function handleNamedCall(
}

if (!$context->inside_throw) {
if ($context->pure && !$pseudo_method_storage->pure) {
if ($context->pure && !$callstatic_storage->pure) {
if (IssueBuffer::accepts(
new ImpureMethodCall(
'Cannot call an impure method from a pure context',
Expand All @@ -526,7 +530,7 @@ private static function handleNamedCall(
)) {
// fall through
}
} elseif ($context->mutation_free && !$pseudo_method_storage->mutation_free) {
} elseif ($context->mutation_free&& !$callstatic_storage->mutation_free) {
if (IssueBuffer::accepts(
new ImpureMethodCall(
'Cannot call a possibly-mutating method from a mutation-free context',
Expand All @@ -539,9 +543,9 @@ private static function handleNamedCall(
} elseif ($statements_analyzer->getSource()
instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer
&& $statements_analyzer->getSource()->track_mutations
&& !$pseudo_method_storage->pure
&& !$callstatic_storage->pure
) {
if (!$pseudo_method_storage->mutation_free) {
if (!$callstatic_storage->mutation_free) {
$statements_analyzer->getSource()->inferred_has_mutation = true;
}

Expand Down
29 changes: 29 additions & 0 deletions tests/PureAnnotationTest.php
Expand Up @@ -413,6 +413,35 @@ private function isValidPort(int $portNumber): bool {
}
}'
],
'pureThroughCallStatic' => [
'<?php
/**
* @method static self FOO()
* @method static static BAR()
* @method static static BAZ()
*
* @psalm-immutable
*/
class MyEnum
{
const FOO = "foo";
const BAR = "bar";
const BAZ = "baz";
/** @psalm-pure */
public static function __callStatic(string $name, array $params): static
{
throw new BadMethodCallException("not implemented");
}
}
/** @psalm-pure */
function gimmeFoo(): MyEnum
{
return MyEnum::FOO();
}',
],
];
}

Expand Down

0 comments on commit 79fa7f5

Please sign in to comment.