@@ -229,118 +229,127 @@ private function findNextCase($phpcsFile, $stackPtr, $end)
229
229
230
230
231
231
/**
232
- * Returns true if a nested terminating statement is found.
232
+ * Returns the position of the nested terminating statement.
233
+ *
234
+ * Returns false if no terminating statement was found.
233
235
*
234
236
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
235
237
* @param int $stackPtr The position to start looking at.
236
238
* @param int $end The position to stop looking at.
237
239
*
238
- * @return bool
240
+ * @return int|false
239
241
*/
240
242
private function findNestedTerminator ($ phpcsFile , $ stackPtr , $ end )
241
243
{
242
- $ tokens = $ phpcsFile ->getTokens ();
243
- $ terminators = [
244
- T_RETURN ,
245
- T_BREAK ,
246
- T_CONTINUE ,
247
- T_THROW ,
248
- T_EXIT ,
249
- ];
244
+ $ tokens = $ phpcsFile ->getTokens ();
250
245
251
246
$ lastToken = $ phpcsFile ->findPrevious (T_WHITESPACE , ($ end - 1 ), $ stackPtr , true );
252
- if ($ lastToken !== false ) {
253
- if ($ tokens [$ lastToken ]['code ' ] === T_CLOSE_CURLY_BRACKET ) {
254
- // We found a closing curly bracket and want to check if its block
255
- // belongs to a SWITCH or an IF, ELSEIF or ELSE clause. If yes, we
256
- // continue searching for a terminating statement within that
257
- // block. Note that we have to make sure that every block of
258
- // the entire if/else statement has a terminating statement.
259
- $ currentCloser = $ lastToken ;
260
- $ hasElseBlock = false ;
261
- do {
262
- $ scopeOpener = $ tokens [$ currentCloser ]['scope_opener ' ];
263
- $ scopeCloser = $ tokens [$ currentCloser ]['scope_closer ' ];
264
-
265
- $ prevToken = $ phpcsFile ->findPrevious (T_WHITESPACE , ($ scopeOpener - 1 ), $ stackPtr , true );
266
- if ($ prevToken === false ) {
247
+ if ($ lastToken === false ) {
248
+ return false ;
249
+ }
250
+
251
+ if ($ tokens [$ lastToken ]['code ' ] === T_CLOSE_CURLY_BRACKET ) {
252
+ // We found a closing curly bracket and want to check if its block
253
+ // belongs to a SWITCH, IF, ELSEIF or ELSE clause. If yes, we
254
+ // continue searching for a terminating statement within that
255
+ // block. Note that we have to make sure that every block of
256
+ // the entire if/else/switch statement has a terminating statement.
257
+ $ currentCloser = $ lastToken ;
258
+ $ hasElseBlock = false ;
259
+ do {
260
+ $ scopeOpener = $ tokens [$ currentCloser ]['scope_opener ' ];
261
+ $ scopeCloser = $ tokens [$ currentCloser ]['scope_closer ' ];
262
+
263
+ $ prevToken = $ phpcsFile ->findPrevious (T_WHITESPACE , ($ scopeOpener - 1 ), $ stackPtr , true );
264
+ if ($ prevToken === false ) {
265
+ return false ;
266
+ }
267
+
268
+ // SWITCH, IF and ELSEIF clauses possess a condition we have to account for.
269
+ if ($ tokens [$ prevToken ]['code ' ] === T_CLOSE_PARENTHESIS ) {
270
+ $ prevToken = $ tokens [$ prevToken ]['parenthesis_owner ' ];
271
+ }
272
+
273
+ if ($ tokens [$ prevToken ]['code ' ] === T_IF ) {
274
+ // If we have not encountered an ELSE clause by now, we cannot
275
+ // be sure that the whole statement terminates in every case.
276
+ if ($ hasElseBlock === false ) {
267
277
return false ;
268
278
}
269
279
270
- // SWITCH, IF and ELSEIF clauses possess a condition we have to account for.
271
- if ($ tokens [$ prevToken ]['code ' ] === T_CLOSE_PARENTHESIS ) {
272
- $ prevToken = $ tokens [$ prevToken ]['parenthesis_owner ' ];
280
+ return $ this ->findNestedTerminator ($ phpcsFile , ($ scopeOpener + 1 ), $ scopeCloser );
281
+ } else if ($ tokens [$ prevToken ]['code ' ] === T_ELSEIF
282
+ || $ tokens [$ prevToken ]['code ' ] === T_ELSE
283
+ ) {
284
+ // If we find a terminating statement within this block,
285
+ // we continue with the previous ELSEIF or IF clause.
286
+ $ hasTerminator = $ this ->findNestedTerminator ($ phpcsFile , ($ scopeOpener + 1 ), $ scopeCloser );
287
+ if ($ hasTerminator === false ) {
288
+ return false ;
273
289
}
274
290
275
- if ($ tokens [$ prevToken ]['code ' ] === T_IF ) {
276
- // If we have not encountered an ELSE clause by now, we cannot
277
- // be sure that the whole statement terminates in every case.
278
- if ($ hasElseBlock === false ) {
279
- return false ;
291
+ $ currentCloser = $ phpcsFile ->findPrevious (T_WHITESPACE , ($ prevToken - 1 ), $ stackPtr , true );
292
+ if ($ tokens [$ prevToken ]['code ' ] === T_ELSE ) {
293
+ $ hasElseBlock = true ;
294
+ }
295
+ } else if ($ tokens [$ prevToken ]['code ' ] === T_SWITCH ) {
296
+ $ hasDefaultBlock = false ;
297
+ $ endOfSwitch = $ tokens [$ prevToken ]['scope_closer ' ];
298
+ $ nextCase = $ prevToken ;
299
+
300
+ // We look for a terminating statement within every blocks.
301
+ while (($ nextCase = $ this ->findNextCase ($ phpcsFile , ($ nextCase + 1 ), $ endOfSwitch )) !== false ) {
302
+ if ($ tokens [$ nextCase ]['code ' ] === T_DEFAULT ) {
303
+ $ hasDefaultBlock = true ;
280
304
}
281
305
282
- return $ this ->findNestedTerminator ($ phpcsFile , ($ scopeOpener + 1 ), $ scopeCloser );
283
- } else if ($ tokens [$ prevToken ]['code ' ] === T_ELSEIF
284
- || $ tokens [$ prevToken ]['code ' ] === T_ELSE
285
- ) {
286
- // If we find a terminating statement within this block,
287
- // we continue with the previous ELSEIF or IF clause.
288
- $ hasTerminator = $ this ->findNestedTerminator ($ phpcsFile , ($ scopeOpener + 1 ), $ scopeCloser );
289
- if ($ hasTerminator === false ) {
290
- return false ;
291
- }
306
+ $ opener = $ tokens [$ nextCase ]['scope_opener ' ];
292
307
293
- $ currentCloser = $ phpcsFile ->findPrevious (T_WHITESPACE , ($ prevToken - 1 ), $ stackPtr , true );
294
- if ($ tokens [$ prevToken ]['code ' ] === T_ELSE ) {
295
- $ hasElseBlock = true ;
308
+ $ nextCode = $ phpcsFile ->findNext (T_WHITESPACE , ($ opener + 1 ), $ endOfSwitch , true );
309
+ if ($ tokens [$ nextCode ]['code ' ] === T_CASE || $ tokens [$ nextCode ]['code ' ] === T_DEFAULT ) {
310
+ // This case statement has no content, so skip it.
311
+ continue ;
296
312
}
297
- } else if ($ tokens [$ prevToken ]['code ' ] === T_SWITCH ) {
298
- $ hasDefaultBlock = false ;
299
- $ endOfSwitch = $ tokens [$ prevToken ]['scope_closer ' ];
300
- $ nextCase = $ prevToken ;
301
-
302
- // We look for a terminating statement within every blocks.
303
- while (($ nextCase = $ this ->findNextCase ($ phpcsFile , ($ nextCase + 1 ), $ endOfSwitch )) !== false ) {
304
- if ($ tokens [$ nextCase ]['code ' ] === T_DEFAULT ) {
305
- $ hasDefaultBlock = true ;
306
- }
307
313
308
- $ opener = $ tokens [$ nextCase ]['scope_opener ' ];
309
-
310
- $ nextCode = $ phpcsFile ->findNext (T_WHITESPACE , ($ opener + 1 ), $ endOfSwitch , true );
311
- if ($ tokens [$ nextCode ]['code ' ] === T_CASE || $ tokens [$ nextCode ]['code ' ] === T_DEFAULT ) {
312
- // This case statement has no content. We skip it.
313
- continue ;
314
- }
315
-
316
- $ nextCode = $ this ->findNextCase ($ phpcsFile , ($ opener + 1 ), $ endOfSwitch );
317
- if ($ nextCode === false ) {
318
- $ nextCode = $ endOfSwitch ;
319
- }
314
+ $ endOfCase = $ this ->findNextCase ($ phpcsFile , ($ opener + 1 ), $ endOfSwitch );
315
+ if ($ endOfCase === false ) {
316
+ $ endOfCase = $ endOfSwitch ;
317
+ }
320
318
321
- $ hasTerminator = $ this ->findNestedTerminator ($ phpcsFile , ($ opener + 1 ), $ nextCode );
322
- if ($ hasTerminator === false ) {
323
- return false ;
324
- }
325
- }//end while
319
+ $ hasTerminator = $ this ->findNestedTerminator ($ phpcsFile , ($ opener + 1 ), $ endOfCase );
320
+ if ($ hasTerminator === false ) {
321
+ return false ;
322
+ }
323
+ }//end while
326
324
327
- // If we have not encountered a DEFAULT block by now, we cannot
328
- // be sure that the whole statement terminates in every case.
329
- return $ hasDefaultBlock ;
330
- } else {
325
+ // If we have not encountered a DEFAULT block by now, we cannot
326
+ // be sure that the whole statement terminates in every case.
327
+ if ($ hasDefaultBlock === false ) {
331
328
return false ;
332
- }//end if
333
- } while ($ currentCloser !== false && $ tokens [$ currentCloser ]['code ' ] === T_CLOSE_CURLY_BRACKET );
334
-
335
- return true ;
336
- } else if ($ tokens [$ lastToken ]['code ' ] === T_SEMICOLON ) {
337
- // We found the last statement of the CASE. Now we want to
338
- // check whether it is a terminating one.
339
- $ terminator = $ phpcsFile ->findStartOfStatement (($ lastToken - 1 ));
340
- if (in_array ($ tokens [$ terminator ]['code ' ], $ terminators , true ) === true ) {
341
- return $ terminator ;
342
- }
343
- }//end if
329
+ }
330
+
331
+ return $ hasTerminator ;
332
+ } else {
333
+ return false ;
334
+ }//end if
335
+ } while ($ currentCloser !== false && $ tokens [$ currentCloser ]['code ' ] === T_CLOSE_CURLY_BRACKET );
336
+
337
+ return true ;
338
+ } else if ($ tokens [$ lastToken ]['code ' ] === T_SEMICOLON ) {
339
+ // We found the last statement of the CASE. Now we want to
340
+ // check whether it is a terminating one.
341
+ $ terminators = [
342
+ T_RETURN ,
343
+ T_BREAK ,
344
+ T_CONTINUE ,
345
+ T_THROW ,
346
+ T_EXIT ,
347
+ ];
348
+
349
+ $ terminator = $ phpcsFile ->findStartOfStatement (($ lastToken - 1 ));
350
+ if (in_array ($ tokens [$ terminator ]['code ' ], $ terminators , true ) === true ) {
351
+ return $ terminator ;
352
+ }
344
353
}//end if
345
354
346
355
return false ;
0 commit comments