@@ -35,11 +35,6 @@ final class CommandConfigureToAttributeRector extends AbstractRector implements
35
35
* @var \Rector\PhpAttribute\NodeFactory\PhpAttributeGroupFactory
36
36
*/
37
37
private $ phpAttributeGroupFactory ;
38
- /**
39
- * @readonly
40
- * @var \Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer
41
- */
42
- private $ phpAttributeAnalyzer ;
43
38
/**
44
39
* @readonly
45
40
* @var \PHPStan\Reflection\ReflectionProvider
@@ -49,10 +44,9 @@ final class CommandConfigureToAttributeRector extends AbstractRector implements
49
44
* @var array<string, string>
50
45
*/
51
46
private const METHODS_TO_ATTRIBUTE_NAMES = ['setName ' => 'name ' , 'setDescription ' => 'description ' , 'setAliases ' => 'aliases ' , 'setHidden ' => 'hidden ' ];
52
- public function __construct (PhpAttributeGroupFactory $ phpAttributeGroupFactory , PhpAttributeAnalyzer $ phpAttributeAnalyzer , ReflectionProvider $ reflectionProvider )
47
+ public function __construct (PhpAttributeGroupFactory $ phpAttributeGroupFactory , ReflectionProvider $ reflectionProvider )
53
48
{
54
49
$ this ->phpAttributeGroupFactory = $ phpAttributeGroupFactory ;
55
- $ this ->phpAttributeAnalyzer = $ phpAttributeAnalyzer ;
56
50
$ this ->reflectionProvider = $ reflectionProvider ;
57
51
}
58
52
public function provideMinPhpVersion () : int
@@ -103,30 +97,47 @@ public function refactor(Node $node) : ?Node
103
97
if (!$ this ->reflectionProvider ->hasClass (SymfonyAnnotation::AS_COMMAND )) {
104
98
return null ;
105
99
}
106
- // already converted
107
- if ($ this ->phpAttributeAnalyzer ->hasPhpAttribute ($ node , SymfonyAnnotation::AS_COMMAND )) {
108
- return null ;
109
- }
110
100
$ configureClassMethod = $ node ->getMethod ('configure ' );
111
101
if (!$ configureClassMethod instanceof ClassMethod) {
112
102
return null ;
113
103
}
114
- $ asCommandAttribute = $ this ->phpAttributeGroupFactory ->createFromClass (SymfonyAnnotation::AS_COMMAND );
104
+ // handle existing attribute
105
+ $ asCommandAttribute = null ;
115
106
$ attributeArgs = [];
107
+ foreach ($ node ->attrGroups as $ attrGroup ) {
108
+ foreach ($ attrGroup ->attrs as $ attribute ) {
109
+ if (!$ this ->nodeNameResolver ->isName ($ attribute ->name , SymfonyAnnotation::AS_COMMAND )) {
110
+ continue ;
111
+ }
112
+ $ asCommandAttribute = $ attribute ;
113
+ foreach ($ asCommandAttribute ->args as $ arg ) {
114
+ if ($ arg ->name === null ) {
115
+ // when the existing attribute does not use named arguments, we cannot upgrade
116
+ return null ;
117
+ }
118
+ $ attributeArgs [$ arg ->name ->toString ()] = $ arg ;
119
+ }
120
+ break 2 ;
121
+ }
122
+ }
123
+ if ($ asCommandAttribute === null ) {
124
+ $ asCommandAttributeGroup = $ this ->phpAttributeGroupFactory ->createFromClass (SymfonyAnnotation::AS_COMMAND );
125
+ $ asCommandAttribute = $ asCommandAttributeGroup ->attrs [0 ];
126
+ $ node ->attrGroups [] = $ asCommandAttributeGroup ;
127
+ }
116
128
foreach (self ::METHODS_TO_ATTRIBUTE_NAMES as $ methodName => $ attributeName ) {
117
129
$ resolvedExpr = $ this ->findAndRemoveMethodExpr ($ configureClassMethod , $ methodName );
118
130
if ($ resolvedExpr instanceof Expr) {
119
- $ attributeArgs [] = $ this ->createNamedArg ($ attributeName , $ resolvedExpr );
131
+ $ attributeArgs [$ attributeName ] = $ this ->createNamedArg ($ attributeName , $ resolvedExpr );
120
132
}
121
133
}
122
- $ asCommandAttribute ->attrs [ 0 ]-> args = $ attributeArgs ;
134
+ $ asCommandAttribute ->args = $ attributeArgs ;
123
135
// remove left overs
124
136
foreach ((array ) $ configureClassMethod ->stmts as $ key => $ stmt ) {
125
137
if ($ this ->isExpressionVariableThis ($ stmt )) {
126
138
unset($ configureClassMethod ->stmts [$ key ]);
127
139
}
128
140
}
129
- $ node ->attrGroups [] = $ asCommandAttribute ;
130
141
return $ node ;
131
142
}
132
143
private function createNamedArg (string $ name , Expr $ expr ) : Arg
0 commit comments