@@ -1446,15 +1446,11 @@ protected function tokenize($string)
14461446 && strpos ($ token [1 ], '#[ ' ) === 0
14471447 ) {
14481448 $ subTokens = $ this ->parsePhpAttribute ($ tokens , $ stackPtr );
1449- if ($ subTokens !== null ) {
1450- array_splice ($ tokens , $ stackPtr , 1 , $ subTokens );
1451- $ numTokens = count ($ tokens );
1449+ array_splice ($ tokens , $ stackPtr , 1 , $ subTokens );
1450+ $ numTokens = count ($ tokens );
14521451
1453- $ tokenIsArray = true ;
1454- $ token = $ tokens [$ stackPtr ];
1455- } else {
1456- $ token [0 ] = T_ATTRIBUTE ;
1457- }
1452+ $ tokenIsArray = true ;
1453+ $ token = $ tokens [$ stackPtr ];
14581454 }
14591455
14601456 if ($ tokenIsArray === true
@@ -4105,11 +4101,10 @@ private function findCloser(array &$tokens, $start, $openerTokens, $closerChar)
41054101 * @param array $tokens The original array of tokens (as returned by token_get_all).
41064102 * @param int $stackPtr The current position in token array.
41074103 *
4108- * @return array|null The array of parsed attribute tokens
4104+ * @return array The array of parsed attribute tokens
41094105 */
41104106 private function parsePhpAttribute (array &$ tokens , $ stackPtr )
41114107 {
4112-
41134108 $ token = $ tokens [$ stackPtr ];
41144109
41154110 $ commentBody = substr ($ token [1 ], 2 );
@@ -4121,18 +4116,24 @@ private function parsePhpAttribute(array &$tokens, $stackPtr)
41214116 && strpos ($ subToken [1 ], '#[ ' ) === 0
41224117 ) {
41234118 $ reparsed = $ this ->parsePhpAttribute ($ subTokens , $ i );
4124- if ($ reparsed !== null ) {
4125- array_splice ($ subTokens , $ i , 1 , $ reparsed );
4126- } else {
4127- $ subToken [0 ] = T_ATTRIBUTE ;
4128- }
4119+ array_splice ($ subTokens , $ i , 1 , $ reparsed );
41294120 }
41304121 }
41314122
41324123 array_splice ($ subTokens , 0 , 1 , [[T_ATTRIBUTE , '#[ ' ]]);
41334124
41344125 // Go looking for the close bracket.
41354126 $ bracketCloser = $ this ->findCloser ($ subTokens , 1 , '[ ' , '] ' );
4127+
4128+ /*
4129+ * No closer bracket found, this might be a multi-line attribute,
4130+ * but it could also be an unfinished attribute (parse error).
4131+ *
4132+ * If it is a multi-line attribute, we need to grab a larger part of the code.
4133+ * If it is a parse error, we need to stick with only handling the line
4134+ * containing the attribute opener.
4135+ */
4136+
41364137 if (PHP_VERSION_ID < 80000 && $ bracketCloser === null ) {
41374138 foreach (array_slice ($ tokens , ($ stackPtr + 1 )) as $ token ) {
41384139 if (is_array ($ token ) === true ) {
@@ -4142,20 +4143,17 @@ private function parsePhpAttribute(array &$tokens, $stackPtr)
41424143 }
41434144 }
41444145
4145- $ subTokens = @token_get_all ('<?php ' .$ commentBody );
4146- array_splice ($ subTokens , 0 , 1 , [[T_ATTRIBUTE , '#[ ' ]]);
4146+ $ newSubTokens = @token_get_all ('<?php ' .$ commentBody );
4147+ array_splice ($ newSubTokens , 0 , 1 , [[T_ATTRIBUTE , '#[ ' ]]);
41474148
4148- $ bracketCloser = $ this ->findCloser ($ subTokens , 1 , '[ ' , '] ' );
4149+ $ bracketCloser = $ this ->findCloser ($ newSubTokens , 1 , '[ ' , '] ' );
41494150 if ($ bracketCloser !== null ) {
4150- array_splice ($ tokens , ($ stackPtr + 1 ), count ($ tokens ), array_slice ($ subTokens , ($ bracketCloser + 1 )));
4151- $ subTokens = array_slice ($ subTokens , 0 , ($ bracketCloser + 1 ));
4151+ // We found the closer, overwrite the original $subTokens array.
4152+ array_splice ($ tokens , ($ stackPtr + 1 ), count ($ tokens ), array_slice ($ newSubTokens , ($ bracketCloser + 1 )));
4153+ $ subTokens = array_slice ($ newSubTokens , 0 , ($ bracketCloser + 1 ));
41524154 }
41534155 }
41544156
4155- if ($ bracketCloser === null ) {
4156- return null ;
4157- }
4158-
41594157 return $ subTokens ;
41604158
41614159 }//end parsePhpAttribute()
0 commit comments