diff --git a/src/PhpCs/FiveLab/Sniffs/Commenting/InheritdocSniff.php b/src/PhpCs/FiveLab/Sniffs/Commenting/InheritdocSniff.php index 42f3fd7..c4b951f 100644 --- a/src/PhpCs/FiveLab/Sniffs/Commenting/InheritdocSniff.php +++ b/src/PhpCs/FiveLab/Sniffs/Commenting/InheritdocSniff.php @@ -104,6 +104,7 @@ private function assertExistDocInParents(File $phpcsFile, int $line, string $met if ($implementRef->hasMethod($methodName)) { $exist = true; + break; } @@ -116,6 +117,7 @@ private function assertExistDocInParents(File $phpcsFile, int $line, string $met if (\preg_match('/^\*\s*@method (\S+) ([^\\\(]+)\s*\(/', \trim($docCommentLine), $parts)) { if ($methodName === $parts[2]) { $exist = true; + break; } } @@ -124,6 +126,7 @@ private function assertExistDocInParents(File $phpcsFile, int $line, string $met if (\preg_match('/^\*\s*@method ([^\\\(]+)\s*\(/', \trim($docCommentLine), $parts)) { if ($methodName === $parts[1]) { $exist = true; + break; } } diff --git a/src/PhpCs/FiveLab/Sniffs/Commenting/ProhibitedDocCommentsSniff.php b/src/PhpCs/FiveLab/Sniffs/Commenting/ProhibitedDocCommentsSniff.php index d139687..387f2ef 100644 --- a/src/PhpCs/FiveLab/Sniffs/Commenting/ProhibitedDocCommentsSniff.php +++ b/src/PhpCs/FiveLab/Sniffs/Commenting/ProhibitedDocCommentsSniff.php @@ -46,6 +46,7 @@ public function process(File $phpcsFile, mixed $stackPtr): void for ($i = $stackPtr + 1; $i < $closePtr; $i++) { if ($tokens[$i]['code'] === T_DOC_COMMENT_TAG) { $hasMetaTag = true; + break; } } diff --git a/src/PhpCs/FiveLab/Sniffs/Formatting/WhiteSpaceAroundControlStatementSniff.php b/src/PhpCs/FiveLab/Sniffs/Formatting/WhiteSpaceAroundControlStatementSniff.php index 6b7f73e..01add38 100644 --- a/src/PhpCs/FiveLab/Sniffs/Formatting/WhiteSpaceAroundControlStatementSniff.php +++ b/src/PhpCs/FiveLab/Sniffs/Formatting/WhiteSpaceAroundControlStatementSniff.php @@ -36,12 +36,14 @@ class WhiteSpaceAroundControlStatementSniff implements Sniff * @var array> */ private static array $ignoredTokens = [ - T_IF => [T_ELSE, T_ELSEIF, T_COLON], - T_ELSE => [T_IF, T_CLOSE_CURLY_BRACKET], - T_ELSEIF => [T_ELSEIF, T_CLOSE_CURLY_BRACKET, T_ELSE], - T_DO => [T_WHILE], - T_WHILE => [T_DO], - T_MATCH => [T_OPEN_SHORT_ARRAY, T_CLOSE_SHORT_ARRAY, T_COMMA], + T_IF => [T_ELSE, T_ELSEIF, T_COLON], + T_ELSE => [T_IF, T_CLOSE_CURLY_BRACKET], + T_ELSEIF => [T_ELSEIF, T_CLOSE_CURLY_BRACKET, T_ELSE], + T_DO => [T_WHILE], + T_WHILE => [T_DO], + T_MATCH => [T_OPEN_SHORT_ARRAY, T_CLOSE_SHORT_ARRAY, T_COMMA], + T_BREAK => [T_CLOSE_CURLY_BRACKET], + T_CONTINUE => [T_CLOSE_CURLY_BRACKET], ]; public function register(): array @@ -56,6 +58,8 @@ public function register(): array T_DO, T_SWITCH, T_MATCH, + T_BREAK, + T_CONTINUE, ]; } @@ -63,7 +67,7 @@ public function process(File $phpcsFile, mixed $stackPtr): void { $stackToken = $phpcsFile->getTokens()[$stackPtr]; - if (!\array_key_exists('scope_closer', $stackToken)) { + if (!\array_key_exists('scope_closer', $stackToken) && !\in_array($stackToken['code'], [T_BREAK, T_CONTINUE], true)) { // Active token hasn't close scope. Maybe use "else if" (or similar) construction where scope undefined. return; } @@ -91,16 +95,22 @@ public function process(File $phpcsFile, mixed $stackPtr): void } // Check blank lines after - $scopeCloserPtr = $stackToken['scope_closer']; - $nextTokenPtr = $phpcsFile->findNext(Tokens::EMPTY_TOKENS, $scopeCloserPtr + 1, null, true); + if (\array_key_exists('scope_closer', $stackToken)) { + $scopeCloserPtr = $stackToken['scope_closer']; + $nextTokenPtr = $phpcsFile->findNext(Tokens::EMPTY_TOKENS, $scopeCloserPtr + 1, null, true); + } else { + $scopeCloserPtr = $stackPtr; + $nextTokenPtr = $stackPtr + 1; + } if ($nextTokenPtr) { $nextToken = $phpcsFile->getTokens()[$nextTokenPtr]; - if ($nextToken['code'] === T_SEMICOLON && $stackToken['code'] === T_MATCH) { - // Use "match" construction. - $nextTokenPtr = $phpcsFile->findNext(Tokens::EMPTY_TOKENS, $nextTokenPtr + 1, null, true); - $nextToken = $nextTokenPtr ? $phpcsFile->getTokens()[$nextTokenPtr] : null; + if ($nextToken['code'] === T_SEMICOLON) { + if (\in_array($stackToken['code'], [T_MATCH, T_BREAK, T_CONTINUE], true)) { + $nextTokenPtr = $phpcsFile->findNext(Tokens::EMPTY_TOKENS, $nextTokenPtr + 1, null, true); + $nextToken = $nextTokenPtr ? $phpcsFile->getTokens()[$nextTokenPtr] : null; + } } if ($nextToken) { diff --git a/src/PhpCs/FiveLab/Sniffs/Formatting/WhiteSpaceBeforeChainCallSniff.php b/src/PhpCs/FiveLab/Sniffs/Formatting/WhiteSpaceBeforeChainCallSniff.php index 3a6b361..d593d4c 100644 --- a/src/PhpCs/FiveLab/Sniffs/Formatting/WhiteSpaceBeforeChainCallSniff.php +++ b/src/PhpCs/FiveLab/Sniffs/Formatting/WhiteSpaceBeforeChainCallSniff.php @@ -21,7 +21,7 @@ class WhiteSpaceBeforeChainCallSniff implements Sniff { - const GAP = 4; + const int GAP = 4; public function register(): array { @@ -96,14 +96,6 @@ public function process(File $phpcsFile, mixed $stackPtr): void ); } - /** - * Calculate whitespaces before first token on line - * - * @param File $phpcsFile - * @param int $line - * - * @return int - */ private function calculateWhitespacesBeforeFirstTokenOnLine(File $phpcsFile, int $line): int { $whitespaces = 0; @@ -111,6 +103,7 @@ private function calculateWhitespacesBeforeFirstTokenOnLine(File $phpcsFile, int foreach (PhpCsUtils::getTokensOnLine($phpcsFile, $line) as $token) { if (T_WHITESPACE === $token['code']) { $whitespaces += $token['length']; + continue; } diff --git a/tests/PhpCs/FiveLab/Sniffs/Formatting/Resources/white-space-around-control-statement/success.php b/tests/PhpCs/FiveLab/Sniffs/Formatting/Resources/white-space-around-control-statement/success.php index b3edd43..1d4cc27 100644 --- a/tests/PhpCs/FiveLab/Sniffs/Formatting/Resources/white-space-around-control-statement/success.php +++ b/tests/PhpCs/FiveLab/Sniffs/Formatting/Resources/white-space-around-control-statement/success.php @@ -100,4 +100,18 @@ if (false) { $bar = 'bar'; } -} \ No newline at end of file + + break; +} + +if ($condition) { + $bar = 'bar'; + + break; +} + +for ($i = 0; $i < 10; $i++) { + $someArray[] = $i; + + continue; +} diff --git a/tests/PhpCs/FiveLab/Sniffs/Formatting/Resources/white-space-around-control-statement/wrong.php b/tests/PhpCs/FiveLab/Sniffs/Formatting/Resources/white-space-around-control-statement/wrong.php index c2a78c4..cca1dbc 100644 --- a/tests/PhpCs/FiveLab/Sniffs/Formatting/Resources/white-space-around-control-statement/wrong.php +++ b/tests/PhpCs/FiveLab/Sniffs/Formatting/Resources/white-space-around-control-statement/wrong.php @@ -15,3 +15,13 @@ $a .= $key; } $bar = 'foo'; + +if ($a) { + $a = 'bar'; + break; +} + +foreach ($array as $key => $item) { + $a .= $key; + continue; +} diff --git a/tests/PhpCs/FiveLab/Sniffs/Formatting/WhiteSpaceAroundControlStatementSniffTest.php b/tests/PhpCs/FiveLab/Sniffs/Formatting/WhiteSpaceAroundControlStatementSniffTest.php index 55616a4..2c58b10 100644 --- a/tests/PhpCs/FiveLab/Sniffs/Formatting/WhiteSpaceAroundControlStatementSniffTest.php +++ b/tests/PhpCs/FiveLab/Sniffs/Formatting/WhiteSpaceAroundControlStatementSniffTest.php @@ -44,6 +44,14 @@ public static function provideDataSet(): array 'message' => 'Must be one blank line after close "foreach" statement.', 'source' => 'FiveLab.Formatting.WhiteSpaceAroundControlStatement.MissedLineAfter', ], + [ + 'message' => 'Must be one blank line before "break" statement.', + 'source' => 'FiveLab.Formatting.WhiteSpaceAroundControlStatement.MissedLineBefore', + ], + [ + 'message' => 'Must be one blank line before "continue" statement.', + 'source' => 'FiveLab.Formatting.WhiteSpaceAroundControlStatement.MissedLineBefore', + ], ], ]; }