mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-01 17:00:51 +00:00
[DeadCode] Remove RemoveDefaultArgumentValueRector (#6148)
This commit is contained in:
parent
c98e180be9
commit
101041d6ae
|
@ -116,7 +116,6 @@
|
|||
"stubs/Doctrine/Common/Persistence/ObjectManager.php",
|
||||
"vendor/nette/forms/src/Forms/Controls/SubmitButton.php",
|
||||
"rules-tests/Restoration/Rector/Use_/RestoreFullyQualifiedNameRector/Source/ShortClassOnly.php",
|
||||
"rules-tests/DeadCode/Rector/MethodCall/RemoveDefaultArgumentValueRector/Source/UserDefined.php",
|
||||
"rules-tests/Transform/Rector/FuncCall/FuncCallToMethodCallRector/Source/some_view_function.php",
|
||||
"rules-tests/TypeDeclaration/Rector/FunctionLike/ReturnTypeDeclarationRector/Source/MyBar.php",
|
||||
"rules-tests/TypeDeclaration/Rector/Property/CompleteVarDocTypePropertyRector/Source/EventDispatcher.php",
|
||||
|
|
|
@ -33,7 +33,6 @@ use Rector\DeadCode\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector;
|
|||
use Rector\DeadCode\Rector\If_\SimplifyIfElseWithSameContentRector;
|
||||
use Rector\DeadCode\Rector\If_\UnwrapFutureCompatibleIfFunctionExistsRector;
|
||||
use Rector\DeadCode\Rector\If_\UnwrapFutureCompatibleIfPhpVersionRector;
|
||||
use Rector\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector;
|
||||
use Rector\DeadCode\Rector\MethodCall\RemoveEmptyMethodCallRector;
|
||||
use Rector\DeadCode\Rector\Node\RemoveNonExistingVarAnnotationRector;
|
||||
use Rector\DeadCode\Rector\Property\RemoveSetterOnlyPropertyAndMethodCallRector;
|
||||
|
@ -69,7 +68,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
$services->set(RemoveDeadReturnRector::class);
|
||||
$services->set(RemoveDeadIfForeachForRector::class);
|
||||
$services->set(RemoveAndTrueRector::class);
|
||||
$services->set(RemoveDefaultArgumentValueRector::class);
|
||||
$services->set(RemoveConcatAutocastRector::class);
|
||||
$services->set(SimplifyUselessVariableRector::class);
|
||||
$services->set(RemoveDelegatingParentCallRector::class);
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
class Fixture
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->runWithDefault([]);
|
||||
$card = self::runStaticWithDefault([]);
|
||||
}
|
||||
|
||||
public function runWithDefault($items = [])
|
||||
{
|
||||
return $items;
|
||||
}
|
||||
|
||||
public static function runStaticWithDefault($cards = [])
|
||||
{
|
||||
return $cards;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
class Fixture
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->runWithDefault();
|
||||
$card = self::runStaticWithDefault();
|
||||
}
|
||||
|
||||
public function runWithDefault($items = [])
|
||||
{
|
||||
return $items;
|
||||
}
|
||||
|
||||
public static function runStaticWithDefault($cards = [])
|
||||
{
|
||||
return $cards;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
function someLocalFunction($items = [])
|
||||
{
|
||||
}
|
||||
|
||||
someLocalFunction([]);
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
function someLocalFunction($items = [])
|
||||
{
|
||||
}
|
||||
|
||||
someLocalFunction();
|
||||
|
||||
?>
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
function notLastArgument($a = false, $b = false, $c = false, $d = false) {
|
||||
$level = getLevelFromSomewhere();
|
||||
|
||||
if ($level == "a" && !$a) return false;
|
||||
if ($level == "b" && !$b) return false;
|
||||
if ($level == "c" && !$c) return false;
|
||||
if ($level == "d" && !$d) return false;
|
||||
}
|
||||
|
||||
notLastArgument(true, false, true, false);
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
function notLastArgument($a = false, $b = false, $c = false, $d = false) {
|
||||
$level = getLevelFromSomewhere();
|
||||
|
||||
if ($level == "a" && !$a) return false;
|
||||
if ($level == "b" && !$b) return false;
|
||||
if ($level == "c" && !$c) return false;
|
||||
if ($level == "d" && !$d) return false;
|
||||
}
|
||||
|
||||
notLastArgument(true, false, true);
|
||||
|
||||
?>
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
function notLastArgument2($a = false, $b = false, $c = false, $d = false) {
|
||||
$level = getLevelFromSomewhere();
|
||||
|
||||
if ($level == "a" && !$a) return false;
|
||||
if ($level == "b" && !$b) return false;
|
||||
if ($level == "c" && !$c) return false;
|
||||
if ($level == "d" && !$d) return false;
|
||||
}
|
||||
|
||||
notLastArgument2(false, false, true, false);
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
function notLastArgument2($a = false, $b = false, $c = false, $d = false) {
|
||||
$level = getLevelFromSomewhere();
|
||||
|
||||
if ($level == "a" && !$a) return false;
|
||||
if ($level == "b" && !$b) return false;
|
||||
if ($level == "c" && !$c) return false;
|
||||
if ($level == "d" && !$d) return false;
|
||||
}
|
||||
|
||||
notLastArgument2(false, false, true);
|
||||
|
||||
?>
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
function notLastArgument3($a = false, $b = false, $c = false, $d = false) {
|
||||
$level = getLevelFromSomewhere();
|
||||
|
||||
if ($level == "a" && !$a) return false;
|
||||
if ($level == "b" && !$b) return false;
|
||||
if ($level == "c" && !$c) return false;
|
||||
if ($level == "d" && !$d) return false;
|
||||
}
|
||||
|
||||
notLastArgument3(false, true, true, false);
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
function notLastArgument3($a = false, $b = false, $c = false, $d = false) {
|
||||
$level = getLevelFromSomewhere();
|
||||
|
||||
if ($level == "a" && !$a) return false;
|
||||
if ($level == "b" && !$b) return false;
|
||||
if ($level == "c" && !$c) return false;
|
||||
if ($level == "d" && !$d) return false;
|
||||
}
|
||||
|
||||
notLastArgument3(false, true, true);
|
||||
|
||||
?>
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
use stdClass;
|
||||
|
||||
function skipHasRequiredArgument(stdClass $stdClass)
|
||||
{
|
||||
}
|
||||
|
||||
skipHasRequiredArgument(new stdClass);
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
function SkipNoArgument()
|
||||
{
|
||||
}
|
||||
|
||||
SkipNoArgument();
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
class SkipPreviousOrder
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->runWithDefault([], 5);
|
||||
}
|
||||
|
||||
public function runWithDefault($items = [], $value)
|
||||
{
|
||||
return $items;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
final class SkipStaticMethodCall
|
||||
{
|
||||
public function __invoke(callable $callback): void
|
||||
{
|
||||
\Closure::bind($callback, $this, self::class)($this);
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
class SkipSystemFunction
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
trigger_error('Error message', E_USER_NOTICE);
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
use function Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Source\userDefinedFunction;
|
||||
|
||||
class UserVendorFunction
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
userDefinedFunction([]);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
|
||||
|
||||
use function Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Source\userDefinedFunction;
|
||||
|
||||
class UserVendorFunction
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
userDefinedFunction();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class RemoveDefaultArgumentValueRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/configured_rule.php';
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\Source;
|
||||
|
||||
function userDefinedFunction($values = [])
|
||||
{
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->set(RemoveDefaultArgumentValueRector::class);
|
||||
};
|
|
@ -1,194 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DeadCode\Rector\MethodCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Name;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\DeadCode\NodeManipulator\CallDefaultParamValuesResolver;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\DeadCode\Rector\MethodCall\RemoveDefaultArgumentValueRector\RemoveDefaultArgumentValueRectorTest
|
||||
*/
|
||||
final class RemoveDefaultArgumentValueRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var CallDefaultParamValuesResolver
|
||||
*/
|
||||
private $callDefaultParamValuesResolver;
|
||||
|
||||
/**
|
||||
* @var ReflectionProvider
|
||||
*/
|
||||
private $reflectionProvider;
|
||||
|
||||
public function __construct(
|
||||
CallDefaultParamValuesResolver $callDefaultParamValuesResolver,
|
||||
ReflectionProvider $reflectionProvider
|
||||
) {
|
||||
$this->callDefaultParamValuesResolver = $callDefaultParamValuesResolver;
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Remove argument value, if it is the same as default value', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->runWithDefault([]);
|
||||
$card = self::runWithStaticDefault([]);
|
||||
}
|
||||
|
||||
public function runWithDefault($items = [])
|
||||
{
|
||||
return $items;
|
||||
}
|
||||
|
||||
public function runStaticWithDefault($cards = [])
|
||||
{
|
||||
return $cards;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->runWithDefault();
|
||||
$card = self::runWithStaticDefault();
|
||||
}
|
||||
|
||||
public function runWithDefault($items = [])
|
||||
{
|
||||
return $items;
|
||||
}
|
||||
|
||||
public function runStaticWithDefault($cards = [])
|
||||
{
|
||||
return $cards;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [MethodCall::class, StaticCall::class, FuncCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall|StaticCall|FuncCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($this->shouldSkip($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$defaultValues = $this->callDefaultParamValuesResolver->resolveFromCall($node);
|
||||
|
||||
$keysToRemove = $this->resolveKeysToRemove($node, $defaultValues);
|
||||
if ($keysToRemove === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($keysToRemove as $keyToRemove) {
|
||||
if (! isset($defaultValues[$keyToRemove])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->nodeRemover->removeArg($node, $keyToRemove);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall|StaticCall|FuncCall $node
|
||||
*/
|
||||
private function shouldSkip(Node $node): bool
|
||||
{
|
||||
if ($node->args === []) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! $node instanceof FuncCall) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $node->name instanceof Name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$functionName = $this->getName($node);
|
||||
if ($functionName === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = new Name($functionName);
|
||||
if (! $this->reflectionProvider->hasFunction($name, null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$reflectionFunction = $this->reflectionProvider->getFunction($name, null);
|
||||
|
||||
// skip native functions, hard to analyze without stubs (stubs would make working with IDE non-practical)
|
||||
return $reflectionFunction->isBuiltin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StaticCall|MethodCall|FuncCall $node
|
||||
* @param Expr[]|mixed[] $defaultValues
|
||||
* @return int[]
|
||||
*/
|
||||
private function resolveKeysToRemove(Node $node, array $defaultValues): array
|
||||
{
|
||||
$keysToKeep = [];
|
||||
|
||||
/** @var int $key */
|
||||
foreach ($node->args as $key => $arg) {
|
||||
if (! isset($defaultValues[$key])) {
|
||||
$keysToKeep[] = $key;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $this->nodeComparator->areNodesEqual($defaultValues[$key], $arg->value)) {
|
||||
$keysToKeep[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
$lastKeyToKeep = end($keysToKeep);
|
||||
$maxKey = count($node->args) - 1;
|
||||
|
||||
if ($lastKeyToKeep === false) {
|
||||
return range(0, $maxKey);
|
||||
}
|
||||
|
||||
$startremove = $lastKeyToKeep + 1;
|
||||
if ($maxKey < $startremove) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return range($startremove, $maxKey);
|
||||
}
|
||||
}
|
|
@ -68,6 +68,7 @@ CODE_SAMPLE
|
|||
$node->getAttribute(AttributeKey::SCOPE),
|
||||
'_'
|
||||
);
|
||||
|
||||
$variable = new Variable($tempVarName);
|
||||
$called = $node instanceof NullsafeMethodCall
|
||||
? new MethodCall($variable, $node->name, $node->args)
|
||||
|
|
Loading…
Reference in New Issue
Block a user