Skip to content

Commit

Permalink
Readonly properties cannot be invalidated
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jan 14, 2022
1 parent 44fd938 commit cbb7963
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/Analyser/MutatingScope.php
Expand Up @@ -3827,7 +3827,19 @@ public function invalidateExpression(Expr $expressionToInvalidate, bool $require
if (!$expr instanceof Node\Stmt\Expression) {
throw new ShouldNotHappenException();
}
$found = $nodeFinder->findFirst([$expr->expr], function (Node $node) use ($expressionToInvalidateClass, $exprStringToInvalidate): bool {

$exprExpr = $expr->expr;
if ($exprExpr instanceof PropertyFetch) {
$propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($exprExpr, $this);
if ($propertyReflection !== null) {
$nativePropertyReflection = $propertyReflection->getNativeReflection();
if ($nativePropertyReflection !== null && $nativePropertyReflection->isReadOnly()) {
continue;
}
}
}

$found = $nodeFinder->findFirst([$exprExpr], function (Node $node) use ($expressionToInvalidateClass, $exprStringToInvalidate): bool {
if (!$node instanceof $expressionToInvalidateClass) {
return false;
}
Expand Down
5 changes: 5 additions & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Expand Up @@ -602,6 +602,11 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-2806.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5328.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-3044.php');

if (PHP_VERSION_ID >= 80100) {
yield from $this->gatherAssertTypes(__DIR__ . '/data/invalidate-readonly-properties.php');
}

yield from $this->gatherAssertTypes(__DIR__ . '/data/weird-array_key_exists-issue.php');
}

Expand Down
31 changes: 31 additions & 0 deletions tests/PHPStan/Analyser/data/invalidate-readonly-properties.php
@@ -0,0 +1,31 @@
<?php // lint >= 8.1

namespace InvalidateReadonlyProperties;

use function PHPStan\Testing\assertType;

class Foo
{

private readonly int $foo;

public function __construct(int $foo)
{
$this->foo = $foo;
}

public function doFoo(): void
{
if ($this->foo === 1) {
assertType('1', $this->foo);
$this->doBar();
assertType('1', $this->foo);
}
}

public function doBar(): void
{

}

}

0 comments on commit cbb7963

Please sign in to comment.