mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-29 06:03:30 +00:00
Add RemoveExtraParametersRector
This commit is contained in:
parent
cac89cbb9a
commit
8d783a68bd
|
@ -8,3 +8,4 @@ services:
|
|||
Rector\Php\Rector\FuncCall\CountOnNullRector: ~
|
||||
Rector\Php\Rector\FunctionLike\ParamScalarTypehintRector: ~
|
||||
Rector\Php\Rector\FunctionLike\ReturnScalarTypehintRector: ~
|
||||
Rector\Php\Rector\FuncCall\RemoveExtraParametersRector: ~
|
||||
|
|
|
@ -22,13 +22,12 @@ final class NullCoalescingOperatorRector extends AbstractRector
|
|||
$array = [];
|
||||
$array['user_id'] = $array['user_id'] ?? 'value';
|
||||
CODE_SAMPLE
|
||||
,
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
$array = [];
|
||||
$array['user_id'] ??= 'value';
|
||||
CODE_SAMPLE
|
||||
|
||||
)
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
142
packages/Php/src/Rector/FuncCall/RemoveExtraParametersRector.php
Normal file
142
packages/Php/src/Rector/FuncCall/RemoveExtraParametersRector.php
Normal file
|
@ -0,0 +1,142 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php\Rector\FuncCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PhpParser\Parser;
|
||||
use Rector\NodeTypeResolver\Node\Attribute;
|
||||
use Rector\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
use ReflectionFunction;
|
||||
use ReflectionFunctionAbstract;
|
||||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* @see https://www.reddit.com/r/PHP/comments/a1ie7g/is_there_a_linter_for_argumentcounterror_for_php/
|
||||
* @see http://php.net/manual/en/class.argumentcounterror.php
|
||||
*/
|
||||
final class RemoveExtraParametersRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var BetterNodeFinder
|
||||
*/
|
||||
private $betterNodeFinder;
|
||||
|
||||
/**
|
||||
* @var Parser
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
public function __construct(BetterNodeFinder $betterNodeFinder, Parser $parser)
|
||||
{
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Remove extra parameters', [
|
||||
new CodeSample('strlen("asdf", 1);', 'strlen("asdf");'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [FuncCall::class, MethodCall::class, StaticCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FuncCall|MethodCall|StaticCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (count($node->args) === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$reflectionFunctionLike = $this->resolveReflectionFunctionLike($node);
|
||||
|
||||
// can be any number of arguments → nothing to limit here
|
||||
if ($this->isVariadic($reflectionFunctionLike, $node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($reflectionFunctionLike->getNumberOfParameters() >= count($node->args)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for ($i = $reflectionFunctionLike->getNumberOfParameters(); $i < count($node->args); $i++) {
|
||||
unset($node->args[$i]);
|
||||
}
|
||||
|
||||
// re-index for printer
|
||||
$node->args = array_values($node->args);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
private function resolveReflectionFunctionLike(Node $node): ReflectionFunctionAbstract
|
||||
{
|
||||
if ($node instanceof FuncCall) {
|
||||
return new ReflectionFunction($this->getName($node));
|
||||
}
|
||||
|
||||
$className = $node->getAttribute(Attribute::CLASS_NAME);
|
||||
return new ReflectionMethod($className, $this->getName($node));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FuncCall|MethodCall|StaticCall $node
|
||||
*/
|
||||
private function isVariadic(ReflectionFunctionAbstract $reflectionFunctionAbstract): bool
|
||||
{
|
||||
// detects from ... in parameters
|
||||
if ($reflectionFunctionAbstract->isVariadic()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// external function/method
|
||||
$nodes = $this->parser->parse(file_get_contents($reflectionFunctionAbstract->getFileName()));
|
||||
|
||||
$removeFunctionLikeNode = $this->betterNodeFinder->find($nodes, function (Node $node) use ($reflectionFunctionAbstract) {
|
||||
if ($reflectionFunctionAbstract instanceof ReflectionFunction) {
|
||||
if ($node instanceof Function_) {
|
||||
if ($this->isName($node, $reflectionFunctionAbstract->getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($node instanceof ClassMethod) {
|
||||
if ($this->isName($node, $reflectionFunctionAbstract->getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
// detect from "func_*_arg(s)" calls in the body
|
||||
return (bool) $this->betterNodeFinder->findFirst($removeFunctionLikeNode, function (Node $node) {
|
||||
if (! $node instanceof FuncCall) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isNames($node, ['func_get_args', 'func_get_arg', 'func_num_args'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -9,9 +9,7 @@ final class NullCoalescingOperatorRectorTest extends AbstractRectorTestCase
|
|||
{
|
||||
public function test(): void
|
||||
{
|
||||
$this->doTestFiles([
|
||||
__DIR__ . '/Fixture/fixture.php.inc'
|
||||
]);
|
||||
$this->doTestFiles([__DIR__ . '/Fixture/fixture.php.inc']);
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
function removeExtraParams()
|
||||
{
|
||||
strlen('asdf', 1);
|
||||
strlen('asdf');
|
||||
|
||||
functionWithParameters(1);
|
||||
functionWithParameters(1, 2);
|
||||
functionWithParameters(1, 2, 3);
|
||||
|
||||
functionWithVariadics(1);
|
||||
functionWithVariadics(1, 2);
|
||||
}
|
||||
|
||||
function functionWithParameters($a, $b = 5)
|
||||
{
|
||||
}
|
||||
|
||||
function functionWithVariadics(...$variadic)
|
||||
{
|
||||
$argumemnts = $variadic;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
function removeExtraParams()
|
||||
{
|
||||
strlen('asdf');
|
||||
strlen('asdf');
|
||||
|
||||
functionWithParameters(1);
|
||||
functionWithParameters(1, 2);
|
||||
functionWithParameters(1, 2);
|
||||
|
||||
functionWithVariadics(1);
|
||||
functionWithVariadics(1, 2);
|
||||
}
|
||||
|
||||
function functionWithParameters($a, $b = 5)
|
||||
{
|
||||
}
|
||||
|
||||
function functionWithVariadics(...$variadic)
|
||||
{
|
||||
$argumemnts = $variadic;
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Php\Tests\Rector\FuncCall\RemoveExtraParametersRector\Fixture;
|
||||
|
||||
final class FuncGetAll
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->perform();
|
||||
$this->perform(1);
|
||||
$this->perform(1, 2);
|
||||
}
|
||||
|
||||
function perform()
|
||||
{
|
||||
$argumemnts = func_get_args();
|
||||
var_dump($argumemnts);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Php\Tests\Rector\FuncCall\RemoveExtraParametersRector\Fixture;
|
||||
|
||||
final class MethodExtraArgument
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->perform(1);
|
||||
$this->perform(1, 2);
|
||||
}
|
||||
|
||||
private function perform($value)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Php\Tests\Rector\FuncCall\RemoveExtraParametersRector\Fixture;
|
||||
|
||||
final class MethodExtraArgument
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->perform(1);
|
||||
$this->perform(1);
|
||||
}
|
||||
|
||||
private function perform($value)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Php\Tests\Rector\FuncCall\RemoveExtraParametersRector\Fixture;
|
||||
|
||||
final class StaticCalls
|
||||
{
|
||||
public static function run()
|
||||
{
|
||||
self::perform(1);
|
||||
self::perform(1, 2);
|
||||
}
|
||||
|
||||
private static function perform($value)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Php\Tests\Rector\FuncCall\RemoveExtraParametersRector\Fixture;
|
||||
|
||||
final class StaticCalls
|
||||
{
|
||||
public static function run()
|
||||
{
|
||||
self::perform(1);
|
||||
self::perform(1);
|
||||
}
|
||||
|
||||
private static function perform($value)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,24 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php\Tests\Rector\FuncCall\RemoveExtraParametersRector;
|
||||
|
||||
use Rector\Php\Rector\FuncCall\RemoveExtraParametersRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
|
||||
final class RemoveExtraParametersRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
public function test(): void
|
||||
{
|
||||
$this->doTestFiles([
|
||||
// __DIR__ . '/Fixture/fixture.php.inc',
|
||||
__DIR__ . '/Fixture/func_get_all.php.inc',
|
||||
// __DIR__ . '/Fixture/methods.php.inc',
|
||||
// __DIR__ . '/Fixture/static_calls.php.inc',
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return RemoveExtraParametersRector::class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
services:
|
||||
Rector\Php\Rector\FuncCall\RemoveExtraParametersRector: ~
|
Loading…
Reference in New Issue
Block a user