mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-24 11:44:14 +01:00
[DeadCode] Fix RemoveUnusedPrivateMethodRector for self call
This commit is contained in:
parent
e2134fedb4
commit
860853dc93
@ -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);
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\DeadCode\Tests\Rector\ClassMethod\RemoveUnusedPrivateMethodRector\Fixture;
|
||||
|
||||
/**
|
||||
* @see https://3v4l.org/IsSHq
|
||||
*/
|
||||
class Customer
|
||||
{
|
||||
private $id;
|
||||
public static function create($id){
|
||||
$customer = new self();
|
||||
$customer->setId($id);
|
||||
return $customer;
|
||||
}
|
||||
private function setId($id){
|
||||
$this->id=$id;
|
||||
}
|
||||
}
|
@ -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',
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user