Skip to content

Commit

Permalink
Assignment to property in closure is an impure point
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Apr 18, 2024
1 parent 94a0b86 commit 7045457
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 4 deletions.
17 changes: 15 additions & 2 deletions src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
use PHPStan\Node\InvalidateExprNode;
use PHPStan\Node\IssetExpr;
use PHPStan\Node\Printer\ExprPrinter;
use PHPStan\Node\PropertyAssignNode;
use PHPStan\Parser\ArrayMapArgVisitor;
use PHPStan\Parser\NewAssignedToPropertyVisitor;
use PHPStan\Parser\Parser;
Expand Down Expand Up @@ -1287,8 +1288,9 @@ static function (): void {
$closureReturnStatements = [];
$closureYieldStatements = [];
$closureExecutionEnds = [];
$closureImpurePoints = [];
$invalidateExpressions = [];
$closureStatementResult = $this->nodeScopeResolver->processStmtNodes($node, $node->stmts, $closureScope, static function (Node $node, Scope $scope) use ($closureScope, &$closureReturnStatements, &$closureYieldStatements, &$closureExecutionEnds, &$invalidateExpressions): void {
$closureStatementResult = $this->nodeScopeResolver->processStmtNodes($node, $node->stmts, $closureScope, static function (Node $node, Scope $scope) use ($closureScope, &$closureReturnStatements, &$closureYieldStatements, &$closureExecutionEnds, &$closureImpurePoints, &$invalidateExpressions): void {
if ($scope->getAnonymousFunctionReflection() !== $closureScope->getAnonymousFunctionReflection()) {
return;
}
Expand All @@ -1298,6 +1300,17 @@ static function (): void {
return;
}

if ($node instanceof PropertyAssignNode) {
$closureImpurePoints[] = new ImpurePoint(
$scope,
$node,
'propertyAssign',
'property assignment',
true,
);
return;
}

if ($node instanceof ExecutionEndNode) {
if ($node->getStatementResult()->isAlwaysTerminating()) {
foreach ($node->getStatementResult()->getExitPoints() as $exitPoint) {
Expand Down Expand Up @@ -1329,7 +1342,7 @@ static function (): void {
}, StatementContext::createTopLevel());

$throwPoints = $closureStatementResult->getThrowPoints();
$impurePoints = $closureStatementResult->getImpurePoints();
$impurePoints = array_merge($closureImpurePoints, $closureStatementResult->getImpurePoints());

$returnTypes = [];
$hasNull = false;
Expand Down
4 changes: 2 additions & 2 deletions tests/PHPStan/Rules/DeadCode/BetterNoopRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,11 @@ public function testRuleImpurePoints(): void
$this->analyse([__DIR__ . '/data/noop-impure-points.php'], [
[
'Unused result of "&&" operator.',
10,
12,
],
[
'Expression "$b()" on a separate line does not do anything.',
57,
59,
],
]);
}
Expand Down
12 changes: 12 additions & 0 deletions tests/PHPStan/Rules/DeadCode/data/noop-impure-points.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
class Foo
{

private static $staticProp = 1;

public function doFoo(bool $b): void
{
$b && $this->doBar();
Expand Down Expand Up @@ -61,6 +63,16 @@ public function doClosures(): void
$ref++;
};
$c();

$d = function () {
self::$foo = 1;
};
$d();

$e = function () {
self::$staticProp = 1;
};
$e();
}

}

0 comments on commit 7045457

Please sign in to comment.