Skip to content

Commit

Permalink
Remove PARENT_NODE from RemoveEmptyMethodCallRector (#3932)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba authored May 22, 2023
1 parent 4793a0d commit 6e88b21
Showing 1 changed file with 65 additions and 31 deletions.
96 changes: 65 additions & 31 deletions rules/DeadCode/Rector/MethodCall/RemoveEmptyMethodCallRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
use Rector\Core\PhpParser\AstResolver;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

Expand Down Expand Up @@ -75,51 +74,33 @@ public function callThis()
*/
public function getNodeTypes(): array
{
return [MethodCall::class];
return [Expression::class, If_::class, Assign::class];
}

/**
* @param MethodCall $node
* @param Expression|If_|Assign $node
*/
public function refactorWithScope(Node $node, Scope $scope): ?Node
public function refactorWithScope(Node $node, Scope $scope)
{
if ($this->shouldSkip($node)) {
return null;
}

$type = $scope->getType($node->var);
if (! $type instanceof TypeWithClassName) {
return null;
if ($node instanceof If_) {
return $this->refactorIf($node, $scope);
}

$classLike = $this->resolveClassLike($node);

if (! $classLike instanceof ClassLike) {
if ($node instanceof Expression) {
$this->refactorExpression($node, $scope);
return null;
}

/** @var Class_|Trait_|Interface_|Enum_ $classLike */
if ($this->shouldSkipClassMethod($classLike, $node, $type)) {
if (! $node->expr instanceof MethodCall) {
return null;
}

// if->cond cannot removed, it has to be replaced with false, see https://3v4l.org/U9S9i
$parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
if ($parentNode instanceof If_ && $parentNode->cond === $node) {
return $this->nodeFactory->createFalse();
}

if ($parentNode instanceof Assign) {
return $this->nodeFactory->createFalse();
}

if (! $parentNode instanceof Expression) {
if (! $this->shouldRemoveMethodCall($node->expr, $scope)) {
return null;
}

$this->removeNode($node);

return null;
$node->expr = $this->nodeFactory->createFalse();
return $node;
}

private function resolveClassLike(MethodCall $methodCall): ?ClassLike
Expand All @@ -133,7 +114,7 @@ private function resolveClassLike(MethodCall $methodCall): ?ClassLike
return $this->reflectionAstResolver->resolveClassFromName($classReflection->getName());
}

private function shouldSkip(MethodCall $methodCall): bool
private function shouldSkipMethodCall(MethodCall $methodCall): bool
{
if ($this->callAnalyzer->isObjectCall($methodCall->var)) {
return true;
Expand Down Expand Up @@ -185,4 +166,57 @@ private function shouldSkipClassMethod(

return ! $classMethod->isPrivate();
}

private function shouldRemoveMethodCall(MethodCall $methodCall, Scope $scope): bool
{
if ($this->shouldSkipMethodCall($methodCall)) {
return false;
}

$type = $scope->getType($methodCall->var);
if (! $type instanceof TypeWithClassName) {
return false;
}

$classLike = $this->resolveClassLike($methodCall);
if (! $classLike instanceof ClassLike) {
return false;
}

/** @var Class_|Trait_|Interface_|Enum_ $classLike */
return ! $this->shouldSkipClassMethod($classLike, $methodCall, $type);
}

/**
* If->cond cannot removed,
* it has to be replaced with false, see https://3v4l.org/U9S9i
*/
private function refactorIf(If_ $if, Scope $scope): ?If_
{
if (! $if->cond instanceof MethodCall) {
return null;
}

if (! $this->shouldRemoveMethodCall($if->cond, $scope)) {
return null;
}

$if->cond = $this->nodeFactory->createFalse();

return $if;
}

private function refactorExpression(Expression $expression, Scope $scope): void
{
if (! $expression->expr instanceof MethodCall) {
return;
}

$methodCall = $expression->expr;
if (! $this->shouldRemoveMethodCall($methodCall, $scope)) {
return;
}

$this->removeNode($expression);
}
}

0 comments on commit 6e88b21

Please sign in to comment.