From 36dbf7a2b08e40a84d3077a579d34241782ae0c1 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 28 Sep 2025 21:26:13 +0200 Subject: [PATCH 1/3] named args --- .../Fixture/NamedArgs/named_arg.php.inc | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/NamedArgs/named_arg.php.inc diff --git a/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/NamedArgs/named_arg.php.inc b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/NamedArgs/named_arg.php.inc new file mode 100644 index 00000000000..28214e8d5b3 --- /dev/null +++ b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/NamedArgs/named_arg.php.inc @@ -0,0 +1,38 @@ +run(items: ['item1', 'item2']); + } + + private function run(array $items) + { + } +} + +?> +----- +run(items: ['item1', 'item2']); + } + + /** + * @param string[] $items + */ + private function run(array $items) + { + } +} + +?> From 9fd1a99fb393b91ef6bea58f2b3281516b3898ea Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 28 Sep 2025 21:27:15 +0200 Subject: [PATCH 2/3] cover named args in ClassMethodArrayDocblockParamFromLocalCallsRector --- rules/TypeDeclaration/NodeAnalyzer/CallTypesResolver.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/rules/TypeDeclaration/NodeAnalyzer/CallTypesResolver.php b/rules/TypeDeclaration/NodeAnalyzer/CallTypesResolver.php index 751ccaab5cd..3a4a28fb1d7 100644 --- a/rules/TypeDeclaration/NodeAnalyzer/CallTypesResolver.php +++ b/rules/TypeDeclaration/NodeAnalyzer/CallTypesResolver.php @@ -9,7 +9,6 @@ use PhpParser\Node\Expr\Array_; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\StaticCall; -use PhpParser\Node\Identifier; use PhpParser\Node\VariadicPlaceholder; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Type\ArrayType; @@ -67,7 +66,7 @@ public function resolveTypesFromCalls(array $calls): array foreach ($calls as $call) { foreach ($call->args as $position => $arg) { if ($this->shouldSkipArg($arg)) { - return []; + continue; } /** @var Arg $arg */ @@ -206,11 +205,7 @@ private function shouldSkipArg(Arg|VariadicPlaceholder $arg): bool return true; } - if ($arg->unpack) { - return true; - } - - return $arg->name instanceof Identifier; + return $arg->unpack; } private function isEmptyArray(Expr $expr): bool From cb7453bc47499b3b55ac9a172704d653c6a4a9ee Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 28 Sep 2025 21:31:26 +0200 Subject: [PATCH 3/3] add flipped fixture --- .../Fixture/NamedArgs/flipped_args.php.inc | 39 +++++++++++++++++++ .../NodeAnalyzer/CallTypesResolver.php | 11 +++++- ...ArrayDocblockParamFromLocalCallsRector.php | 2 +- 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/NamedArgs/flipped_args.php.inc diff --git a/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/NamedArgs/flipped_args.php.inc b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/NamedArgs/flipped_args.php.inc new file mode 100644 index 00000000000..d4f8d672eea --- /dev/null +++ b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/NamedArgs/flipped_args.php.inc @@ -0,0 +1,39 @@ +run(names: ['John', 'Doe'], items: [123, 456]); + } + + private function run(array $items, array $names) + { + } +} + +?> +----- +run(names: ['John', 'Doe'], items: [123, 456]); + } + + /** + * @param int[] $items + * @param string[] $names + */ + private function run(array $items, array $names) + { + } +} + +?> diff --git a/rules/TypeDeclaration/NodeAnalyzer/CallTypesResolver.php b/rules/TypeDeclaration/NodeAnalyzer/CallTypesResolver.php index 3a4a28fb1d7..d8a120838c0 100644 --- a/rules/TypeDeclaration/NodeAnalyzer/CallTypesResolver.php +++ b/rules/TypeDeclaration/NodeAnalyzer/CallTypesResolver.php @@ -9,6 +9,7 @@ use PhpParser\Node\Expr\Array_; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\StaticCall; +use PhpParser\Node\Identifier; use PhpParser\Node\VariadicPlaceholder; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Type\ArrayType; @@ -57,7 +58,7 @@ public function resolveStrictTypesFromCalls(array $calls): array /** * @param MethodCall[]|StaticCall[] $calls - * @return array + * @return array */ public function resolveTypesFromCalls(array $calls): array { @@ -75,7 +76,13 @@ public function resolveTypesFromCalls(array $calls): array continue; } - $staticTypesByArgumentPosition[$position][] = $this->resolveArgValueType($arg); + if ($arg->name instanceof Identifier) { + $positionOrName = $arg->name->toString(); + } else { + $positionOrName = $position; + } + + $staticTypesByArgumentPosition[$positionOrName][] = $this->resolveArgValueType($arg); } } diff --git a/rules/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector.php b/rules/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector.php index 301ebdbf5f9..36408389a68 100644 --- a/rules/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector.php +++ b/rules/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector.php @@ -107,7 +107,7 @@ public function refactor(Node $node): ?Node continue; } - $resolvedParameterType = $classMethodParameterTypes[$parameterPosition] ?? null; + $resolvedParameterType = $classMethodParameterTypes[$parameterPosition] ?? $classMethodParameterTypes[$parameterName] ?? null; if (! $resolvedParameterType instanceof Type) { continue; }