Skip to content

Commit

Permalink
Keep called method in RemoveEmptyClassMethodRector (#5425)
Browse files Browse the repository at this point in the history
* Create keep_used_method.php.inc #8382

Rector should not remove empty private methods that are called from somewhere

* Keep called method in RemoveEmptyClassMethodRector

---------

Co-authored-by: noother <noothy@gmail.com>
  • Loading branch information
TomasVotruba and noother committed Jan 2, 2024
1 parent 8724fee commit 9144efc
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
@@ -0,0 +1,13 @@
<?php

namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector\Fixture;

final class KeepUsedMethod {
public function bar()
{
$this->gaz();
}

private function gaz() {
}
}
38 changes: 38 additions & 0 deletions rules/DeadCode/Rector/ClassMethod/RemoveEmptyClassMethodRector.php
Expand Up @@ -5,6 +5,8 @@
namespace Rector\DeadCode\Rector\ClassMethod;

use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
Expand All @@ -14,6 +16,7 @@
use Rector\DeadCode\NodeManipulator\ControllerClassMethodManipulator;
use Rector\NodeAnalyzer\ParamAnalyzer;
use Rector\NodeManipulator\ClassMethodManipulator;
use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\Rector\AbstractRector;
use Rector\ValueObject\MethodName;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
Expand All @@ -29,6 +32,7 @@ public function __construct(
private readonly ControllerClassMethodManipulator $controllerClassMethodManipulator,
private readonly ParamAnalyzer $paramAnalyzer,
private readonly PhpDocInfoFactory $phpDocInfoFactory,
private readonly BetterNodeFinder $betterNodeFinder
) {
}

Expand Down Expand Up @@ -127,6 +131,19 @@ private function shouldSkipNonFinalNonPrivateClassMethod(Class_ $class, ClassMet

private function shouldSkipClassMethod(Class_ $class, ClassMethod $classMethod): bool
{
$desiredClassMethodName = $this->getName($classMethod);

// is method called somewhere else in the class?
foreach ($class->getMethods() as $anotherClassMethod) {
if ($anotherClassMethod === $classMethod) {
continue;
}

if ($this->containsMethodCall($anotherClassMethod, $desiredClassMethodName)) {
return true;
}
}

if ($this->classMethodManipulator->isNamedConstructor($classMethod)) {
return true;
}
Expand Down Expand Up @@ -164,4 +181,25 @@ private function hasDeprecatedAnnotation(ClassMethod $classMethod): bool

return $phpDocInfo->hasByType(DeprecatedTagValueNode::class);
}

private function containsMethodCall(ClassMethod $anotherClassMethod, string $desiredClassMethodName): bool
{
return (bool) $this->betterNodeFinder->findFirst($anotherClassMethod, function (Node $node) use (
$desiredClassMethodName
): bool {
if (! $node instanceof MethodCall) {
return false;
}

if (! $node->var instanceof Variable) {
return false;
}

if (! $this->isName($node->var, 'this')) {
return false;
}

return $this->isName($node->name, $desiredClassMethodName);
});
}
}

0 comments on commit 9144efc

Please sign in to comment.