@@ -2283,27 +2283,103 @@ public function findNext(
22832283 */
22842284 public function findStartOfStatement ($ start , $ ignore =null )
22852285 {
2286- $ endTokens = Util \Tokens::$ blockOpeners ;
2286+ $ startTokens = Util \Tokens::$ blockOpeners ;
2287+ $ startTokens [T_OPEN_SHORT_ARRAY ] = true ;
2288+ $ startTokens [T_OPEN_TAG ] = true ;
22872289
2288- $ endTokens [T_COLON ] = true ;
2289- $ endTokens [T_COMMA ] = true ;
2290- $ endTokens [T_DOUBLE_ARROW ] = true ;
2291- $ endTokens [T_SEMICOLON ] = true ;
2292- $ endTokens [T_OPEN_TAG ] = true ;
2293- $ endTokens [T_CLOSE_TAG ] = true ;
2294- $ endTokens [T_OPEN_SHORT_ARRAY ] = true ;
2290+ $ endTokens = [
2291+ T_CLOSE_TAG => true ,
2292+ T_COLON => true ,
2293+ T_COMMA => true ,
2294+ T_DOUBLE_ARROW => true ,
2295+ T_MATCH_ARROW => true ,
2296+ T_SEMICOLON => true ,
2297+ ];
22952298
22962299 if ($ ignore !== null ) {
22972300 $ ignore = (array ) $ ignore ;
22982301 foreach ($ ignore as $ code ) {
2299- unset($ endTokens [$ code ]);
2302+ if (isset ($ startTokens [$ code ]) === true ) {
2303+ unset($ startTokens [$ code ]);
2304+ }
2305+
2306+ if (isset ($ endTokens [$ code ]) === true ) {
2307+ unset($ endTokens [$ code ]);
2308+ }
23002309 }
23012310 }
23022311
2312+ // If the start token is inside the case part of a match expression,
2313+ // find the start of the condition. If it's in the statement part, find
2314+ // the token that comes after the match arrow.
2315+ $ matchExpression = $ this ->getCondition ($ start , T_MATCH );
2316+ if ($ matchExpression !== false ) {
2317+ for ($ prevMatch = $ start ; $ prevMatch > $ this ->tokens [$ matchExpression ]['scope_opener ' ]; $ prevMatch --) {
2318+ if ($ prevMatch !== $ start
2319+ && ($ this ->tokens [$ prevMatch ]['code ' ] === T_MATCH_ARROW
2320+ || $ this ->tokens [$ prevMatch ]['code ' ] === T_COMMA )
2321+ ) {
2322+ break ;
2323+ }
2324+
2325+ // Skip nested statements.
2326+ if (isset ($ this ->tokens [$ prevMatch ]['bracket_opener ' ]) === true
2327+ && $ prevMatch === $ this ->tokens [$ prevMatch ]['bracket_closer ' ]
2328+ ) {
2329+ $ prevMatch = $ this ->tokens [$ prevMatch ]['bracket_opener ' ];
2330+ } else if (isset ($ this ->tokens [$ prevMatch ]['parenthesis_opener ' ]) === true
2331+ && $ prevMatch === $ this ->tokens [$ prevMatch ]['parenthesis_closer ' ]
2332+ ) {
2333+ $ prevMatch = $ this ->tokens [$ prevMatch ]['parenthesis_opener ' ];
2334+ }
2335+ }
2336+
2337+ if ($ prevMatch <= $ this ->tokens [$ matchExpression ]['scope_opener ' ]) {
2338+ // We're before the arrow in the first case.
2339+ $ next = $ this ->findNext (Util \Tokens::$ emptyTokens , ($ this ->tokens [$ matchExpression ]['scope_opener ' ] + 1 ), null , true );
2340+ if ($ next === false ) {
2341+ return $ start ;
2342+ }
2343+
2344+ return $ next ;
2345+ }
2346+
2347+ if ($ this ->tokens [$ prevMatch ]['code ' ] === T_COMMA ) {
2348+ // We're before the arrow, but not in the first case.
2349+ $ prevMatchArrow = $ this ->findPrevious (T_MATCH_ARROW , ($ prevMatch - 1 ), $ this ->tokens [$ matchExpression ]['scope_opener ' ]);
2350+ if ($ prevMatchArrow === false ) {
2351+ // We're before the arrow in the first case.
2352+ $ next = $ this ->findNext (Util \Tokens::$ emptyTokens , ($ this ->tokens [$ matchExpression ]['scope_opener ' ] + 1 ), null , true );
2353+ return $ next ;
2354+ }
2355+
2356+ $ nextComma = $ this ->findNext (T_COMMA , ($ prevMatchArrow + 1 ));
2357+ $ next = $ this ->findNext (Util \Tokens::$ emptyTokens , ($ nextComma + 1 ), null , true );
2358+ return $ next ;
2359+ }
2360+ }//end if
2361+
23032362 $ lastNotEmpty = $ start ;
23042363
2364+ // If we are starting at a token that ends a scope block, skip to
2365+ // the start and continue from there.
2366+ // If we are starting at a token that ends a statement, skip this
2367+ // token so we find the true start of the statement.
2368+ while (isset ($ endTokens [$ this ->tokens [$ start ]['code ' ]]) === true
2369+ || (isset ($ this ->tokens [$ start ]['scope_condition ' ]) === true
2370+ && $ start === $ this ->tokens [$ start ]['scope_closer ' ])
2371+ ) {
2372+ if (isset ($ this ->tokens [$ start ]['scope_condition ' ]) === true ) {
2373+ $ start = $ this ->tokens [$ start ]['scope_condition ' ];
2374+ } else {
2375+ $ start --;
2376+ }
2377+ }
2378+
23052379 for ($ i = $ start ; $ i >= 0 ; $ i --) {
2306- if (isset ($ endTokens [$ this ->tokens [$ i ]['code ' ]]) === true ) {
2380+ if (isset ($ startTokens [$ this ->tokens [$ i ]['code ' ]]) === true
2381+ || isset ($ endTokens [$ this ->tokens [$ i ]['code ' ]]) === true
2382+ ) {
23072383 // Found the end of the previous statement.
23082384 return $ lastNotEmpty ;
23092385 }
@@ -2332,7 +2408,12 @@ public function findStartOfStatement($start, $ignore=null)
23322408 && $ i === $ this ->tokens [$ i ]['parenthesis_closer ' ]
23332409 ) {
23342410 $ i = $ this ->tokens [$ i ]['parenthesis_opener ' ];
2335- }
2411+ } else if ($ this ->tokens [$ i ]['code ' ] === T_CLOSE_USE_GROUP ) {
2412+ $ start = $ this ->findPrevious (T_OPEN_USE_GROUP , ($ i - 1 ));
2413+ if ($ start !== false ) {
2414+ $ i = $ start ;
2415+ }
2416+ }//end if
23362417
23372418 if (isset (Util \Tokens::$ emptyTokens [$ this ->tokens [$ i ]['code ' ]]) === false ) {
23382419 $ lastNotEmpty = $ i ;
@@ -2374,6 +2455,31 @@ public function findEndOfStatement($start, $ignore=null)
23742455 }
23752456 }
23762457
2458+ // If the start token is inside the case part of a match expression,
2459+ // advance to the match arrow and continue looking for the
2460+ // end of the statement from there so that we skip over commas.
2461+ $ matchExpression = $ this ->getCondition ($ start , T_MATCH );
2462+ if ($ matchExpression !== false ) {
2463+ $ beforeArrow = true ;
2464+ $ prevMatchArrow = $ this ->findPrevious (T_MATCH_ARROW , ($ start - 1 ), $ this ->tokens [$ matchExpression ]['scope_opener ' ]);
2465+ if ($ prevMatchArrow !== false ) {
2466+ $ prevComma = $ this ->findNext (T_COMMA , ($ prevMatchArrow + 1 ), $ start );
2467+ if ($ prevComma === false ) {
2468+ // No comma between this token and the last match arrow,
2469+ // so this token exists after the arrow and we can continue
2470+ // checking as normal.
2471+ $ beforeArrow = false ;
2472+ }
2473+ }
2474+
2475+ if ($ beforeArrow === true ) {
2476+ $ nextMatchArrow = $ this ->findNext (T_MATCH_ARROW , ($ start + 1 ), $ this ->tokens [$ matchExpression ]['scope_closer ' ]);
2477+ if ($ nextMatchArrow !== false ) {
2478+ $ start = $ nextMatchArrow ;
2479+ }
2480+ }
2481+ }//end if
2482+
23772483 $ lastNotEmpty = $ start ;
23782484 for ($ i = $ start ; $ i < $ this ->numTokens ; $ i ++) {
23792485 if ($ i !== $ start && isset ($ endTokens [$ this ->tokens [$ i ]['code ' ]]) === true ) {
0 commit comments