Skip to content

Commit 1e35303

Browse files
committed
fix checks for phpstan/phpstan#8929
of course just checking for ArrayAccess isn't enough - it's only valid for index assignment operations 🤦
1 parent a7e289f commit 1e35303

File tree

3 files changed

+16
-3
lines changed

3 files changed

+16
-3
lines changed

src/Rules/Properties/ReadOnlyPropertyAssignRule.php

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
use ArrayAccess;
66
use PhpParser\Node;
77
use PHPStan\Analyser\Scope;
8+
use PHPStan\Node\Expr\SetOffsetValueTypeExpr;
9+
use PHPStan\Node\Expr\UnsetOffsetExpr;
810
use PHPStan\Node\PropertyAssignNode;
911
use PHPStan\Reflection\ConstructorsHelper;
1012
use PHPStan\Reflection\MethodReflection;
@@ -91,7 +93,11 @@ public function processNode(Node $node, Scope $scope): array
9193
continue;
9294
}
9395

94-
if ((new ObjectType(ArrayAccess::class))->isSuperTypeOf($propertyReflection->getNativeType())->yes()) {
96+
$expr = $node->getAssignedExpr();
97+
if (
98+
(new ObjectType(ArrayAccess::class))->isSuperTypeOf($propertyReflection->getNativeType())->yes()
99+
&& (($expr instanceof SetOffsetValueTypeExpr) || ($expr instanceof UnsetOffsetExpr))
100+
) {
95101
continue;
96102
}
97103

tests/PHPStan/Rules/Properties/ReadOnlyPropertyAssignRuleTest.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,12 @@ public function testBug8929(): void
174174
self::markTestSkipped('Test requires PHP 8.1');
175175
}
176176

177-
$this->analyse([__DIR__ . '/data/bug-8929.php'], []);
177+
$this->analyse([__DIR__ . '/data/bug-8929.php'], [
178+
[
179+
'Readonly property Bug8929\Test::$cache is assigned outside of the constructor.',
180+
19,
181+
],
182+
]);
178183
}
179184

180185
}

tests/PHPStan/Rules/Properties/data/bug-8929.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public function __construct()
1414

1515
public function add(object $key, mixed $value): void
1616
{
17-
$this->cache[$key] = $value;
17+
$this->cache[$key] = $value; // valid offset access
18+
unset($this->cache[$key]); // valid offset access
19+
$this->cache = new \WeakMap(); // reassigning is invalid however
1820
}
1921
}

0 commit comments

Comments
 (0)