From 3fa22e20ba8e08e49dd40d1e64ed5f317d968197 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sat, 29 Nov 2025 11:52:01 +0100 Subject: [PATCH 1/2] Support Attribute in SortNamedParam --- .../Fixture/attribute.php.inc | 39 +++++++++++++++++++ .../Rector/FuncCall/SortNamedParamRector.php | 16 ++++++-- src/Reflection/ReflectionResolver.php | 14 +++++++ 3 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 rules-tests/CodeQuality/Rector/FuncCall/SortNamedParamRector/Fixture/attribute.php.inc diff --git a/rules-tests/CodeQuality/Rector/FuncCall/SortNamedParamRector/Fixture/attribute.php.inc b/rules-tests/CodeQuality/Rector/FuncCall/SortNamedParamRector/Fixture/attribute.php.inc new file mode 100644 index 00000000000..f7657cef7a3 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/FuncCall/SortNamedParamRector/Fixture/attribute.php.inc @@ -0,0 +1,39 @@ + +----- + diff --git a/rules/CodeQuality/Rector/FuncCall/SortNamedParamRector.php b/rules/CodeQuality/Rector/FuncCall/SortNamedParamRector.php index 06fe8f49b08..88fce6182b2 100644 --- a/rules/CodeQuality/Rector/FuncCall/SortNamedParamRector.php +++ b/rules/CodeQuality/Rector/FuncCall/SortNamedParamRector.php @@ -6,6 +6,8 @@ use PhpParser\Node; use PhpParser\Node\Arg; +use PhpParser\Node\Attribute; +use PhpParser\Node\Expr\CallLike; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\New_; @@ -62,19 +64,23 @@ function run($foo = null, $bar = null, $baz = null) {} */ public function getNodeTypes(): array { - return [MethodCall::class, StaticCall::class, New_::class, FuncCall::class]; + return [MethodCall::class, StaticCall::class, New_::class, FuncCall::class, Attribute::class]; } /** - * @param MethodCall|StaticCall|New_|FuncCall $node + * @param MethodCall|StaticCall|New_|FuncCall|Attribute $node */ public function refactor(Node $node): ?Node { - if ($node->isFirstClassCallable()) { + if ($node instanceof CallLike && $node->isFirstClassCallable()) { return null; } - $args = $node->getArgs(); + if ($node instanceof Attribute) { + $args = $node->args; + } else { + $args = $node->getArgs(); + } if (count($args) <= 1) { return null; } @@ -85,6 +91,8 @@ public function refactor(Node $node): ?Node if ($node instanceof New_) { $functionLikeReflection = $this->reflectionResolver->resolveMethodReflectionFromNew($node); + } elseif ($node instanceof Attribute) { + $functionLikeReflection = $this->reflectionResolver->resolveMethodReflectionFromAttribute($node); } else { $functionLikeReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node); } diff --git a/src/Reflection/ReflectionResolver.php b/src/Reflection/ReflectionResolver.php index 453511af953..04f47384b53 100644 --- a/src/Reflection/ReflectionResolver.php +++ b/src/Reflection/ReflectionResolver.php @@ -5,6 +5,7 @@ namespace Rector\Reflection; use PhpParser\Node; +use PhpParser\Node\Attribute; use PhpParser\Node\Expr\CallLike; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\MethodCall; @@ -256,6 +257,19 @@ public function resolveMethodReflectionFromNew(New_ $new): ?MethodReflection return $this->resolveMethodReflection($className, MethodName::CONSTRUCT, $scope); } + public function resolveMethodReflectionFromAttribute(Attribute $attribute): ?MethodReflection + { + $attributeClassType = $this->nodeTypeResolver->getType($attribute->name); + $className = ClassNameFromObjectTypeResolver::resolve($attributeClassType); + + if ($className === null) { + return null; + } + + $scope = $attribute->getAttribute(AttributeKey::SCOPE); + return $this->resolveMethodReflection($className, MethodName::CONSTRUCT, $scope); + } + public function resolvePropertyReflectionFromPropertyFetch( PropertyFetch | StaticPropertyFetch $propertyFetch ): ?PhpPropertyReflection { From 44fd73f8aaca2bb65779879eb7b749b116558933 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sat, 29 Nov 2025 12:14:26 +0100 Subject: [PATCH 2/2] Move to source folder --- .../Fixture/attribute.php.inc | 16 ++-------------- .../SortNamedParamRector/Source/MyAttribute.php | 11 +++++++++++ 2 files changed, 13 insertions(+), 14 deletions(-) create mode 100644 rules-tests/CodeQuality/Rector/FuncCall/SortNamedParamRector/Source/MyAttribute.php diff --git a/rules-tests/CodeQuality/Rector/FuncCall/SortNamedParamRector/Fixture/attribute.php.inc b/rules-tests/CodeQuality/Rector/FuncCall/SortNamedParamRector/Fixture/attribute.php.inc index f7657cef7a3..924133c1dce 100644 --- a/rules-tests/CodeQuality/Rector/FuncCall/SortNamedParamRector/Fixture/attribute.php.inc +++ b/rules-tests/CodeQuality/Rector/FuncCall/SortNamedParamRector/Fixture/attribute.php.inc @@ -2,13 +2,7 @@ namespace Rector\Tests\CodeQuality\Rector\FuncCall\SortNamedParamRector\Fixture; -#[\Attribute] -class MyAttribute -{ - public function __construct($foo = null, $bar = null, $baz = null) - { - } -} +use Rector\Tests\CodeQuality\Rector\FuncCall\SortNamedParamRector\Source\MyAttribute; #[MyAttribute(bar: 1, foo: 2)] #[MyAttribute(1, baz: 2, bar: 3)] @@ -22,13 +16,7 @@ class Test namespace Rector\Tests\CodeQuality\Rector\FuncCall\SortNamedParamRector\Fixture; -#[\Attribute] -class MyAttribute -{ - public function __construct($foo = null, $bar = null, $baz = null) - { - } -} +use Rector\Tests\CodeQuality\Rector\FuncCall\SortNamedParamRector\Source\MyAttribute; #[MyAttribute(foo: 2, bar: 1)] #[MyAttribute(1, bar: 3, baz: 2)] diff --git a/rules-tests/CodeQuality/Rector/FuncCall/SortNamedParamRector/Source/MyAttribute.php b/rules-tests/CodeQuality/Rector/FuncCall/SortNamedParamRector/Source/MyAttribute.php new file mode 100644 index 00000000000..e700fab0922 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/FuncCall/SortNamedParamRector/Source/MyAttribute.php @@ -0,0 +1,11 @@ +