Skip to content

Commit

Permalink
[DeadCode] Skip used on Closure use next stmt on RemoveUnusedVariable…
Browse files Browse the repository at this point in the history
…AssignRector (#4042)

* [DeadCode] Skip used on Closure use next stmt on RemoveUnusedVariableAssignRector

* Fix phpsatn

* cs fix
  • Loading branch information
samsonasik committed Jun 2, 2023
1 parent cfccdd0 commit 495900a
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor;

use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\AssignRef;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\Variable;
Expand Down Expand Up @@ -33,12 +34,7 @@ public function enterNode(Node $node): ?Node
}

$byRefVariableNames = $this->resolveClosureUseIsByRefAttribute($node, []);
foreach ($node->getParams() as $param) {
if ($param->byRef && $param->var instanceof Variable) {
$param->var->setAttribute(AttributeKey::IS_BYREF_VAR, true);
$byRefVariableNames[] = $param->var->name;
}
}
$byRefVariableNames = $this->resolveParamIsByRefAttribute($node, $byRefVariableNames);

$stmts = $node->getStmts();
if ($stmts === null) {
Expand All @@ -47,7 +43,12 @@ public function enterNode(Node $node): ?Node

$this->simpleCallableNodeTraverser->traverseNodesWithCallable(
$stmts,
static function (Node $subNode) use ($byRefVariableNames): null|Variable {
function (Node $subNode) use (&$byRefVariableNames): null|Variable {
if ($subNode instanceof Closure) {
$byRefVariableNames = $this->resolveClosureUseIsByRefAttribute($subNode, $byRefVariableNames);
return null;
}

if (! $subNode instanceof Variable) {
return null;
}
Expand All @@ -64,6 +65,22 @@ static function (Node $subNode) use ($byRefVariableNames): null|Variable {
return null;
}

/**
* @param string[] $byRefVariableNames
* @return string[]
*/
private function resolveParamIsByRefAttribute(FunctionLike $functionLike, array $byRefVariableNames): array
{
foreach ($functionLike->getParams() as $param) {
if ($param->byRef && $param->var instanceof Variable && ! $param->var->name instanceof Expr) {
$param->var->setAttribute(AttributeKey::IS_BYREF_VAR, true);
$byRefVariableNames[] = $param->var->name;
}
}

return $byRefVariableNames;
}

/**
* @param string[] $byRefVariableNames
* @return string[]
Expand All @@ -75,7 +92,7 @@ private function resolveClosureUseIsByRefAttribute(FunctionLike $functionLike, a
}

foreach ($functionLike->uses as $closureUse) {
if ($closureUse->byRef && is_string($closureUse->var->name)) {
if ($closureUse->byRef && ! $closureUse->var->name instanceof Expr) {
$closureUse->var->setAttribute(AttributeKey::IS_BYREF_VAR, true);
$byRefVariableNames[] = $closureUse->var->name;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Rector\Tests\DeadCode\Rector\Assign\RemoveUnusedVariableAssignRector\Fixture;

class SkipUsedOnClosureUse {
public function article(string $id): array
{
$johnSmith = null;
$article = static function (string $id) use (&$johnSmith): array {
return [
'author' => $johnSmith,
];
};

$johnSmith = [
'id' => 123,
'name' => 'John Smith',
'recentArticle' => $article('1'),
];

return $article($id);
}
}

0 comments on commit 495900a

Please sign in to comment.