Skip to content

Commit 086ba2d

Browse files
committed
Updated Rector to commit 95eeca2cfdf58f76c58dddbf9b499f9eb1fcb6b3
rectorphp/rector-src@95eeca2 Manage named arguments in ArgumentAdderRector rule (#7777)
1 parent 3e869c1 commit 086ba2d

File tree

3 files changed

+57
-10
lines changed

3 files changed

+57
-10
lines changed

rules/Arguments/Rector/ClassMethod/ArgumentAdderRector.php

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PhpParser\Node\Expr\MethodCall;
1111
use PhpParser\Node\Expr\StaticCall;
1212
use PhpParser\Node\Expr\Variable;
13+
use PhpParser\Node\Identifier;
1314
use PhpParser\Node\Name;
1415
use PhpParser\Node\Param;
1516
use PhpParser\Node\Stmt\Class_;
@@ -23,6 +24,7 @@
2324
use Rector\Contract\Rector\ConfigurableRectorInterface;
2425
use Rector\Enum\ObjectReference;
2526
use Rector\Exception\ShouldNotHappenException;
27+
use Rector\NodeAnalyzer\ArgsAnalyzer;
2628
use Rector\PhpParser\AstResolver;
2729
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
2830
use Rector\Rector\AbstractRector;
@@ -51,17 +53,22 @@ final class ArgumentAdderRector extends AbstractRector implements ConfigurableRe
5153
* @readonly
5254
*/
5355
private StaticTypeMapper $staticTypeMapper;
56+
/**
57+
* @readonly
58+
*/
59+
private ArgsAnalyzer $argsAnalyzer;
5460
/**
5561
* @var ArgumentAdder[]|ArgumentAdderWithoutDefaultValue[]
5662
*/
5763
private array $addedArguments = [];
5864
private bool $hasChanged = \false;
59-
public function __construct(ArgumentAddingScope $argumentAddingScope, ChangedArgumentsDetector $changedArgumentsDetector, AstResolver $astResolver, StaticTypeMapper $staticTypeMapper)
65+
public function __construct(ArgumentAddingScope $argumentAddingScope, ChangedArgumentsDetector $changedArgumentsDetector, AstResolver $astResolver, StaticTypeMapper $staticTypeMapper, ArgsAnalyzer $argsAnalyzer)
6066
{
6167
$this->argumentAddingScope = $argumentAddingScope;
6268
$this->changedArgumentsDetector = $changedArgumentsDetector;
6369
$this->astResolver = $astResolver;
6470
$this->staticTypeMapper = $staticTypeMapper;
71+
$this->argsAnalyzer = $argsAnalyzer;
6572
}
6673
public function getRuleDefinition(): RuleDefinition
6774
{
@@ -164,11 +171,17 @@ private function processMethodCall(MethodCall $methodCall, $argumentAdder, int $
164171
}
165172
$defaultValue = $argumentAdder->getArgumentDefaultValue();
166173
$arg = new Arg(BuilderHelpers::normalizeValue($defaultValue));
167-
if (isset($methodCall->args[$position])) {
168-
return;
174+
// if there are named argyments, we just add it at the end as a new named argument
175+
if ($this->argsAnalyzer->hasNamedArg($methodCall->getArgs())) {
176+
$argumentName = $argumentAdder->getArgumentName();
177+
if ($argumentName === null) {
178+
throw new ShouldNotHappenException();
179+
}
180+
$arg->name = new Identifier($argumentName);
181+
} else {
182+
$this->fillGapBetweenWithDefaultValue($methodCall, $position);
169183
}
170-
$this->fillGapBetweenWithDefaultValue($methodCall, $position);
171-
$methodCall->args[$position] = $arg;
184+
$methodCall->args[] = $arg;
172185
$this->hasChanged = \true;
173186
}
174187
/**
@@ -223,7 +236,21 @@ private function shouldSkipParameter($node, $argumentAdder): bool
223236
// argument added and type has been changed
224237
return $this->changedArgumentsDetector->isTypeChanged($param, $argumentAdder->getArgumentType());
225238
}
226-
if (isset($node->args[$position])) {
239+
$arguments = $node->getArgs();
240+
$firstNamedArgumentPosition = $this->argsAnalyzer->resolveFirstNamedArgPosition($arguments);
241+
// If named arguments exist
242+
if ($firstNamedArgumentPosition !== null) {
243+
// Check if the parameter we're trying to add is before the first named argument
244+
if ($position < $firstNamedArgumentPosition) {
245+
return \true;
246+
//if that is the case, the parameter already exists, skip
247+
}
248+
// Check if the parameter we're trying to add is already present as a named argument
249+
if ($this->argsAnalyzer->resolveArgPosition($arguments, $argumentName, -1) !== -1) {
250+
return \true;
251+
// if it exists as a named argument, skip
252+
}
253+
} elseif (isset($node->args[$position])) {
227254
return \true;
228255
}
229256
// Check if default value is the same
@@ -287,8 +314,14 @@ private function processStaticCall(StaticCall $staticCall, int $position, $argum
287314
if (!$this->isName($staticCall->class, ObjectReference::PARENT)) {
288315
return;
289316
}
290-
$this->fillGapBetweenWithDefaultValue($staticCall, $position);
291-
$staticCall->args[$position] = new Arg(new Variable($argumentName));
317+
// if there are named arguments, we just add it at the end as a new named argument
318+
$arg = new Arg(new Variable($argumentName));
319+
if ($this->argsAnalyzer->hasNamedArg($staticCall->getArgs())) {
320+
$arg->name = new Identifier($argumentName);
321+
} else {
322+
$this->fillGapBetweenWithDefaultValue($staticCall, $position);
323+
}
324+
$staticCall->args[] = $arg;
292325
$this->hasChanged = \true;
293326
}
294327
/**

src/Application/VersionResolver.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ final class VersionResolver
1919
* @api
2020
* @var string
2121
*/
22-
public const PACKAGE_VERSION = '3288dc175f3e33b0f8cba66ca849e46093e92a5a';
22+
public const PACKAGE_VERSION = '95eeca2cfdf58f76c58dddbf9b499f9eb1fcb6b3';
2323
/**
2424
* @api
2525
* @var string
2626
*/
27-
public const RELEASE_DATE = '2025-12-25 13:15:51';
27+
public const RELEASE_DATE = '2025-12-25 13:16:25';
2828
/**
2929
* @var int
3030
*/

src/NodeAnalyzer/ArgsAnalyzer.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,18 @@ public function resolveArgPosition(array $args, string $name, int $defaultPositi
4444
}
4545
return $defaultPosition;
4646
}
47+
/**
48+
* @param Arg[] $args
49+
*/
50+
public function resolveFirstNamedArgPosition(array $args): ?int
51+
{
52+
$position = 0;
53+
foreach ($args as $arg) {
54+
if ($arg->name instanceof Identifier) {
55+
return $position;
56+
}
57+
++$position;
58+
}
59+
return null;
60+
}
4761
}

0 commit comments

Comments
 (0)