[DeadCode] Fix variable usage detection

This commit is contained in:
dobryy 2020-07-22 18:43:23 +02:00
parent d007ae0896
commit 4a025c7a2b
7 changed files with 93 additions and 7 deletions

View File

@ -7,8 +7,6 @@ use Rector\PHPUnit\Rector\MethodCall\RemoveExpectAnyFromMockRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
# [configurable]
# Rector\PHPUnit\Rector\Class_\ArrayArgumentInTestToDataProviderRector: null
$services = $containerConfigurator->services();
$services->set(RemoveExpectAnyFromMockRector::class);

View File

@ -6,9 +6,12 @@ namespace Rector\DeadCode\NodeFinder;
use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Variable;
use PhpParser\NodeTraverser;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeNestingScope\ParentScopeFinder;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -29,14 +32,28 @@ final class NextVariableUsageNodeFinder
*/
private $parentScopeFinder;
/**
* @var BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;
public function __construct(
ParentScopeFinder $parentScopeFinder,
CallableNodeTraverser $callableNodeTraverser,
BetterStandardPrinter $betterStandardPrinter
BetterStandardPrinter $betterStandardPrinter,
BetterNodeFinder $betterNodeFinder,
NodeNameResolver $nodeNameResolver
) {
$this->callableNodeTraverser = $callableNodeTraverser;
$this->betterStandardPrinter = $betterStandardPrinter;
$this->parentScopeFinder = $parentScopeFinder;
$this->betterNodeFinder = $betterNodeFinder;
$this->nodeNameResolver = $nodeNameResolver;
}
public function find(Assign $assign): ?Node
@ -46,8 +63,8 @@ final class NextVariableUsageNodeFinder
return null;
}
/** @var Variable $expr */
$expr = $assign->var;
$this->callableNodeTraverser->traverseNodesWithCallable((array) $scopeNode->stmts, function (Node $currentNode) use (
$expr,
&$nextUsageOfVariable
@ -68,8 +85,7 @@ final class NextVariableUsageNodeFinder
$currentNodeParent = $currentNode->getAttribute(AttributeKey::PARENT_NODE);
// stop at next assign
if ($currentNodeParent instanceof Assign) {
if ($currentNodeParent instanceof Assign && ! $this->hasInParentExpression($currentNodeParent, $expr)) {
return NodeTraverser::STOP_TRAVERSAL;
}
@ -80,4 +96,14 @@ final class NextVariableUsageNodeFinder
return $nextUsageOfVariable;
}
private function hasInParentExpression(Assign $assign, Variable $variable): bool
{
$name = $this->nodeNameResolver->getName($variable);
if ($name === null) {
return false;
}
return $this->betterNodeFinder->hasVariableOfName($assign->expr, $name);
}
}

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Rector\DeadCode\Tests\Rector\Assign\RemoveUnusedAssignVariableRector\Fixture;
final class SkipAssignExpressionClassUseVariable
{
public function run()
{
$datetime = time();
$datetime = new \DateTime($datetime);
return $datetime;
}
}

View File

@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace Rector\DeadCode\Tests\Rector\Assign\RemoveUnusedAssignVariableRector\Fixture;
final class SkipAssignExpressionClosureUseVariable
{
public function run()
{
$content = [1, 2, 3];
$filtered = array_filter([1, 2, 3], function ($v) use ($content) {
return $content !== $v;
});
return $filtered;
}
}

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Rector\DeadCode\Tests\Rector\Assign\RemoveUnusedAssignVariableRector\Fixture;
final class SkipAssignExpressionUseValue
{
public function run()
{
$content = 1;
$content = $content + 1;
return $content;
}
}

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Rector\DeadCode\Tests\Rector\Assign\RemoveUnusedAssignVariableRector\Fixture;
final class SkipAssignExpressionUseVariableAsFunctionParam
{
public function run()
{
$content = [1, 2, 3];
$content = array_push($content, 1);
return $content;
}
}

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Rector\Core\PhpParser\Node;
use PhpParser\Node;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
@ -12,7 +13,6 @@ use PhpParser\Node\Stmt\Expression;
use PhpParser\NodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symfony\Component\DependencyInjection\Variable;
/**
* @see \Rector\Core\Tests\PhpParser\Node\BetterNodeFinder\BetterNodeFinderTest