@@ -53,11 +53,7 @@ public function getPriority(): int
5353
5454 public function isCandidate (Tokens $ tokens ): bool
5555 {
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- ]);
56+ return \defined ('T_READONLY ' ) && $ tokens ->isAnyTokenKindsFound (self ::getPromotedPropertyVisibilityKinds ());
6157 }
6258
6359 public function isRisky (): bool
@@ -83,6 +79,8 @@ public function fix(\SplFileInfo $file, Tokens $tokens): void
8379 continue ;
8480 }
8581
82+ $ constructorNameIndex = $ tokens ->getNextMeaningfulToken ($ constructorAnalysis ->getConstructorIndex ());
83+
8684 $ classOpenBraceIndex = $ tokens ->getNextTokenOfKind ($ index , ['{ ' ]);
8785 \assert (\is_int ($ classOpenBraceIndex ));
8886 $ classCloseBraceIndex = $ tokens ->findBlockEnd (Tokens::BLOCK_TYPE_CURLY_BRACE , $ classOpenBraceIndex );
@@ -119,34 +117,20 @@ private function fixParameters(
119117 int $ constructorCloseParenthesisIndex
120118 ): void {
121119 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 )) {
120+ if (!$ tokens [$ index ]->isGivenKind (\T_VARIABLE )) {
134121 continue ;
135122 }
136123
137- $ prevIndex = $ tokens-> getPrevMeaningfulToken ( $ index );
138- if ($ tokens [ $ prevIndex ]-> isGivenKind (\ T_READONLY ) ) {
124+ $ insertIndex = self :: getInsertIndex ( $ tokens, $ index );
125+ if ($ insertIndex === null ) {
139126 continue ;
140127 }
141128
142- $ propertyIndex = $ tokens ->getNextTokenOfKind ($ index , [[\T_VARIABLE ]]);
143- \assert (\is_int ($ propertyIndex ));
144-
145129 $ propertyAssignment = $ tokens ->findSequence (
146130 [
147131 [\T_VARIABLE , '$this ' ],
148132 [\T_OBJECT_OPERATOR ],
149- [\T_STRING , \substr ($ tokens [$ propertyIndex ]->getContent (), 1 )],
133+ [\T_STRING , \substr ($ tokens [$ index ]->getContent (), 1 )],
150134 ],
151135 $ classOpenBraceIndex ,
152136 $ classCloseBraceIndex ,
@@ -156,12 +140,56 @@ private function fixParameters(
156140 }
157141
158142 $ tokens ->insertAt (
159- $ index + 1 ,
143+ $ insertIndex + 1 ,
160144 [
161145 new Token ([\T_WHITESPACE , ' ' ]),
162146 new Token ([\T_READONLY , 'readonly ' ]),
163147 ],
164148 );
165149 }
166150 }
151+
152+ private static function getInsertIndex (Tokens $ tokens , int $ index ): ?int
153+ {
154+ $ insertIndex = null ;
155+
156+ $ index = $ tokens ->getPrevMeaningfulToken ($ index );
157+ \assert (\is_int ($ index ));
158+ while (!$ tokens [$ index ]->equalsAny ([', ' , '( ' ])) {
159+ $ index = $ tokens ->getPrevMeaningfulToken ($ index );
160+ \assert (\is_int ($ index ));
161+ if ($ tokens [$ index ]->isGivenKind (\T_READONLY )) {
162+ return null ;
163+ }
164+ if ($ insertIndex === null && $ tokens [$ index ]->isGivenKind (self ::getPromotedPropertyVisibilityKinds ())) {
165+ $ insertIndex = $ index ;
166+ }
167+ }
168+
169+ return $ insertIndex ;
170+ }
171+
172+ /**
173+ * @return list<int>
174+ */
175+ private static function getPromotedPropertyVisibilityKinds (): array
176+ {
177+ /** @var null|list<int> $promotedPropertyVisibilityKinds */
178+ static $ promotedPropertyVisibilityKinds = null ;
179+
180+ if ($ promotedPropertyVisibilityKinds === null ) {
181+ $ promotedPropertyVisibilityKinds = [
182+ CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PRIVATE ,
183+ CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PROTECTED ,
184+ CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PUBLIC ,
185+ ];
186+ if (\defined ('T_PUBLIC_SET ' )) {
187+ $ promotedPropertyVisibilityKinds [] = \T_PUBLIC_SET ;
188+ $ promotedPropertyVisibilityKinds [] = \T_PROTECTED_SET ;
189+ $ promotedPropertyVisibilityKinds [] = \T_PRIVATE_SET ;
190+ }
191+ }
192+
193+ return $ promotedPropertyVisibilityKinds ;
194+ }
167195}
0 commit comments