mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-20 10:02:29 +00:00
decouple FuncCallManipulator
This commit is contained in:
parent
b611c4aeda
commit
0f8cdacd26
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DeadCode\NodeManipulator;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use PhpParser\NodeTraverser;
|
||||
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
|
||||
final class VariadicFunctionLikeDetector
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private const VARIADIC_FUNCTION_NAMES = ['func_get_arg', 'func_get_args', 'func_num_args'];
|
||||
|
||||
/**
|
||||
* @var NodeNameResolver
|
||||
*/
|
||||
private $nodeNameResolver;
|
||||
|
||||
/**
|
||||
* @var CallableNodeTraverser
|
||||
*/
|
||||
private $callableNodeTraverser;
|
||||
|
||||
public function __construct(NodeNameResolver $nodeNameResolver, CallableNodeTraverser $callableNodeTraverser)
|
||||
{
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->callableNodeTraverser = $callableNodeTraverser;
|
||||
}
|
||||
|
||||
public function isVariadic(FunctionLike $functionLike): bool
|
||||
{
|
||||
$isVariadic = false;
|
||||
|
||||
$this->callableNodeTraverser->traverseNodesWithCallable(
|
||||
(array) $functionLike->getStmts(),
|
||||
function (Node $node) use (&$isVariadic) {
|
||||
if (! $node instanceof FuncCall) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->nodeNameResolver->isNames($node, self::VARIADIC_FUNCTION_NAMES)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$isVariadic = true;
|
||||
|
||||
return NodeTraverser::STOP_TRAVERSAL;
|
||||
}
|
||||
);
|
||||
|
||||
return $isVariadic;
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ use Rector\Core\Rector\AbstractRector;
|
|||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\DeadCode\NodeManipulator\MagicMethodDetector;
|
||||
use Rector\DeadCode\NodeManipulator\VariadicFunctionLikeDetector;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
/**
|
||||
|
@ -39,14 +40,21 @@ final class RemoveUnusedParameterRector extends AbstractRector
|
|||
*/
|
||||
private $magicMethodDetector;
|
||||
|
||||
/**
|
||||
* @var VariadicFunctionLikeDetector
|
||||
*/
|
||||
private $variadicFunctionLikeDetector;
|
||||
|
||||
public function __construct(
|
||||
ClassManipulator $classManipulator,
|
||||
ClassMethodManipulator $classMethodManipulator,
|
||||
MagicMethodDetector $magicMethodDetector
|
||||
MagicMethodDetector $magicMethodDetector,
|
||||
VariadicFunctionLikeDetector $variadicFunctionLikeDetector
|
||||
) {
|
||||
$this->classManipulator = $classManipulator;
|
||||
$this->classMethodManipulator = $classMethodManipulator;
|
||||
$this->magicMethodDetector = $magicMethodDetector;
|
||||
$this->variadicFunctionLikeDetector = $variadicFunctionLikeDetector;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
|
@ -113,9 +121,12 @@ PHP
|
|||
|
||||
foreach ($childrenOfClass as $childClassNode) {
|
||||
$methodOfChild = $childClassNode->getMethod($methodName);
|
||||
if ($methodOfChild !== null) {
|
||||
$this->removeNodes($this->getParameterOverlap($methodOfChild->params, $unusedParameters));
|
||||
if ($methodOfChild === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$overlappingParameters = $this->getParameterOverlap($methodOfChild->params, $unusedParameters);
|
||||
$this->removeNodes($overlappingParameters);
|
||||
}
|
||||
|
||||
$this->removeNodes($unusedParameters);
|
||||
|
@ -124,7 +135,7 @@ PHP
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Class_[] $childrenOfClass
|
||||
* @param Class_[] $childrenOfClass
|
||||
* @return Param[]
|
||||
*/
|
||||
private function getUnusedParameters(ClassMethod $classMethod, string $methodName, array $childrenOfClass): array
|
||||
|
@ -136,13 +147,16 @@ PHP
|
|||
|
||||
foreach ($childrenOfClass as $childClassNode) {
|
||||
$methodOfChild = $childClassNode->getMethod($methodName);
|
||||
if ($methodOfChild !== null) {
|
||||
$unusedParameters = $this->getParameterOverlap(
|
||||
$unusedParameters,
|
||||
$this->resolveUnusedParameters($methodOfChild)
|
||||
);
|
||||
if ($methodOfChild === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$unusedParameters = $this->getParameterOverlap(
|
||||
$unusedParameters,
|
||||
$this->resolveUnusedParameters($methodOfChild)
|
||||
);
|
||||
}
|
||||
|
||||
return $unusedParameters;
|
||||
}
|
||||
|
||||
|
@ -156,8 +170,8 @@ PHP
|
|||
return array_uintersect(
|
||||
$parameters1,
|
||||
$parameters2,
|
||||
function (Param $a, Param $b): int {
|
||||
return $this->areNodesEqual($a, $b) ? 0 : 1;
|
||||
function (Param $firstParam, Param $secondParam): int {
|
||||
return $this->areNodesWithoutCommentsEqual($firstParam, $secondParam) ? 0 : 1;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -195,6 +209,10 @@ PHP
|
|||
return true;
|
||||
}
|
||||
|
||||
if ($this->variadicFunctionLikeDetector->isVariadic($classMethod)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$class = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
|
||||
// skip interfaces and traits
|
||||
if (! $class instanceof Class_) {
|
||||
|
|
|
@ -13,7 +13,6 @@ use PhpParser\Node\Stmt\Class_;
|
|||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\PhpParser\Node\Value\ValueResolver;
|
||||
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
@ -42,22 +41,22 @@ final class ClassMethodManipulator
|
|||
private $nodeNameResolver;
|
||||
|
||||
/**
|
||||
* @var ValueResolver
|
||||
* @var FuncCallManipulator
|
||||
*/
|
||||
private $valueResolver;
|
||||
private $funcCallManipulator;
|
||||
|
||||
public function __construct(
|
||||
BetterNodeFinder $betterNodeFinder,
|
||||
BetterStandardPrinter $betterStandardPrinter,
|
||||
NodeTypeResolver $nodeTypeResolver,
|
||||
NodeNameResolver $nodeNameResolver,
|
||||
ValueResolver $valueResolver
|
||||
FuncCallManipulator $funcCallManipulator
|
||||
) {
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->betterStandardPrinter = $betterStandardPrinter;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->valueResolver = $valueResolver;
|
||||
$this->funcCallManipulator = $funcCallManipulator;
|
||||
}
|
||||
|
||||
public function isParameterUsedMethod(Param $param, ClassMethod $classMethod): bool
|
||||
|
@ -81,7 +80,7 @@ final class ClassMethodManipulator
|
|||
return $this->nodeNameResolver->isName($node, 'compact');
|
||||
});
|
||||
|
||||
$arguments = $this->extractArgumentsFromCompactFuncCalls($compactFuncCalls);
|
||||
$arguments = $this->funcCallManipulator->extractArgumentsFromCompactFuncCalls($compactFuncCalls);
|
||||
|
||||
return $this->nodeNameResolver->isNames($param, $arguments);
|
||||
}
|
||||
|
@ -208,26 +207,6 @@ final class ClassMethodManipulator
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FuncCall[] $compactFuncCalls
|
||||
* @return string[]
|
||||
*/
|
||||
private function extractArgumentsFromCompactFuncCalls(array $compactFuncCalls): array
|
||||
{
|
||||
$arguments = [];
|
||||
foreach ($compactFuncCalls as $compactFuncCall) {
|
||||
foreach ($compactFuncCall->args as $arg) {
|
||||
$value = $this->valueResolver->getValue($arg->value);
|
||||
|
||||
if ($value) {
|
||||
$arguments[] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
private function isMethodInParent(string $class, string $method): bool
|
||||
{
|
||||
foreach (class_parents($class) as $parentClass) {
|
||||
|
|
42
src/PhpParser/Node/Manipulator/FuncCallManipulator.php
Normal file
42
src/PhpParser/Node/Manipulator/FuncCallManipulator.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\PhpParser\Node\Manipulator;
|
||||
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use Rector\Core\PhpParser\Node\Value\ValueResolver;
|
||||
|
||||
final class FuncCallManipulator
|
||||
{
|
||||
/**
|
||||
* @var ValueResolver
|
||||
*/
|
||||
private $valueResolver;
|
||||
|
||||
public function __construct(ValueResolver $valueResolver)
|
||||
{
|
||||
$this->valueResolver = $valueResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FuncCall[] $compactFuncCalls
|
||||
* @return string[]
|
||||
*/
|
||||
public function extractArgumentsFromCompactFuncCalls(array $compactFuncCalls): array
|
||||
{
|
||||
$arguments = [];
|
||||
foreach ($compactFuncCalls as $compactFuncCall) {
|
||||
foreach ($compactFuncCall->args as $arg) {
|
||||
$value = $this->valueResolver->getValue($arg->value);
|
||||
if ($value === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$arguments[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user