Skip to content

Commit

Permalink
TypeSpecifier - observe hasSideEffects() for static methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed May 27, 2022
1 parent f22c92d commit 1182199
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/Analyser/TypeSpecifier.php
Expand Up @@ -1204,6 +1204,28 @@ public function create(
}
}

if (
$expr instanceof StaticCall
&& $expr->name instanceof Node\Identifier
&& $scope !== null
) {
$methodName = $expr->name->toString();
if ($expr->class instanceof Name) {
$calledOnType = $scope->resolveTypeByName($expr->class);
} else {
$calledOnType = $scope->getType($expr->class);
}

$methodReflection = $scope->getMethodReflection($calledOnType, $methodName);
if ($methodReflection === null || $methodReflection->hasSideEffects()->yes()) {
if (isset($resultType) && !TypeCombinator::containsNull($resultType)) {
return $this->createNullsafeTypes($rootExpr, $originalExpr, $scope, $context, $overwrite, $type);
}

return new SpecifiedTypes([], [], false, [], $rootExpr);
}
}

$sureTypes = [];
$sureNotTypes = [];
$exprString = $this->printer->prettyPrintExpr($expr);
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Expand Up @@ -894,6 +894,7 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/non-empty-string-substr-specifying.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/unset-conditional-expressions.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/conditional-types-inference.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7210.php');
}

/**
Expand Down
34 changes: 34 additions & 0 deletions tests/PHPStan/Analyser/data/bug-7210.php
@@ -0,0 +1,34 @@
<?php

namespace Bug7210;

use function PHPStan\Testing\assertType;

class HelloWorld {
public function doStuff(): void {
if (self::getBool()) {
return;
}

assertType('bool', self::getBool());
}

/** @phpstan-impure */
private static function getBool(): bool {
return mt_rand(0, 1) === 0;
}
}

class HelloWorld2 {
public function doStuff(): void {
if (self::getBool()) {
return;
}

assertType('false', self::getBool());
}

private static function getBool(): bool {
return mt_rand(0, 1) === 0;
}
}

0 comments on commit 1182199

Please sign in to comment.