Skip to content

Commit f1c5104

Browse files
Manage named arguments when removing values (#7835)
1 parent 26f7bc1 commit f1c5104

File tree

5 files changed

+103
-2
lines changed

5 files changed

+103
-2
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Fixture;
4+
5+
use Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Source\SomeMultiArg;
6+
7+
$object = new SomeMultiArg();
8+
$object->firstArgument(0, b: 1);
9+
$object->firstArgument(a: 0);
10+
$object->firstArgument(b: 1, a: 0);
11+
$object->secondArgument(0, b: 1);
12+
$object->secondArgument(b: 1);
13+
$object->secondArgument(b: 1, a: 0);
14+
15+
?>
16+
17+
-----
18+
<?php
19+
20+
namespace Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Fixture;
21+
22+
use Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Source\SomeMultiArg;
23+
24+
$object = new SomeMultiArg();
25+
$object->firstArgument(b: 1);
26+
$object->firstArgument();
27+
$object->firstArgument(b: 1);
28+
$object->secondArgument(0);
29+
$object->secondArgument();
30+
$object->secondArgument(a: 0);
31+
32+
?>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Fixture;
4+
5+
use Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Source\SomeMultiArg;
6+
7+
$object = new SomeMultiArg();
8+
$object->firstArgument(b: 1);
9+
$object->secondArgument(a: 1);
10+
$object->secondArgument(0, c: 2);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Source;
6+
7+
class SomeMultiArg
8+
{
9+
public function firstArgument($a = 1, $b = 2)
10+
{
11+
}
12+
13+
public function secondArgument($a = 1, $b = 2, $c = 3)
14+
{
15+
}
16+
}

‎rules-tests/Arguments/Rector/MethodCall/RemoveMethodCallParamRector/config/configured_rule.php‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66
use Rector\Arguments\ValueObject\RemoveMethodCallParam;
77
use Rector\Config\RectorConfig;
88
use Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Source\MethodCaller;
9+
use Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Source\SomeMultiArg;
910
use Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\Source\StaticCaller;
1011

1112
return static function (RectorConfig $rectorConfig): void {
1213
$rectorConfig
1314
->ruleWithConfiguration(RemoveMethodCallParamRector::class, [
1415
new RemoveMethodCallParam(MethodCaller::class, 'process', 1),
1516
new RemoveMethodCallParam(StaticCaller::class, 'remove', 3),
17+
new RemoveMethodCallParam(SomeMultiArg::class, 'firstArgument', 0),
18+
new RemoveMethodCallParam(SomeMultiArg::class, 'secondArgument', 1),
1619
]);
1720
};

‎rules/Arguments/Rector/MethodCall/RemoveMethodCallParamRector.php‎

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
use PhpParser\Node;
88
use PhpParser\Node\Expr\MethodCall;
99
use PhpParser\Node\Expr\StaticCall;
10+
use PhpParser\Node\Expr\Variable;
1011
use Rector\Arguments\ValueObject\RemoveMethodCallParam;
1112
use Rector\Contract\Rector\ConfigurableRectorInterface;
13+
use Rector\NodeAnalyzer\ArgsAnalyzer;
14+
use Rector\PhpParser\AstResolver;
1215
use Rector\Rector\AbstractRector;
1316
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
1417
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@@ -25,6 +28,12 @@ final class RemoveMethodCallParamRector extends AbstractRector implements Config
2528
*/
2629
private array $removeMethodCallParams = [];
2730

31+
public function __construct(
32+
private readonly AstResolver $astResolver,
33+
private readonly ArgsAnalyzer $argsAnalyzer,
34+
) {
35+
}
36+
2837
public function getRuleDefinition(): RuleDefinition
2938
{
3039
return new RuleDefinition('Remove parameter of method call', [
@@ -83,11 +92,42 @@ public function refactor(Node $node): ?Node
8392
}
8493

8594
$args = $node->getArgs();
86-
if (! isset($args[$removeMethodCallParam->getParamPosition()])) {
95+
$position = $removeMethodCallParam->getParamPosition();
96+
$firstNamedArgPosition = $this->argsAnalyzer->resolveFirstNamedArgPosition($args);
97+
98+
// if the call has named arguments and the argument that we want to remove is not
99+
// before any named argument, we need to check if it is in the list of named arguments
100+
// if it is, we use the position of the named argument as the position to remove
101+
// if it is not, we cannot remove it
102+
if ($firstNamedArgPosition !== null && $position >= $firstNamedArgPosition) {
103+
$call = $this->astResolver->resolveClassMethodOrFunctionFromCall($node);
104+
if ($call === null) {
105+
return null;
106+
}
107+
108+
$paramName = null;
109+
$variable = $call->params[$position]->var;
110+
if ($variable instanceof Variable) {
111+
$paramName = $variable->name;
112+
}
113+
114+
$newPosition = -1;
115+
if (is_string($paramName)) {
116+
$newPosition = $this->argsAnalyzer->resolveArgPosition($args, $paramName, $newPosition);
117+
}
118+
119+
if ($newPosition === -1) {
120+
return null;
121+
}
122+
123+
$position = $newPosition;
124+
}
125+
126+
if (! isset($args[$position])) {
87127
continue;
88128
}
89129

90-
unset($node->args[$removeMethodCallParam->getParamPosition()]);
130+
unset($node->args[$position]);
91131
$hasChanged = true;
92132
}
93133

0 commit comments

Comments
 (0)