Skip to content

Commit 98e63f8

Browse files
authored
[DeadCode] Skip RemoveDefaultValueFromAssignedPropertyRector on early return in constructor-called method (#8261)
1 parent 4229d89 commit 98e63f8

2 files changed

Lines changed: 67 additions & 1 deletion

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Rector\Tests\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector\Fixture;
4+
5+
final class SkipEarlyReturnInCalledMethod
6+
{
7+
private array $unknownLeadIds = [];
8+
9+
public function __construct(
10+
private readonly array $campaignMembers,
11+
) {
12+
$this->fetchLeads();
13+
}
14+
15+
private function fetchLeads(): void
16+
{
17+
if ($this->campaignMembers === []) {
18+
return;
19+
}
20+
21+
$this->unknownLeadIds = $this->campaignMembers;
22+
}
23+
}

‎rules/DeadCode/Rector/Property/RemoveDefaultValueFromAssignedPropertyRector.php‎

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
use PhpParser\Node\Expr;
99
use PhpParser\Node\Expr\ArrayDimFetch;
1010
use PhpParser\Node\Expr\Assign;
11+
use PhpParser\Node\Expr\MethodCall;
1112
use PhpParser\Node\Stmt\Class_;
1213
use PhpParser\Node\Stmt\ClassMethod;
14+
use PhpParser\Node\Stmt\Expression;
1315
use PhpParser\Node\Stmt\Return_;
1416
use Rector\Configuration\Parameter\FeatureFlags;
1517
use Rector\NodeAnalyzer\PropertyFetchAnalyzer;
@@ -85,7 +87,7 @@ public function refactor(Node $node): ?Node
8587
}
8688

8789
// early return can skip the assign, so the default value is still needed
88-
if ($this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped($constructClassMethod, Return_::class)) {
90+
if ($this->hasEarlyReturn($node, $constructClassMethod)) {
8991
return null;
9092
}
9193

@@ -138,6 +140,47 @@ public function refactor(Node $node): ?Node
138140
return null;
139141
}
140142

143+
/**
144+
* The constructor itself, or any local method it calls, can skip the assign with an early return
145+
*/
146+
private function hasEarlyReturn(Class_ $class, ClassMethod $constructClassMethod): bool
147+
{
148+
if ($this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped($constructClassMethod, Return_::class)) {
149+
return true;
150+
}
151+
152+
foreach ((array) $constructClassMethod->stmts as $stmt) {
153+
if (! $stmt instanceof Expression) {
154+
continue;
155+
}
156+
157+
if (! $stmt->expr instanceof MethodCall) {
158+
continue;
159+
}
160+
161+
$methodCall = $stmt->expr;
162+
if (! $this->isName($methodCall->var, 'this')) {
163+
continue;
164+
}
165+
166+
$methodName = $this->getName($methodCall->name);
167+
if ($methodName === null) {
168+
continue;
169+
}
170+
171+
$calledClassMethod = $class->getMethod($methodName);
172+
if (! $calledClassMethod instanceof ClassMethod) {
173+
continue;
174+
}
175+
176+
if ($this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped($calledClassMethod, Return_::class)) {
177+
return true;
178+
}
179+
}
180+
181+
return false;
182+
}
183+
141184
private function isAssignedViaArrayDimFetch(Class_ $class, string $propertyName): bool
142185
{
143186
return $this->betterNodeFinder->findFirst($class, function (Node $subNode) use ($propertyName): bool {

0 commit comments

Comments
 (0)