@@ -1445,24 +1445,38 @@ public static function isConstructorPromotion(File $phpcsFile, $stackPtr)
14451445
14461446 // If the previous token is a visibility keyword, this is constructor
14471447 // promotion. eg: `public $foobar`.
1448- $ prev = $ phpcsFile ->findPrevious (Tokens::$ emptyTokens , ($ stackPtr - 1 ), $ functionIndex , true );
1449- if (! is_int ($ prev )) {
1448+ $ prevIndex = $ phpcsFile ->findPrevious (Tokens::$ emptyTokens , ($ stackPtr - 1 ), $ functionIndex , true );
1449+ if (! is_int ($ prevIndex )) {
14501450 return false ;
14511451 }
1452- $ prevToken = $ tokens [$ prev ];
1452+ $ prevToken = $ tokens [$ prevIndex ];
14531453 if (in_array ($ prevToken ['code ' ], Tokens::$ scopeModifiers , true )) {
14541454 return true ;
14551455 }
14561456
14571457 // If the previous token is not a visibility keyword, but the one before it
14581458 // is, the previous token was probably a typehint and this is constructor
14591459 // promotion. eg: `public boolean $foobar`.
1460- $ prev = $ phpcsFile ->findPrevious (Tokens::$ emptyTokens , ($ prev - 1 ), $ functionIndex , true );
1461- if (! is_int ($ prev )) {
1460+ $ prev2Index = $ phpcsFile ->findPrevious (Tokens::$ emptyTokens , ($ prevIndex - 1 ), $ functionIndex , true );
1461+ if (! is_int ($ prev2Index )) {
14621462 return false ;
14631463 }
1464- $ prevToken = $ tokens [$ prev ];
1465- if (in_array ($ prevToken ['code ' ], Tokens::$ scopeModifiers , true )) {
1464+ $ prev2Token = $ tokens [$ prev2Index ];
1465+ if (in_array ($ prev2Token ['code ' ], Tokens::$ scopeModifiers , true )) {
1466+ return true ;
1467+ }
1468+
1469+ // If the previous token is not a visibility keyword, but the one two
1470+ // before it is, and one of the tokens is `readonly`, the previous token
1471+ // was probably a typehint and this is constructor promotion. eg: `public
1472+ // readonly boolean $foobar`.
1473+ $ prev3Index = $ phpcsFile ->findPrevious (Tokens::$ emptyTokens , ($ prev2Index - 1 ), $ functionIndex , true );
1474+ if (! is_int ($ prev3Index )) {
1475+ return false ;
1476+ }
1477+ $ prev3Token = $ tokens [$ prev3Index ];
1478+ $ wasPreviousReadonly = $ prevToken ['content ' ] === 'readonly ' || $ prev2Token ['content ' ] === 'readonly ' ;
1479+ if (in_array ($ prev3Token ['code ' ], Tokens::$ scopeModifiers , true ) && $ wasPreviousReadonly ) {
14661480 return true ;
14671481 }
14681482
0 commit comments