Skip to content

Commit 9a76de9

Browse files
authored
[DeadCode] Skip used by use by ref closure on assign on RemoveUnusedVariableAssignRector (#7398)
1 parent 69197d1 commit 9a76de9

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Rector\Tests\DeadCode\Rector\Assign\RemoveUnusedVariableAssignRector\Fixture;
4+
5+
function skipUsedByUseByRefClosure(Throwable $signalingException)
6+
{
7+
$prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$prevErrorHandler, $signalingException) {
8+
if ($file === __FILE__) {
9+
throw $signalingException;
10+
}
11+
12+
return $prevErrorHandler !== null ? $prevErrorHandler($type, $msg, $file, $line, $context) : false;
13+
});
14+
}
15+
16+
?>

rules/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99
use PhpParser\Node\Expr\Assign;
1010
use PhpParser\Node\Expr\AssignRef;
1111
use PhpParser\Node\Expr\Cast;
12+
use PhpParser\Node\Expr\Closure;
1213
use PhpParser\Node\Expr\FuncCall;
1314
use PhpParser\Node\Expr\Include_;
1415
use PhpParser\Node\Expr\Variable;
1516
use PhpParser\Node\Stmt;
17+
use PhpParser\Node\Stmt\Class_;
1618
use PhpParser\Node\Stmt\ClassMethod;
1719
use PhpParser\Node\Stmt\Expression;
1820
use PhpParser\Node\Stmt\Function_;
21+
use PhpParser\NodeVisitor;
1922
use Rector\DeadCode\SideEffect\SideEffectNodeDetector;
2023
use Rector\NodeAnalyzer\VariableAnalyzer;
2124
use Rector\NodeManipulator\StmtsManipulator;
@@ -180,6 +183,31 @@ private function resolvedAssignedVariablesByStmtPosition(array $stmts): array
180183
continue;
181184
}
182185

186+
$this->traverseNodesWithCallable(
187+
$stmt->expr->expr,
188+
function (Node $subNode) use (&$refVariableNames) {
189+
if ($subNode instanceof Class_ || $subNode instanceof Function_) {
190+
return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
191+
}
192+
193+
if (! $subNode instanceof Closure) {
194+
return null;
195+
}
196+
197+
foreach ($subNode->uses as $closureUse) {
198+
if (! $closureUse->var instanceof Variable) {
199+
continue;
200+
}
201+
202+
if (! $closureUse->byRef) {
203+
continue;
204+
}
205+
206+
$refVariableNames[] = (string) $this->getName($closureUse->var);
207+
}
208+
}
209+
);
210+
183211
$assign = $stmt->expr;
184212
if (! $assign->var instanceof Variable) {
185213
continue;

0 commit comments

Comments
 (0)