diff --git a/src/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php b/src/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php index 1efb15c7be..dc4419daea 100644 --- a/src/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php +++ b/src/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php @@ -80,21 +80,25 @@ public function process(File $phpcsFile, $stackPtr) } } - if ($tokens[$stackPtr]['code'] === T_WHILE || $tokens[$stackPtr]['code'] === T_FOR) { - // This could be from a DO WHILE, which doesn't have an opening brace or a while/for without body. - if (isset($tokens[$stackPtr]['parenthesis_closer']) === true) { - $afterParensCloser = $phpcsFile->findNext(Tokens::$emptyTokens, ($tokens[$stackPtr]['parenthesis_closer'] + 1), null, true); - if ($afterParensCloser === false) { - // Live coding. - return; - } + if (isset($tokens[$stackPtr]['parenthesis_closer']) === true) { + $nextTokenIndex = ($tokens[$stackPtr]['parenthesis_closer'] + 1); + } else if (in_array($tokens[$stackPtr]['code'], [T_ELSE, T_DO], true) === true) { + $nextTokenIndex = ($stackPtr + 1); + } - if ($tokens[$afterParensCloser]['code'] === T_SEMICOLON) { - $phpcsFile->recordMetric($stackPtr, 'Control structure defined inline', 'no'); - return; - } + if (isset($nextTokenIndex) === true) { + $firstNonEmptyToken = $phpcsFile->findNext(Tokens::$emptyTokens, $nextTokenIndex, null, true); + if ($firstNonEmptyToken === false) { + // Live coding. + return; } - }//end if + + if ($tokens[$firstNonEmptyToken]['code'] === T_SEMICOLON) { + // This is a control structure without a body. Bow out. + $phpcsFile->recordMetric($stackPtr, 'Control structure defined inline', 'no'); + return; + } + } if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false && $tokens[$stackPtr]['code'] !== T_ELSE @@ -161,9 +165,7 @@ public function process(File $phpcsFile, $stackPtr) $closer = $stackPtr; } - if ($tokens[($closer + 1)]['code'] === T_WHITESPACE - || $tokens[($closer + 1)]['code'] === T_SEMICOLON - ) { + if ($tokens[($closer + 1)]['code'] === T_WHITESPACE) { $phpcsFile->fixer->addContent($closer, ' {'); } else { $phpcsFile->fixer->addContent($closer, ' { '); @@ -259,102 +261,69 @@ public function process(File $phpcsFile, $stackPtr) } $nextContent = $phpcsFile->findNext(Tokens::$emptyTokens, ($end + 1), null, true); - if ($nextContent === false || $tokens[$nextContent]['line'] !== $tokens[$end]['line']) { - // Looks for completely empty statements. - $next = $phpcsFile->findNext(T_WHITESPACE, ($closer + 1), ($end + 1), true); - } else { - $next = ($end + 1); - $endLine = $end; - } - if ($next !== $end) { - if ($nextContent === false || $tokens[$nextContent]['line'] !== $tokens[$end]['line']) { - // Account for a comment on the end of the line. - for ($endLine = $end; $endLine < $phpcsFile->numTokens; $endLine++) { - if (isset($tokens[($endLine + 1)]) === false - || $tokens[$endLine]['line'] !== $tokens[($endLine + 1)]['line'] - ) { - break; - } - } - - if (isset(Tokens::$commentTokens[$tokens[$endLine]['code']]) === false - && ($tokens[$endLine]['code'] !== T_WHITESPACE - || isset(Tokens::$commentTokens[$tokens[($endLine - 1)]['code']]) === false) - ) { - $endLine = $end; - } - } - - if ($endLine !== $end) { - $endToken = $endLine; - $addedContent = ''; - } else { - $endToken = $end; - $addedContent = $phpcsFile->eolChar; - - if ($tokens[$end]['code'] !== T_SEMICOLON - && $tokens[$end]['code'] !== T_CLOSE_CURLY_BRACKET + if ($nextContent === false || $tokens[$nextContent]['line'] !== $tokens[$end]['line']) { + // Account for a comment on the end of the line. + for ($endLine = $end; $endLine < $phpcsFile->numTokens; $endLine++) { + if (isset($tokens[($endLine + 1)]) === false + || $tokens[$endLine]['line'] !== $tokens[($endLine + 1)]['line'] ) { - $phpcsFile->fixer->addContent($end, '; '); + break; } } - $next = $phpcsFile->findNext(T_WHITESPACE, ($endToken + 1), null, true); - if ($next !== false - && ($tokens[$next]['code'] === T_ELSE - || $tokens[$next]['code'] === T_ELSEIF) + if (isset(Tokens::$commentTokens[$tokens[$endLine]['code']]) === false + && ($tokens[$endLine]['code'] !== T_WHITESPACE + || isset(Tokens::$commentTokens[$tokens[($endLine - 1)]['code']]) === false) ) { - $phpcsFile->fixer->addContentBefore($next, '} '); - } else { - $indent = ''; - for ($first = $stackPtr; $first > 0; $first--) { - if ($tokens[$first]['column'] === 1) { - break; - } - } + $endLine = $end; + } + } else { + $endLine = $end; + } - if ($tokens[$first]['code'] === T_WHITESPACE) { - $indent = $tokens[$first]['content']; - } else if ($tokens[$first]['code'] === T_INLINE_HTML - || $tokens[$first]['code'] === T_OPEN_TAG - ) { - $addedContent = ''; - } + if ($endLine !== $end) { + $endToken = $endLine; + $addedContent = ''; + } else { + $endToken = $end; + $addedContent = $phpcsFile->eolChar; - $addedContent .= $indent.'}'; - if ($next !== false && $tokens[$endToken]['code'] === T_COMMENT) { - $addedContent .= $phpcsFile->eolChar; - } + if ($tokens[$end]['code'] !== T_SEMICOLON + && $tokens[$end]['code'] !== T_CLOSE_CURLY_BRACKET + ) { + $phpcsFile->fixer->addContent($end, '; '); + } + } - $phpcsFile->fixer->addContent($endToken, $addedContent); - }//end if + $next = $phpcsFile->findNext(T_WHITESPACE, ($endToken + 1), null, true); + if ($next !== false + && ($tokens[$next]['code'] === T_ELSE + || $tokens[$next]['code'] === T_ELSEIF) + ) { + $phpcsFile->fixer->addContentBefore($next, '} '); } else { - if ($nextContent === false || $tokens[$nextContent]['line'] !== $tokens[$end]['line']) { - // Account for a comment on the end of the line. - for ($endLine = $end; $endLine < $phpcsFile->numTokens; $endLine++) { - if (isset($tokens[($endLine + 1)]) === false - || $tokens[$endLine]['line'] !== $tokens[($endLine + 1)]['line'] - ) { - break; - } + $indent = ''; + for ($first = $stackPtr; $first > 0; $first--) { + if ($tokens[$first]['column'] === 1) { + break; } + } - if ($tokens[$endLine]['code'] !== T_COMMENT - && ($tokens[$endLine]['code'] !== T_WHITESPACE - || $tokens[($endLine - 1)]['code'] !== T_COMMENT) - ) { - $endLine = $end; - } + if ($tokens[$first]['code'] === T_WHITESPACE) { + $indent = $tokens[$first]['content']; + } else if ($tokens[$first]['code'] === T_INLINE_HTML + || $tokens[$first]['code'] === T_OPEN_TAG + ) { + $addedContent = ''; } - if ($endLine !== $end) { - $phpcsFile->fixer->replaceToken($end, ''); - $phpcsFile->fixer->addNewlineBefore($endLine); - $phpcsFile->fixer->addContent($endLine, '}'); - } else { - $phpcsFile->fixer->replaceToken($end, '}'); + $addedContent .= $indent.'}'; + if ($next !== false && $tokens[$endToken]['code'] === T_COMMENT) { + $addedContent .= $phpcsFile->eolChar; } + + $phpcsFile->fixer->addContent($endToken, $addedContent); }//end if $phpcsFile->fixer->endChangeset(); diff --git a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc index ada26fb7ff..1b02430859 100644 --- a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc +++ b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc @@ -276,3 +276,24 @@ function testFinally() if ($something) { echo 'hello'; } else /* comment */ if ($somethingElse) echo 'hi'; + +if ($sniffShouldBailEarly); + +if (false) { +} elseif ($sniffShouldBailEarly); + +if (false) { +} else if ($sniffShouldBailEarly); + +if (false) { +} else ($sniffShouldGenerateError); + +if (false) { +} else; // Sniff should bail early. + +foreach ($array as $sniffShouldBailEarly); + +foreach ($array as $sniffShouldBailEarly) + /* some comment */; + +do ; while ($sniffShouldBailEarly > 5); diff --git a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc.fixed b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc.fixed index 53c6f0952c..ad03ad626f 100644 --- a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc.fixed +++ b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc.fixed @@ -314,3 +314,25 @@ if ($something) { echo 'hello'; } else /* comment */ if ($somethingElse) { echo 'hi'; } + +if ($sniffShouldBailEarly); + +if (false) { +} elseif ($sniffShouldBailEarly); + +if (false) { +} else if ($sniffShouldBailEarly); + +if (false) { +} else { ($sniffShouldGenerateError); +} + +if (false) { +} else; // Sniff should bail early. + +foreach ($array as $sniffShouldBailEarly); + +foreach ($array as $sniffShouldBailEarly) + /* some comment */; + +do ; while ($sniffShouldBailEarly > 5); diff --git a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.js b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.js index 763c1c1c1c..f7be223903 100644 --- a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.js +++ b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.js @@ -33,3 +33,20 @@ if ($("#myid").rotationDegrees()=='90') if (something) { alert('hello'); } else /* comment */ if (somethingElse) alert('hi'); + +if (sniffShouldBailEarly); + +if (false) { +} else if (sniffShouldBailEarly); + +if (false) { +} else (sniffShouldGenerateError); + +if (false) { +} else; // Sniff should bail early. + +while (sniffShouldBailEarly); + +for (sniffShouldBailEarly; sniffShouldBailEarly > 0; sniffShouldBailEarly--); + +do ; while ($sniffShouldBailEarly > 5); diff --git a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.js.fixed b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.js.fixed index 050a406bba..a923790b93 100644 --- a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.js.fixed +++ b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.js.fixed @@ -42,3 +42,21 @@ if (something) { alert('hello'); } else /* comment */ if (somethingElse) { alert('hi'); } + +if (sniffShouldBailEarly); + +if (false) { +} else if (sniffShouldBailEarly); + +if (false) { +} else { (sniffShouldGenerateError); +} + +if (false) { +} else; // Sniff should bail early. + +while (sniffShouldBailEarly); + +for (sniffShouldBailEarly; sniffShouldBailEarly > 0; sniffShouldBailEarly--); + +do ; while ($sniffShouldBailEarly > 5); diff --git a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.php b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.php index 22eeb075cc..df68df39fe 100644 --- a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.php +++ b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.php @@ -81,6 +81,7 @@ public function getErrorList($testFile='') 260 => 1, 269 => 1, 278 => 1, + 289 => 1, ]; case 'InlineControlStructureUnitTest.1.js': @@ -94,6 +95,7 @@ public function getErrorList($testFile='') 27 => 1, 30 => 1, 35 => 1, + 43 => 1, ]; default: