Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CodeQuality] Skip Variable may be immutable via New_ or Clone_ on SimplifyUselessVariableRector #1060

Merged
merged 15 commits into from
Oct 26, 2021
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Rector\Tests\CodeQuality\Rector\Return_\SimplifyUselessVariableRector\Fixture;

use DateTimeImmutable;

final class SkipVariableUsedWithDateTimeImmutable
{
public function run()
{
$dateTime = new DateTimeImmutable();
$dateTime = $dateTime->setTime(14, 0, 0);

return $dateTime;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ private function shouldSkipExactlyReturnDateTime(ClassMethod $classMethod): bool
return false;
}

if (! $this->callAnalyzer->isNewInstance($this->betterNodeFinder, $return->expr)) {
if (! $this->callAnalyzer->isNewInstance($return->expr)) {
return false;
}

Expand Down
25 changes: 12 additions & 13 deletions rules/CodeQuality/Rector/Return_/SimplifyUselessVariableRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Type\MixedType;
use Rector\Core\NodeAnalyzer\CallAnalyzer;
use Rector\Core\NodeAnalyzer\VariableAnalyzer;
use Rector\Core\PhpParser\Node\AssignAndBinaryMap;
use Rector\Core\Rector\AbstractRector;
Expand All @@ -28,7 +29,8 @@ final class SimplifyUselessVariableRector extends AbstractRector
{
public function __construct(
private AssignAndBinaryMap $assignAndBinaryMap,
private VariableAnalyzer $variableAnalyzer
private VariableAnalyzer $variableAnalyzer,
private CallAnalyzer $callAnalyzer
) {
}

Expand Down Expand Up @@ -69,13 +71,10 @@ public function refactor(Node $node): ?Node
return null;
}

$previousNode = $node->getAttribute(AttributeKey::PREVIOUS_NODE);
if (! $previousNode instanceof Expression) {
return null;
}

/** @var AssignOp|Assign $previousNode */
$previousNode = $previousNode->expr;
/** @var Expression $previousExpression */
$previousExpression = $node->getAttribute(AttributeKey::PREVIOUS_NODE);
/** @var Assign|AssignOp $previousNode */
$previousNode = $previousExpression->expr;
$previousVariableNode = $previousNode->var;

if ($this->hasSomeComment($previousVariableNode)) {
Expand Down Expand Up @@ -131,10 +130,6 @@ private function shouldSkip(Return_ $return): bool
$variableNode = $return->expr;

$previousExpression = $return->getAttribute(AttributeKey::PREVIOUS_NODE);
if (! $previousExpression instanceof Node) {
return true;
}

if (! $previousExpression instanceof Expression) {
return true;
}
Expand All @@ -154,7 +149,11 @@ private function shouldSkip(Return_ $return): bool
return true;
}

return $this->variableAnalyzer->isStaticOrGlobal($variableNode);
if ($this->variableAnalyzer->isStaticOrGlobal($variableNode)) {
return true;
}

return $this->callAnalyzer->isNewInstance($previousNode->var);
}

private function hasSomeComment(Expr $expr): bool
Expand Down
16 changes: 11 additions & 5 deletions src/NodeAnalyzer/CallAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use PhpParser\Node\Stmt\If_;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Symfony\Contracts\Service\Attribute\Required;

final class CallAnalyzer
{
Expand All @@ -25,11 +26,19 @@ final class CallAnalyzer
*/
private const OBJECT_CALL_TYPES = [MethodCall::class, NullsafeMethodCall::class, StaticCall::class];

private BetterNodeFinder $betterNodeFinder;

public function __construct(
private NodeComparator $nodeComparator
) {
}

#[Required]
public function autowireCallAnalyzer(BetterNodeFinder $betterNodeFinder): void
{
$this->betterNodeFinder = $betterNodeFinder;
}

public function isObjectCall(Expr $expr): bool
{
if ($expr instanceof BooleanNot) {
Expand Down Expand Up @@ -66,16 +75,13 @@ public function doesIfHasObjectCall(array $ifs): bool
return false;
}

/**
* Inject BetterNodeFinder due Circular reference
*/
public function isNewInstance(BetterNodeFinder $betterNodeFinder, Expr $expr): bool
public function isNewInstance(Expr $expr): bool
{
if ($expr instanceof Clone_ || $expr instanceof New_) {
return true;
}

return (bool) $betterNodeFinder->findFirstPreviousOfNode($expr, function (Node $node) use ($expr): bool {
return (bool) $this->betterNodeFinder->findFirstPreviousOfNode($expr, function (Node $node) use ($expr): bool {
if (! $node instanceof Assign) {
return false;
}
Expand Down