diff --git a/rules-tests/Arguments/Rector/ClassMethod/ReplaceArgumentDefaultValueRector/Fixture/replace_named_arguments.php.inc b/rules-tests/Arguments/Rector/ClassMethod/ReplaceArgumentDefaultValueRector/Fixture/replace_named_arguments.php.inc new file mode 100644 index 00000000000..23c42ec1c40 --- /dev/null +++ b/rules-tests/Arguments/Rector/ClassMethod/ReplaceArgumentDefaultValueRector/Fixture/replace_named_arguments.php.inc @@ -0,0 +1,32 @@ +firstArgument(0, b: 1); +$object->firstArgument(a: 0); +$object->firstArgument(b: 1, a: 0); +$object->secondArgument(0, b: 1); +$object->secondArgument(b: 1); +$object->secondArgument(b: 1, a: 0); + +?> + +----- +firstArgument(3, b: 1); +$object->firstArgument(a: 3); +$object->firstArgument(b: 1, a: 3); +$object->secondArgument(0, b: 4); +$object->secondArgument(b: 4); +$object->secondArgument(b: 4, a: 0); + +?> diff --git a/rules-tests/Arguments/Rector/ClassMethod/ReplaceArgumentDefaultValueRector/Fixture/skip_named_arguments.php.inc b/rules-tests/Arguments/Rector/ClassMethod/ReplaceArgumentDefaultValueRector/Fixture/skip_named_arguments.php.inc new file mode 100644 index 00000000000..e91280a69d3 --- /dev/null +++ b/rules-tests/Arguments/Rector/ClassMethod/ReplaceArgumentDefaultValueRector/Fixture/skip_named_arguments.php.inc @@ -0,0 +1,13 @@ +firstArgument(b: 1); +$object->secondArgument(a: 1); +$object->secondArgument(0, c: 2); +Yaml::parse('...', flags: false, other: false, another: true); diff --git a/rules-tests/Arguments/Rector/ClassMethod/ReplaceArgumentDefaultValueRector/Source/SomeMultiArg.php b/rules-tests/Arguments/Rector/ClassMethod/ReplaceArgumentDefaultValueRector/Source/SomeMultiArg.php new file mode 100644 index 00000000000..eafdc7b4487 --- /dev/null +++ b/rules-tests/Arguments/Rector/ClassMethod/ReplaceArgumentDefaultValueRector/Source/SomeMultiArg.php @@ -0,0 +1,16 @@ +processParams($node, $replaceArgumentDefaultValue); } - if (! isset($node->args[$replaceArgumentDefaultValue->getPosition()])) { - return null; - } - return $this->processArgs($node, $replaceArgumentDefaultValue); } @@ -102,7 +103,48 @@ private function processArgs( } $position = $replaceArgumentDefaultValue->getPosition(); - $particularArg = $expr->getArgs()[$position] ?? null; + $arguments = $expr->getArgs(); + $firstNamedArgPosition = $this->argsAnalyzer->resolveFirstNamedArgPosition($arguments); + // if the call has named argyments and we want to replace an array of values + // we cannot replace it as we cannot really match this array of values to + // the existing arguments, it would be too complex + if ($firstNamedArgPosition !== null && is_array($replaceArgumentDefaultValue->getValueBefore())) { + return null; + } + + // if the call has named arguments and the argument that we want to replace is not + // before any named argument, we need to check if it is in the list of named arguments + // if it is, we use the position of the named argyment as the position to replace + // if it is not, we cannot replace it + if ($firstNamedArgPosition !== null && $position >= $firstNamedArgPosition) { + $call = $this->astResolver->resolveClassMethodOrFunctionFromCall($expr); + if ($call === null) { + return null; + } + + $paramName = null; + $variable = $call->params[$position]->var; + if ($variable instanceof Variable) { + $paramName = $variable->name; + } + + $newPosition = -1; + if (is_string($paramName)) { + $newPosition = $this->argsAnalyzer->resolveArgPosition($arguments, $paramName, $newPosition); + } + + if ($newPosition === -1) { + return null; + } + + $position = $newPosition; + } + + if (! isset($arguments[$position])) { + return null; + } + + $particularArg = $arguments[$position] ?? null; if (! $particularArg instanceof Arg) { return null; } @@ -111,7 +153,7 @@ private function processArgs( if (is_scalar( $replaceArgumentDefaultValue->getValueBefore() ) && $argValue === $replaceArgumentDefaultValue->getValueBefore()) { - $expr->args[$position] = $this->normalizeValueToArgument($replaceArgumentDefaultValue->getValueAfter()); + $particularArg->value = $this->normalizeValue($replaceArgumentDefaultValue->getValueAfter()); return $expr; }