diff --git a/packages/DeadCode/src/Rector/ClassMethod/RemoveUnusedPrivateMethodRector.php b/packages/DeadCode/src/Rector/ClassMethod/RemoveUnusedPrivateMethodRector.php index 699f7c9f081..a0f40ce3eed 100644 --- a/packages/DeadCode/src/Rector/ClassMethod/RemoveUnusedPrivateMethodRector.php +++ b/packages/DeadCode/src/Rector/ClassMethod/RemoveUnusedPrivateMethodRector.php @@ -4,7 +4,7 @@ namespace Rector\DeadCode\Rector\ClassMethod; use PhpParser\Node; use PhpParser\Node\Stmt\ClassMethod; -use Rector\PhpParser\Node\Manipulator\ClassMethodManipulator; +use Rector\NodeContainer\ParsedNodesByType; use Rector\Rector\AbstractRector; use Rector\RectorDefinition\CodeSample; use Rector\RectorDefinition\RectorDefinition; @@ -12,13 +12,13 @@ use Rector\RectorDefinition\RectorDefinition; final class RemoveUnusedPrivateMethodRector extends AbstractRector { /** - * @var ClassMethodManipulator + * @var ParsedNodesByType */ - private $classMethodManipulator; + private $parsedNodesByType; - public function __construct(ClassMethodManipulator $classMethodManipulator) + public function __construct(ParsedNodesByType $parsedNodesByType) { - $this->classMethodManipulator = $classMethodManipulator; + $this->parsedNodesByType = $parsedNodesByType; } public function getDefinition(): RectorDefinition @@ -74,7 +74,7 @@ CODE_SAMPLE return null; } - $classMethodCalls = $this->classMethodManipulator->getAllClassMethodCall($node); + $classMethodCalls = $this->parsedNodesByType->findClassMethodCalls($node); if ($classMethodCalls === []) { $this->removeNode($node); } diff --git a/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/Fixture/skip_local_called.php.inc b/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/Fixture/skip_local_called.php.inc new file mode 100644 index 00000000000..bf7a917775b --- /dev/null +++ b/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/Fixture/skip_local_called.php.inc @@ -0,0 +1,19 @@ +setId($id); + return $customer; + } + private function setId($id){ + $this->id=$id; + } +} diff --git a/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/RemoveUnusedPrivateMethodRectorTest.php b/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/RemoveUnusedPrivateMethodRectorTest.php index ee1619173c5..bc5150855af 100644 --- a/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/RemoveUnusedPrivateMethodRectorTest.php +++ b/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/RemoveUnusedPrivateMethodRectorTest.php @@ -12,8 +12,10 @@ final class RemoveUnusedPrivateMethodRectorTest extends AbstractRectorTestCase $this->doTestFiles([ __DIR__ . '/Fixture/fixture.php.inc', __DIR__ . '/Fixture/static_method.php.inc', - __DIR__ . '/Fixture/keep_anonymous.php.inc', __DIR__ . '/Fixture/private_constructor.php.inc', + // skip + __DIR__ . '/Fixture/keep_anonymous.php.inc', + __DIR__ . '/Fixture/skip_local_called.php.inc', ]); } diff --git a/src/NodeContainer/ParsedNodesByType.php b/src/NodeContainer/ParsedNodesByType.php index 0a3f9c1e0f5..55ecb2bb96a 100644 --- a/src/NodeContainer/ParsedNodesByType.php +++ b/src/NodeContainer/ParsedNodesByType.php @@ -5,6 +5,7 @@ namespace Rector\NodeContainer; use Nette\Utils\Strings; use PhpParser\Node; use PhpParser\Node\Expr\ClassConstFetch; +use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\New_; use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Stmt\Class_; @@ -40,6 +41,7 @@ final class ParsedNodesByType // simply collected New_::class, StaticCall::class, + MethodCall::class, ]; /** @@ -77,6 +79,11 @@ final class ParsedNodesByType */ private $simpleParsedNodesByType = []; + /** + * @var mixed[] + */ + private $methodsCallsByTypeAndMethod = []; + public function __construct(NameResolver $nameResolver) { $this->nameResolver = $nameResolver; @@ -377,11 +384,34 @@ final class ParsedNodesByType return; } + if ($node instanceof MethodCall || $node instanceof StaticCall) { + $this->addCall($node); + return; + } + // simple collect $type = get_class($node); $this->simpleParsedNodesByType[$type][] = $node; } + /** + * @return MethodCall[] + */ + public function findClassMethodCalls(ClassMethod $classMethod): array + { + $className = $classMethod->getAttribute(AttributeKey::CLASS_NAME); + if ($className === null) { // anonymous + return []; + } + + $methodName = $this->nameResolver->resolve($classMethod); + if ($methodName === null) { + return []; + } + + return $this->methodsCallsByTypeAndMethod[$className][$methodName] ?? []; + } + private function addClass(Class_ $classNode): void { if ($this->isClassAnonymous($classNode)) { @@ -489,4 +519,22 @@ final class ParsedNodesByType // PHPStan polution return Strings::startsWith($classNode->name->toString(), 'AnonymousClass'); } + + /** + * @param MethodCall|StaticCall $node + */ + private function addCall(Node $node): void + { + $className = $this->nodeTypeResolver->resolve($node)[0] ?? null; + if ($className === null) { // anonymous + return; + } + + $methodName = $this->nameResolver->resolve($node); + if ($methodName === null) { + return; + } + + $this->methodsCallsByTypeAndMethod[$className][$methodName][] = $node; + } } diff --git a/src/PhpParser/Node/Manipulator/ClassMethodManipulator.php b/src/PhpParser/Node/Manipulator/ClassMethodManipulator.php index 671fdb8cc88..c7e8e781145 100644 --- a/src/PhpParser/Node/Manipulator/ClassMethodManipulator.php +++ b/src/PhpParser/Node/Manipulator/ClassMethodManipulator.php @@ -4,8 +4,6 @@ namespace Rector\PhpParser\Node\Manipulator; use PhpParser\Node; use PhpParser\Node\Expr\FuncCall; -use PhpParser\Node\Expr\MethodCall; -use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\Variable; use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Param; @@ -163,34 +161,6 @@ final class ClassMethodManipulator }); } - /** - * @return MethodCall[] - */ - public function getAllClassMethodCall(ClassMethod $classMethod): array - { - $classNode = $classMethod->getAttribute(AttributeKey::CLASS_NODE); - if ($classNode === null) { - return []; - } - - return $this->betterNodeFinder->find($classNode, function (Node $node) use ($classMethod) { - // itself - if ($this->betterStandardPrinter->areNodesEqual($node, $classMethod)) { - return false; - } - - // is it the name match? - if ($this->nameResolver->resolve($node) !== $this->nameResolver->resolve($classMethod)) { - return false; - } - - if ($node instanceof MethodCall && $this->nameResolver->isName($node->var, 'this')) { - return true; - } - return $node instanceof StaticCall && $this->nameResolver->isNames($node->class, ['self', 'static']); - }); - } - /** * @param string[] $possibleNames */