Skip to content

Commit c2a33b8

Browse files
committed
Minor refactoring and doc correction
1 parent 15afb2f commit c2a33b8

File tree

1 file changed

+98
-89
lines changed

1 file changed

+98
-89
lines changed

src/Standards/PSR2/Sniffs/ControlStructures/SwitchDeclarationSniff.php

Lines changed: 98 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -229,118 +229,127 @@ private function findNextCase($phpcsFile, $stackPtr, $end)
229229

230230

231231
/**
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.
233235
*
234236
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
235237
* @param int $stackPtr The position to start looking at.
236238
* @param int $end The position to stop looking at.
237239
*
238-
* @return bool
240+
* @return int|false
239241
*/
240242
private function findNestedTerminator($phpcsFile, $stackPtr, $end)
241243
{
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();
250245

251246
$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) {
267277
return false;
268278
}
269279

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;
273289
}
274290

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;
280304
}
281305

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'];
292307

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;
296312
}
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-
}
307313

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+
}
320318

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
326324

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) {
331328
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+
}
344353
}//end if
345354

346355
return false;

0 commit comments

Comments
 (0)