diff --git a/package.xml b/package.xml
index 8e6ec1d628..6df5902174 100644
--- a/package.xml
+++ b/package.xml
@@ -26,6 +26,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
BSD 3-Clause License
+ - Fixed bug #2688 : Case statements not tokenized correctly when switch is contained within ternary
- Fixed bug #2698 : PHPCS throws errors determining auto report width when shell_exec is disabled
-- Thanks to Matthew Peveler for the patch
- Fixed bug #2751 : Autoload relative paths first to avoid confusion with files from the global include path
diff --git a/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc b/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc
index 88a81869d5..af605cd71d 100644
--- a/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc
+++ b/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc
@@ -262,3 +262,12 @@ switch ($sContext)
do_something();
}
}
+
+$foo = $foo ?
+ function () {
+ switch ($a) {
+ case 'a':
+ break;
+ }
+ } :
+ null;
diff --git a/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc.fixed b/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc.fixed
index 748cee944f..d5671feea3 100644
--- a/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc.fixed
+++ b/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc.fixed
@@ -265,3 +265,12 @@ switch ($sContext)
do_something();
}
}
+
+$foo = $foo ?
+ function () {
+ switch ($a) {
+ case 'a':
+ break;
+ }
+ } :
+ null;
diff --git a/src/Standards/Squiz/Tests/ControlStructures/SwitchDeclarationUnitTest.inc b/src/Standards/Squiz/Tests/ControlStructures/SwitchDeclarationUnitTest.inc
index 5c71161425..cf397607bf 100644
--- a/src/Standards/Squiz/Tests/ControlStructures/SwitchDeclarationUnitTest.inc
+++ b/src/Standards/Squiz/Tests/ControlStructures/SwitchDeclarationUnitTest.inc
@@ -315,3 +315,19 @@ switch ($foo) {
'bar'
);
}
+
+$foo = $foo ?
+ function () {
+ switch ($a) {
+ case 'a':
+ break;
+
+ case (preg_match('/foo/i', $foo) ? $a : $b):
+ echo 'really?'
+ break;
+
+ default:
+ break;
+ }
+ } :
+ null;
diff --git a/src/Standards/Squiz/Tests/ControlStructures/SwitchDeclarationUnitTest.php b/src/Standards/Squiz/Tests/ControlStructures/SwitchDeclarationUnitTest.php
index ab392c6181..c94c8333a5 100644
--- a/src/Standards/Squiz/Tests/ControlStructures/SwitchDeclarationUnitTest.php
+++ b/src/Standards/Squiz/Tests/ControlStructures/SwitchDeclarationUnitTest.php
@@ -27,48 +27,103 @@ class SwitchDeclarationUnitTest extends AbstractSniffUnitTest
*/
public function getErrorList($testFile='SwitchDeclarationUnitTest.inc')
{
- return [
- 27 => 1,
- 29 => 1,
- 34 => 1,
- 36 => 1,
- 44 => 1,
- 48 => 1,
- 52 => 1,
- 54 => 1,
- 55 => 1,
- 56 => 1,
- 58 => 1,
- 59 => 1,
- 61 => 1,
- 62 => 1,
- 79 => 1,
- 85 => 2,
- 88 => 2,
- 89 => 2,
- 92 => 1,
- 95 => 3,
- 99 => 1,
- 116 => 1,
- 122 => 1,
- 127 => 2,
- 134 => 2,
- 135 => 1,
- 138 => 1,
- 143 => 1,
- 144 => 1,
- 147 => 1,
- 165 => 1,
- 172 => 1,
- 176 => 2,
- 180 => 1,
- 192 => 2,
- 196 => 1,
- 223 => 1,
- 266 => 1,
- 282 => 1,
- 284 => 2,
- ];
+ switch ($testFile) {
+ case 'SwitchDeclarationUnitTest.inc':
+ return [
+ 27 => 1,
+ 29 => 1,
+ 34 => 1,
+ 36 => 1,
+ 44 => 1,
+ 48 => 1,
+ 52 => 1,
+ 54 => 1,
+ 55 => 1,
+ 56 => 1,
+ 58 => 1,
+ 59 => 1,
+ 61 => 1,
+ 62 => 1,
+ 79 => 1,
+ 85 => 2,
+ 88 => 2,
+ 89 => 2,
+ 92 => 1,
+ 95 => 3,
+ 99 => 1,
+ 116 => 1,
+ 122 => 1,
+ 127 => 2,
+ 134 => 2,
+ 135 => 1,
+ 138 => 1,
+ 143 => 1,
+ 144 => 1,
+ 147 => 1,
+ 165 => 1,
+ 172 => 1,
+ 176 => 2,
+ 180 => 1,
+ 192 => 2,
+ 196 => 1,
+ 223 => 1,
+ 266 => 1,
+ 282 => 1,
+ 284 => 2,
+ 322 => 1,
+ 323 => 1,
+ 327 => 1,
+ 329 => 1,
+ 330 => 1,
+ ];
+
+ case 'SwitchDeclarationUnitTest.js':
+ return [
+ 27 => 1,
+ 29 => 1,
+ 34 => 1,
+ 36 => 1,
+ 44 => 1,
+ 48 => 1,
+ 52 => 1,
+ 54 => 1,
+ 55 => 1,
+ 56 => 1,
+ 58 => 1,
+ 59 => 1,
+ 61 => 1,
+ 62 => 1,
+ 79 => 1,
+ 85 => 2,
+ 88 => 2,
+ 89 => 2,
+ 92 => 1,
+ 95 => 3,
+ 99 => 1,
+ 116 => 1,
+ 122 => 1,
+ 127 => 2,
+ 134 => 2,
+ 135 => 1,
+ 138 => 1,
+ 143 => 1,
+ 144 => 1,
+ 147 => 1,
+ 165 => 1,
+ 172 => 1,
+ 176 => 2,
+ 180 => 1,
+ 192 => 2,
+ 196 => 1,
+ 223 => 1,
+ 266 => 1,
+ 282 => 1,
+ 284 => 2,
+ ];
+
+ default:
+ return [];
+ }//end switch
}//end getErrorList()
diff --git a/src/Tokenizers/PHP.php b/src/Tokenizers/PHP.php
index 6eb750c3a0..6c32655712 100644
--- a/src/Tokenizers/PHP.php
+++ b/src/Tokenizers/PHP.php
@@ -1450,7 +1450,7 @@ function return types. We want to keep the parenthesis map clean,
// inline IF statement.
if (empty($insideInlineIf) === false && $newToken['code'] === T_COLON) {
// Make sure this isn't the return type separator of a closure.
- $isReturnType = false;
+ $isInlineIf = true;
for ($i = ($stackPtr - 1); $i > 0; $i--) {
if (is_array($tokens[$i]) === false
|| ($tokens[$i][0] !== T_DOC_COMMENT
@@ -1487,14 +1487,44 @@ function return types. We want to keep the parenthesis map clean,
}
if ($tokens[$i][0] === T_FUNCTION || $tokens[$i][0] === T_FN || $tokens[$i][0] === T_USE) {
- $isReturnType = true;
+ $isInlineIf = false;
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ echo "\t\t* token is function return type, not T_INLINE_ELSE".PHP_EOL;
+ }
}
}//end if
- if ($isReturnType === false) {
+ // Check to see if this is a CASE or DEFAULT opener.
+ $inlineIfToken = $insideInlineIf[(count($insideInlineIf) - 1)];
+ for ($i = $stackPtr; $i > $inlineIfToken; $i--) {
+ if (is_array($tokens[$i]) === true
+ && ($tokens[$i][0] === T_CASE
+ || $tokens[$i][0] === T_DEFAULT)
+ ) {
+ $isInlineIf = false;
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ echo "\t\t* token is T_CASE or T_DEFAULT opener, not T_INLINE_ELSE".PHP_EOL;
+ }
+
+ break;
+ }
+
+ if (is_array($tokens[$i]) === false
+ && ($tokens[$i] === ';'
+ || $tokens[$i] === '{')
+ ) {
+ break;
+ }
+ }
+
+ if ($isInlineIf === true) {
array_pop($insideInlineIf);
$newToken['code'] = T_INLINE_ELSE;
$newToken['type'] = 'T_INLINE_ELSE';
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ echo "\t\t* token changed from T_COLON to T_INLINE_ELSE".PHP_EOL;
+ }
}
}//end if