Skip to content

Commit c11d602

Browse files
phpstan-botclaude
andcommitted
Broaden write-only property check to cover union types and non-ArrayAccess objects
- Simplify condition to `!$propertyType->isObject()->no()` so that any type that *might* be an object triggers a PropertyRead when appending via `[]` - Add test cases for Threaded (non-ArrayAccess object), ArrayObject|array union, and ArrayObject|string union Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 41cf381 commit c11d602

2 files changed

Lines changed: 50 additions & 4 deletions

File tree

src/Node/ClassStatementsGatherer.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,7 @@ private function gatherNodes(Node $node, Scope $scope): void
206206
$assignedExpr = $node->getAssignedExpr();
207207
if ($assignedExpr instanceof SetOffsetValueTypeExpr || $assignedExpr instanceof SetExistingOffsetValueTypeExpr) {
208208
$propertyType = $scope->getType($propertyFetch);
209-
if (
210-
!$propertyType->isArray()->yes()
211-
&& $propertyType->isObject()->yes()
212-
) {
209+
if (!$propertyType->isObject()->no()) {
213210
$this->propertyUsages[] = new PropertyRead($propertyFetch, $scope);
214211
}
215212
}

tests/PHPStan/Rules/DeadCode/data/bug-6777.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,52 @@ public function send(string $s) : void{
1313
$this->array[] = $s;
1414
}
1515
}
16+
17+
class WithThreaded
18+
{
19+
private \Threaded $collection;
20+
21+
public function __construct()
22+
{
23+
$this->collection = new \Threaded();
24+
}
25+
26+
public function add(string $s): void
27+
{
28+
$this->collection[] = $s;
29+
}
30+
}
31+
32+
class WithUnionObjectArray
33+
{
34+
/** @var \ArrayObject<int, string>|array<int, string> */
35+
private \ArrayObject|array $collection;
36+
37+
/** @param \ArrayObject<int, string>|array<int, string> $collection */
38+
public function __construct(\ArrayObject|array $collection)
39+
{
40+
$this->collection = $collection;
41+
}
42+
43+
public function add(string $s): void
44+
{
45+
$this->collection[] = $s;
46+
}
47+
}
48+
49+
class WithUnionObjectString
50+
{
51+
/** @var \ArrayObject<int, string>|string */
52+
private \ArrayObject|string $collection;
53+
54+
/** @param \ArrayObject<int, string>|string $collection */
55+
public function __construct(\ArrayObject|string $collection)
56+
{
57+
$this->collection = $collection;
58+
}
59+
60+
public function add(string $s): void
61+
{
62+
$this->collection[] = $s;
63+
}
64+
}

0 commit comments

Comments
 (0)