[Arguments] Add RemoveMethodCallParamRector (#1906)

This commit is contained in:
Tomas Votruba 2022-03-05 12:33:32 +01:00 committed by GitHub
parent 00e857f07e
commit 3948d8b1d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 274 additions and 2 deletions

View File

@ -1,10 +1,10 @@
# 505 Rules Overview
# 506 Rules Overview
<br>
## Categories
- [Arguments](#arguments) (4)
- [Arguments](#arguments) (5)
- [CodeQuality](#codequality) (71)
@ -170,6 +170,42 @@ return static function (ContainerConfigurator $containerConfigurator): void {
<br>
### RemoveMethodCallParamRector
Remove parameter of method call
:wrench: **configure it!**
- class: [`Rector\Arguments\Rector\MethodCall\RemoveMethodCallParamRector`](../rules/Arguments/Rector/MethodCall/RemoveMethodCallParamRector.php)
```php
use Rector\Arguments\Rector\MethodCall\RemoveMethodCallParamRector;
use Rector\Arguments\ValueObject\RemoveMethodCallParam;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(RemoveMethodCallParamRector::class)
->configure([new RemoveMethodCallParam('Caller', 'process', 1)]);
};
```
```diff
final class SomeClass
{
public function run(Caller $caller)
{
- $caller->process(1, 2);
+ $caller->process(1);
}
}
```
<br>
### ReplaceArgumentDefaultValueRector
Replaces defined map of arguments in defined methods and their calls.

View File

@ -0,0 +1,13 @@
<?php
namespace Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Fixture;
use Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Source\MethodCaller;
final class SkipAlreadyRemoved
{
public function run(MethodCaller $caller)
{
$caller->process(1);
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Fixture;
use Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Source\MethodCaller;
final class SomeClass
{
public function run(MethodCaller $caller)
{
$caller->process(1, 2);
}
}
?>
-----
<?php
namespace Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Fixture;
use Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Source\MethodCaller;
final class SomeClass
{
public function run(MethodCaller $caller)
{
$caller->process(1);
}
}
?>

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class RemoveMethodCallParamRectorTest 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';
}
}

View File

@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Source;
final class MethodCaller
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
use Rector\Arguments\Rector\MethodCall\RemoveMethodCallParamRector;
use Rector\Arguments\ValueObject\RemoveMethodCallParam;
use Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Source\MethodCaller;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(RemoveMethodCallParamRector::class)
->configure([new RemoveMethodCallParam(MethodCaller::class, 'process', 1)]);
};

View File

@ -0,0 +1,103 @@
<?php
declare(strict_types=1);
namespace Rector\Arguments\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use Rector\Arguments\ValueObject\RemoveMethodCallParam;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use Webmozart\Assert\Assert;
/**
* @see \Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\RemoveMethodCallParamRectorTest
*/
final class RemoveMethodCallParamRector extends AbstractRector implements ConfigurableRectorInterface
{
/**
* @var RemoveMethodCallParam[]
*/
private array $removeMethodCallParams = [];
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Remove parameter of method call', [
new ConfiguredCodeSample(
<<<'CODE_SAMPLE'
final class SomeClass
{
public function run(Caller $caller)
{
$caller->process(1, 2);
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
final class SomeClass
{
public function run(Caller $caller)
{
$caller->process(1);
}
}
CODE_SAMPLE
,
[new RemoveMethodCallParam('Caller', 'process', 1)]
),
]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node): ?Node
{
$hasChanged = false;
foreach ($this->removeMethodCallParams as $removeMethodCallParam) {
if (! $this->isName($node->name, $removeMethodCallParam->getMethodName())) {
continue;
}
if (! $this->isObjectType($node->var, $removeMethodCallParam->getObjectType())) {
continue;
}
$args = $node->getArgs();
if (! isset($args[$removeMethodCallParam->getParamPosition()])) {
continue;
}
unset($node->args[$removeMethodCallParam->getParamPosition()]);
$hasChanged = true;
}
if (! $hasChanged) {
return null;
}
return $node;
}
/**
* @param mixed[] $configuration
*/
public function configure(array $configuration): void
{
Assert::allIsInstanceOf($configuration, RemoveMethodCallParam::class);
$this->removeMethodCallParams = $configuration;
}
}

View File

@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace Rector\Arguments\ValueObject;
use PHPStan\Type\ObjectType;
final class RemoveMethodCallParam
{
public function __construct(
private readonly string $class,
private readonly string $methodName,
private readonly int $paramPosition
) {
}
public function getObjectType(): ObjectType
{
return new ObjectType($this->class);
}
public function getMethodName(): string
{
return $this->methodName;
}
public function getParamPosition(): int
{
return $this->paramPosition;
}
}