2222
2323final class ReadonlyPromotedPropertiesFixer extends AbstractFixer
2424{
25+ /** @var list<int> */
26+ private array $ promotedPropertyVisibilityKinds ;
27+
28+ public function __construct ()
29+ {
30+ $ this ->promotedPropertyVisibilityKinds = [
31+ CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PRIVATE ,
32+ CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PROTECTED ,
33+ CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PUBLIC ,
34+ ];
35+ if (\defined ('T_PUBLIC_SET ' )) {
36+ $ this ->promotedPropertyVisibilityKinds [] = \T_PUBLIC_SET ;
37+ $ this ->promotedPropertyVisibilityKinds [] = \T_PROTECTED_SET ;
38+ $ this ->promotedPropertyVisibilityKinds [] = \T_PRIVATE_SET ;
39+ }
40+ }
41+
2542 public function getDefinition (): FixerDefinitionInterface
2643 {
2744 return new FixerDefinition (
@@ -53,11 +70,7 @@ public function getPriority(): int
5370
5471 public function isCandidate (Tokens $ tokens ): bool
5572 {
56- return \defined ('T_READONLY ' ) && $ tokens ->isAnyTokenKindsFound ([
57- CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PRIVATE ,
58- CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PROTECTED ,
59- CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PUBLIC ,
60- ]);
73+ return \defined ('T_READONLY ' ) && $ tokens ->isAnyTokenKindsFound ($ this ->promotedPropertyVisibilityKinds );
6174 }
6275
6376 public function isRisky (): bool
@@ -83,6 +96,8 @@ public function fix(\SplFileInfo $file, Tokens $tokens): void
8396 continue ;
8497 }
8598
99+ $ constructorNameIndex = $ tokens ->getNextMeaningfulToken ($ constructorAnalysis ->getConstructorIndex ());
100+
86101 $ classOpenBraceIndex = $ tokens ->getNextTokenOfKind ($ index , ['{ ' ]);
87102 \assert (\is_int ($ classOpenBraceIndex ));
88103 $ classCloseBraceIndex = $ tokens ->findBlockEnd (Tokens::BLOCK_TYPE_CURLY_BRACE , $ classOpenBraceIndex );
@@ -119,34 +134,20 @@ private function fixParameters(
119134 int $ constructorCloseParenthesisIndex
120135 ): void {
121136 for ($ index = $ constructorCloseParenthesisIndex ; $ index > $ constructorOpenParenthesisIndex ; $ index --) {
122- if (
123- !$ tokens [$ index ]->isGivenKind ([
124- CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PRIVATE ,
125- CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PROTECTED ,
126- CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PUBLIC ,
127- ])
128- ) {
129- continue ;
130- }
131-
132- $ nextIndex = $ tokens ->getNextMeaningfulToken ($ index );
133- if ($ tokens [$ nextIndex ]->isGivenKind (\T_READONLY )) {
137+ if (!$ tokens [$ index ]->isGivenKind (\T_VARIABLE )) {
134138 continue ;
135139 }
136140
137- $ prevIndex = $ tokens -> getPrevMeaningfulToken ( $ index );
138- if ($ tokens [ $ prevIndex ]-> isGivenKind (\ T_READONLY ) ) {
141+ $ insertIndex = $ this -> getInsertIndex ( $ tokens , $ index );
142+ if ($ insertIndex === null ) {
139143 continue ;
140144 }
141145
142- $ propertyIndex = $ tokens ->getNextTokenOfKind ($ index , [[\T_VARIABLE ]]);
143- \assert (\is_int ($ propertyIndex ));
144-
145146 $ propertyAssignment = $ tokens ->findSequence (
146147 [
147148 [\T_VARIABLE , '$this ' ],
148149 [\T_OBJECT_OPERATOR ],
149- [\T_STRING , \substr ($ tokens [$ propertyIndex ]->getContent (), 1 )],
150+ [\T_STRING , \substr ($ tokens [$ index ]->getContent (), 1 )],
150151 ],
151152 $ classOpenBraceIndex ,
152153 $ classCloseBraceIndex ,
@@ -156,12 +157,32 @@ private function fixParameters(
156157 }
157158
158159 $ tokens ->insertAt (
159- $ index + 1 ,
160+ $ insertIndex + 1 ,
160161 [
161162 new Token ([\T_WHITESPACE , ' ' ]),
162163 new Token ([\T_READONLY , 'readonly ' ]),
163164 ],
164165 );
165166 }
166167 }
168+
169+ private function getInsertIndex (Tokens $ tokens , int $ index ): ?int
170+ {
171+ $ insertIndex = null ;
172+
173+ $ index = $ tokens ->getPrevMeaningfulToken ($ index );
174+ \assert (\is_int ($ index ));
175+ while (!$ tokens [$ index ]->equalsAny ([', ' , '( ' ])) {
176+ $ index = $ tokens ->getPrevMeaningfulToken ($ index );
177+ \assert (\is_int ($ index ));
178+ if ($ tokens [$ index ]->isGivenKind (\T_READONLY )) {
179+ return null ;
180+ }
181+ if ($ insertIndex === null && $ tokens [$ index ]->isGivenKind ($ this ->promotedPropertyVisibilityKinds )) {
182+ $ insertIndex = $ index ;
183+ }
184+ }
185+
186+ return $ insertIndex ;
187+ }
167188}
0 commit comments