From aec30b74b9d411c337ff07dfefd297225f33d0b7 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 11 Sep 2025 19:32:13 +0700 Subject: [PATCH] [Php81] Handle different named argument on NullToStrictStringFuncCallArgRector --- config/set/php85.php | 2 +- .../Fixture/different_named.php.inc | 27 +++++++++++++++++++ .../NullToStrictStringFuncCallArgRector.php | 27 +++++++------------ .../Rector/Class_/SleepToSerializeRector.php | 4 +-- src/ValueObject/PhpVersionFeature.php | 2 +- 5 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/different_named.php.inc diff --git a/config/set/php85.php b/config/set/php85.php index cee158fa245..81d2598ad6b 100644 --- a/config/set/php85.php +++ b/config/set/php85.php @@ -8,8 +8,8 @@ use PhpParser\Node\Expr\Cast\String_; use Rector\Config\RectorConfig; use Rector\Php85\Rector\ArrayDimFetch\ArrayFirstLastRector; -use Rector\Php85\Rector\ClassMethod\NullDebugInfoReturnRector; use Rector\Php85\Rector\Class_\SleepToSerializeRector; +use Rector\Php85\Rector\ClassMethod\NullDebugInfoReturnRector; use Rector\Php85\Rector\Const_\DeprecatedAnnotationToDeprecatedAttributeRector; use Rector\Php85\Rector\FuncCall\ArrayKeyExistsNullToEmptyStringRector; use Rector\Php85\Rector\FuncCall\ChrArgModuloRector; diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/different_named.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/different_named.php.inc new file mode 100644 index 00000000000..7426af4e5e3 --- /dev/null +++ b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/different_named.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php b/rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php index 42abbafa38d..7b115dc6d2b 100644 --- a/rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php +++ b/rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php @@ -12,7 +12,6 @@ use PHPStan\Reflection\ClassReflection; use PHPStan\Reflection\FunctionReflection; use PHPStan\Reflection\Native\NativeFunctionReflection; -use Rector\NodeAnalyzer\ArgsAnalyzer; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper; use Rector\Php81\Enum\NameNullToStrictNullFunctionMap; @@ -31,7 +30,6 @@ final class NullToStrictStringFuncCallArgRector extends AbstractRector implement { public function __construct( private readonly ReflectionResolver $reflectionResolver, - private readonly ArgsAnalyzer $argsAnalyzer, private readonly NullToStrictStringIntConverter $nullToStrictStringIntConverter ) { } @@ -89,9 +87,7 @@ public function refactor(Node $node): ?Node } $args = $node->getArgs(); - $positions = $this->argsAnalyzer->hasNamedArg($args) - ? $this->resolveNamedPositions($node, $args) - : $this->resolveOriginalPositions($node, $scope); + $positions = $this->resolvePositions($node, $args, $scope); if ($positions === []) { return null; @@ -139,11 +135,13 @@ public function provideMinPhpVersion(): int * @param Arg[] $args * @return int[]|string[] */ - private function resolveNamedPositions(FuncCall $funcCall, array $args): array + private function resolvePositions(FuncCall $funcCall, array $args, Scope $scope): array { + $positions = []; + $functionName = $this->getName($funcCall); $argNames = NameNullToStrictNullFunctionMap::FUNCTION_TO_PARAM_NAMES[$functionName] ?? []; - $positions = []; + $excludedArgNames = []; foreach ($args as $position => $arg) { if (! $arg->name instanceof Identifier) { @@ -154,20 +152,13 @@ private function resolveNamedPositions(FuncCall $funcCall, array $args): array continue; } + $excludedArgNames[] = $arg->name->toString(); $positions[] = $position; } - return $positions; - } - - /** - * @return int[]|string[] - */ - private function resolveOriginalPositions(FuncCall $funcCall, Scope $scope): array - { $functionReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($funcCall); if (! $functionReflection instanceof NativeFunctionReflection) { - return []; + return $positions; } $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select( @@ -177,10 +168,10 @@ private function resolveOriginalPositions(FuncCall $funcCall, Scope $scope): arr ); $functionName = $functionReflection->getName(); $argNames = NameNullToStrictNullFunctionMap::FUNCTION_TO_PARAM_NAMES[$functionName]; - $positions = []; foreach ($parametersAcceptor->getParameters() as $position => $parameterReflection) { - if (in_array($parameterReflection->getName(), $argNames, true)) { + if (in_array($parameterReflection->getName(), $argNames, true) + && ! in_array($parameterReflection->getName(), $excludedArgNames, true)) { $positions[] = $position; } } diff --git a/rules/Php85/Rector/Class_/SleepToSerializeRector.php b/rules/Php85/Rector/Class_/SleepToSerializeRector.php index c70198b7f1d..ce0595d9cb7 100644 --- a/rules/Php85/Rector/Class_/SleepToSerializeRector.php +++ b/rules/Php85/Rector/Class_/SleepToSerializeRector.php @@ -4,13 +4,13 @@ namespace Rector\Php85\Rector\Class_; -use PhpParser\Node\Scalar\String_; -use PhpParser\Node\Expr\Variable; use PhpParser\Node; use PhpParser\Node\Expr\Array_; use PhpParser\Node\Expr\ArrayItem; use PhpParser\Node\Expr\PropertyFetch; +use PhpParser\Node\Expr\Variable; use PhpParser\Node\Identifier; +use PhpParser\Node\Scalar\String_; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; use Rector\PhpParser\Node\BetterNodeFinder; diff --git a/src/ValueObject/PhpVersionFeature.php b/src/ValueObject/PhpVersionFeature.php index 78a946ee218..0fb9c7daf04 100644 --- a/src/ValueObject/PhpVersionFeature.php +++ b/src/ValueObject/PhpVersionFeature.php @@ -816,7 +816,7 @@ final class PhpVersionFeature * @var int */ public const DEPRECATED_METHOD_SLEEP = PhpVersion::PHP_85; - + /** * @see https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_string_which_are_not_one_byte_long_to_ord * @var int