@@ -167,15 +167,16 @@ private function promoteProperties(Tokens $tokens, int $classIndex, ConstructorA
167167 continue ;
168168 }
169169
170- $ tokensToInsert = self ::removePropertyAndReturnTokensToInsert ($ tokens , $ propertyIndex );
170+ [ $ tokensToInsertBefore , $ tokensToInsertAfter ] = self ::removePropertyAndReturnTokensToInsert ($ tokens , $ propertyIndex );
171171
172172 self ::renameVariable ($ tokens , $ constructorAnalysis ->getConstructorIndex (), $ oldParameterName , $ newParameterName );
173173
174174 self ::removeAssignment ($ tokens , $ constructorPromotableAssignments [$ constructorParameterName ]);
175175 $ this ->updateParameterSignature (
176176 $ tokens ,
177177 $ constructorParameterIndex ,
178- $ tokensToInsert ,
178+ $ tokensToInsertBefore ,
179+ $ tokensToInsertAfter ,
179180 \substr ($ propertyType , 0 , 1 ) === '? ' ,
180181 );
181182 }
@@ -316,12 +317,12 @@ private static function getClassProperties(Tokens $tokens, int $classIndex): arr
316317 }
317318
318319 /**
319- * @return list<Token>
320+ * @return array{ list<Token>, list<Token>}
320321 */
321322 private static function removePropertyAndReturnTokensToInsert (Tokens $ tokens , ?int $ propertyIndex ): array
322323 {
323324 if ($ propertyIndex === null ) {
324- return [new Token ([\T_PUBLIC , 'public ' ])];
325+ return [[ new Token ([\T_PUBLIC , 'public ' ])], [] ];
325326 }
326327
327328 $ visibilityIndex = $ tokens ->getPrevTokenOfKind ($ propertyIndex , [[\T_PRIVATE ], [\T_PROTECTED ], [\T_PUBLIC ], [\T_VAR ]]);
@@ -342,21 +343,28 @@ private static function removePropertyAndReturnTokensToInsert(Tokens $tokens, ?i
342343 $ removeFrom ++;
343344 }
344345
345- $ tokensToInsert = [];
346+ $ tokensToInsertBefore = [];
346347 for ($ index = $ removeFrom ; $ index <= $ visibilityIndex - 1 ; $ index ++) {
347- $ tokensToInsert [] = $ tokens [$ index ];
348+ $ tokensToInsertBefore [] = $ tokens [$ index ];
348349 }
349350
350351 $ visibilityToken = $ tokens [$ visibilityIndex ];
351352 if ($ tokens [$ visibilityIndex ]->isGivenKind (\T_VAR )) {
352353 $ visibilityToken = new Token ([\T_PUBLIC , 'public ' ]);
353354 }
354- $ tokensToInsert [] = $ visibilityToken ;
355+ $ tokensToInsertBefore [] = $ visibilityToken ;
356+
357+ $ tokensToInsertAfter = [];
358+ if ($ tokens [$ removeTo ]->isGivenKind (CT ::T_PROPERTY_HOOK_BRACE_CLOSE )) {
359+ for ($ index = $ propertyIndex + 1 ; $ index <= $ removeTo ; $ index ++) {
360+ $ tokensToInsertAfter [] = $ tokens [$ index ];
361+ }
362+ }
355363
356364 $ tokens ->clearRange ($ removeFrom + 1 , $ removeTo );
357365 TokenRemover::removeWithLinesIfPossible ($ tokens , $ removeFrom );
358366
359- return $ tokensToInsert ;
367+ return [ $ tokensToInsertBefore , $ tokensToInsertAfter ] ;
360368 }
361369
362370 /**
@@ -377,6 +385,10 @@ private static function getTokenOfKindSibling(Tokens $tokens, int $direction, in
377385 }
378386 }
379387
388+ if ($ tokens [$ index ]->isGivenKind (CT ::T_PROPERTY_HOOK_BRACE_CLOSE )) {
389+ break ;
390+ }
391+
380392 $ index += $ direction ;
381393 }
382394
@@ -412,31 +424,42 @@ private static function removeAssignment(Tokens $tokens, int $variableAssignment
412424 }
413425
414426 /**
415- * @param list<Token> $tokensToInsert
427+ * @param list<Token> $tokensToInsertBefore
428+ * @param list<Token> $tokensToInsertAfter
416429 */
417- private function updateParameterSignature (Tokens $ tokens , int $ constructorParameterIndex , array $ tokensToInsert , bool $ makeTypeNullable ): void
418- {
430+ private function updateParameterSignature (
431+ Tokens $ tokens ,
432+ int $ constructorParameterIndex ,
433+ array $ tokensToInsertBefore ,
434+ array $ tokensToInsertAfter ,
435+ bool $ makeTypeNullable
436+ ): void {
419437 $ prevElementIndex = $ tokens ->getPrevTokenOfKind ($ constructorParameterIndex , ['( ' , ', ' , [CT ::T_ATTRIBUTE_CLOSE ]]);
420438 \assert (\is_int ($ prevElementIndex ));
421439
422440 $ propertyStartIndex = $ tokens ->getNextMeaningfulToken ($ prevElementIndex );
423441 \assert (\is_int ($ propertyStartIndex ));
424442
425- foreach ($ tokensToInsert as $ index => $ token ) {
443+ foreach ($ tokensToInsertBefore as $ index => $ token ) {
426444 if ($ token ->isGivenKind (\T_PUBLIC )) {
427- $ tokensToInsert [$ index ] = new Token ([CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PUBLIC , $ token ->getContent ()]);
445+ $ tokensToInsertBefore [$ index ] = new Token ([CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PUBLIC , $ token ->getContent ()]);
428446 } elseif ($ token ->isGivenKind (\T_PROTECTED )) {
429- $ tokensToInsert [$ index ] = new Token ([CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PROTECTED , $ token ->getContent ()]);
447+ $ tokensToInsertBefore [$ index ] = new Token ([CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PROTECTED , $ token ->getContent ()]);
430448 } elseif ($ token ->isGivenKind (\T_PRIVATE )) {
431- $ tokensToInsert [$ index ] = new Token ([CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PRIVATE , $ token ->getContent ()]);
449+ $ tokensToInsertBefore [$ index ] = new Token ([CT ::T_CONSTRUCTOR_PROPERTY_PROMOTION_PRIVATE , $ token ->getContent ()]);
432450 }
433451 }
434- $ tokensToInsert [] = new Token ([\T_WHITESPACE , ' ' ]);
452+ $ tokensToInsertBefore [] = new Token ([\T_WHITESPACE , ' ' ]);
435453
436454 if ($ makeTypeNullable && !$ tokens [$ propertyStartIndex ]->isGivenKind (CT ::T_NULLABLE_TYPE )) {
437- $ tokensToInsert [] = new Token ([CT ::T_NULLABLE_TYPE , '? ' ]);
455+ $ tokensToInsertBefore [] = new Token ([CT ::T_NULLABLE_TYPE , '? ' ]);
438456 }
439457
440- $ this ->tokensToInsert [$ propertyStartIndex ] = $ tokensToInsert ;
458+ $ this ->tokensToInsert [$ propertyStartIndex ] = $ tokensToInsertBefore ;
459+
460+ $ nextPropertyStartIndex = $ tokens ->getNextMeaningfulToken ($ propertyStartIndex );
461+ \assert (\is_int ($ nextPropertyStartIndex ));
462+
463+ $ this ->tokensToInsert [$ nextPropertyStartIndex + 1 ] = $ tokensToInsertAfter ;
441464 }
442465}
0 commit comments