Skip to content

Commit

Permalink
Fixed bug #2688 : Case statements not tokenized correctly when switch…
Browse files Browse the repository at this point in the history
… is contained within ternary
  • Loading branch information
gsherwood committed Dec 16, 2019
1 parent 5c9586b commit 15aedfc
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 45 deletions.
1 change: 1 addition & 0 deletions package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
</stability>
<license uri="https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt">BSD 3-Clause License</license>
<notes>
- 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,12 @@ switch ($sContext)
do_something();
}
}

$foo = $foo ?
function () {
switch ($a) {
case 'a':
break;
}
} :
null;
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,12 @@ switch ($sContext)
do_something();
}
}

$foo = $foo ?
function () {
switch ($a) {
case 'a':
break;
}
} :
null;
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
36 changes: 33 additions & 3 deletions src/Tokenizers/PHP.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down

0 comments on commit 15aedfc

Please sign in to comment.