Skip to content

Commit 7ed8ea2

Browse files
authored
Merge pull request #1316 from PHPCSStandards/feature/tokenizer-php-switch-case-default-can-start-body-with-php-close-tag
PHP close tag should be regarded as scope opener for switch case/default statements
2 parents 9397930 + b80dc24 commit 7ed8ea2

32 files changed

+553
-70
lines changed

src/Standards/Generic/Tests/CodeAnalysis/AssignmentInConditionUnitTest.1.inc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ switch ( true ) {
7777
case $sample = 'something':
7878
break;
7979

80-
case $sample = 'something' && $a = $b:
80+
case $sample = 'something' && $a = $b;
8181
break;
8282
}
8383

@@ -93,3 +93,14 @@ if ($a = 123) :
9393
endif;
9494

9595
match ($a[0] = 123) {};
96+
97+
switch ( true ) {
98+
case $sample = 'something': {
99+
break;
100+
}
101+
case $sample ?>
102+
<?php $a = $b ?><!-- This is okay, this is in the case body, not the condition. -->
103+
<?php break;
104+
case $sample = 'something' && $a = $b ?>
105+
<?php break;
106+
}

src/Standards/Generic/Tests/CodeAnalysis/AssignmentInConditionUnitTest.php

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -50,40 +50,42 @@ public function getWarningList($testFile = '')
5050
switch ($testFile) {
5151
case 'AssignmentInConditionUnitTest.1.inc':
5252
return [
53-
46 => 1,
54-
47 => 1,
55-
48 => 1,
56-
49 => 1,
57-
50 => 1,
58-
51 => 1,
59-
52 => 1,
60-
53 => 1,
61-
54 => 1,
62-
55 => 1,
63-
56 => 1,
64-
57 => 1,
65-
58 => 1,
66-
59 => 1,
67-
60 => 1,
68-
61 => 2,
69-
63 => 1,
70-
64 => 1,
71-
67 => 1,
72-
68 => 1,
73-
69 => 1,
74-
70 => 1,
75-
71 => 1,
76-
72 => 1,
77-
73 => 1,
78-
75 => 1,
79-
77 => 1,
80-
80 => 2,
81-
84 => 1,
82-
85 => 2,
83-
88 => 1,
84-
90 => 1,
85-
92 => 1,
86-
95 => 1,
53+
46 => 1,
54+
47 => 1,
55+
48 => 1,
56+
49 => 1,
57+
50 => 1,
58+
51 => 1,
59+
52 => 1,
60+
53 => 1,
61+
54 => 1,
62+
55 => 1,
63+
56 => 1,
64+
57 => 1,
65+
58 => 1,
66+
59 => 1,
67+
60 => 1,
68+
61 => 2,
69+
63 => 1,
70+
64 => 1,
71+
67 => 1,
72+
68 => 1,
73+
69 => 1,
74+
70 => 1,
75+
71 => 1,
76+
72 => 1,
77+
73 => 1,
78+
75 => 1,
79+
77 => 1,
80+
80 => 2,
81+
84 => 1,
82+
85 => 2,
83+
88 => 1,
84+
90 => 1,
85+
92 => 1,
86+
95 => 1,
87+
98 => 1,
88+
104 => 2,
8789
];
8890

8991
default:

src/Standards/Generic/Tests/Metrics/CyclomaticComplexityUnitTest.1.inc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,3 +458,32 @@ abstract class AbstractClass {
458458
interface MyInterface {
459459
public function sniffShouldIgnoreInterfaceMethods();
460460
}
461+
462+
function complexityElevenWithSwitchCaseCreativeScopeOpeners()
463+
{
464+
switch ($condition) {
465+
case 'colon':
466+
break;
467+
case 'semicolon';
468+
return;
469+
case 'colon with curlies': {
470+
return;
471+
}
472+
case 'semicolon with curlies'; {
473+
return;
474+
}
475+
case 'PHP close tag' ?>
476+
<?php return ?>
477+
<?php case 'PHP close tag with semicolon'; ?>
478+
<?php return ?>
479+
<?php case 'PHP close tag 2' ?>
480+
<?php goto LABEL ?>
481+
<?php case 'PHP close tag with semicolon'; ?>
482+
<?php exit ?>
483+
<?php case 'PHP close tag 3' ?>
484+
<?php return ?>
485+
<?php default ?>
486+
<?php break ?>
487+
<?php
488+
}
489+
}

src/Standards/Generic/Tests/Metrics/CyclomaticComplexityUnitTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public function getWarningList($testFile = '')
6666
381 => 1,
6767
417 => 1,
6868
445 => 1,
69+
462 => 1,
6970
];
7071
default:
7172
return [];

src/Standards/PEAR/Tests/WhiteSpace/ScopeClosingBraceUnitTest.inc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,33 @@ enum Cards
168168
<?php if ($someConditional) : ?>
169169
<div class="container">
170170
</div> <?php endif;
171+
172+
function switchCaseCreativeScopeOpeners()
173+
{
174+
switch ($correct) {
175+
case 'colon':
176+
break;
177+
case 'semicolon';
178+
return;
179+
case 'PHP close tag' ?>
180+
<?php return ?>
181+
<?php case 'PHP close tag with semicolon'; ?>
182+
<?php exit ?>
183+
<?php case 'PHP close tag 3' ?>
184+
<?php return ?>
185+
<?php default ?>
186+
<?php break ?>
187+
<?php
188+
}
189+
190+
switch ($incorrect) {
191+
case 'semicolon'; return;
192+
case 'PHP close tag' ?>
193+
<?php return ?>
194+
<?php case 'PHP close tag with semicolon'; ?>
195+
<?php exit ?>
196+
<?php default ?>
197+
<?php break ?>
198+
<?php
199+
}
200+
}

src/Standards/PEAR/Tests/WhiteSpace/ScopeClosingBraceUnitTest.inc.fixed

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,34 @@ enum Cards
175175
<div class="container">
176176
</div> <?php
177177
endif;
178+
179+
function switchCaseCreativeScopeOpeners()
180+
{
181+
switch ($correct) {
182+
case 'colon':
183+
break;
184+
case 'semicolon';
185+
return;
186+
case 'PHP close tag' ?>
187+
<?php return ?>
188+
<?php case 'PHP close tag with semicolon'; ?>
189+
<?php exit ?>
190+
<?php case 'PHP close tag 3' ?>
191+
<?php return ?>
192+
<?php default ?>
193+
<?php break ?>
194+
<?php
195+
}
196+
197+
switch ($incorrect) {
198+
case 'semicolon';
199+
return;
200+
case 'PHP close tag' ?>
201+
<?php return ?>
202+
<?php case 'PHP close tag with semicolon'; ?>
203+
<?php exit ?>
204+
<?php default ?>
205+
<?php break ?>
206+
<?php
207+
}
208+
}

src/Standards/PEAR/Tests/WhiteSpace/ScopeClosingBraceUnitTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ public function getErrorList()
5151
160 => 1,
5252
164 => 1,
5353
170 => 1,
54+
191 => 1,
55+
193 => 1,
56+
195 => 1,
57+
197 => 1,
58+
199 => 1,
5459
];
5560
}
5661

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,15 @@ public function process(File $phpcsFile, int $stackPtr)
186186
}
187187
} else {
188188
$error = strtoupper($type) . ' statements must be defined using a colon';
189-
if ($tokens[$opener]['code'] === T_SEMICOLON) {
189+
if ($tokens[$opener]['code'] === T_SEMICOLON || $tokens[$opener]['code'] === T_CLOSE_TAG) {
190190
$fix = $phpcsFile->addFixableError($error, $nextCase, 'WrongOpener' . $type);
191191
if ($fix === true) {
192-
$phpcsFile->fixer->replaceToken($opener, ':');
192+
if ($tokens[$opener]['code'] === T_SEMICOLON) {
193+
$phpcsFile->fixer->replaceToken($opener, ':');
194+
} else {
195+
$prevNonEmpty = $phpcsFile->findPrevious(T_WHITESPACE, ($opener - 1), null, true);
196+
$phpcsFile->fixer->addContent($prevNonEmpty, ':');
197+
}
193198
}
194199
} else {
195200
// Probably a case/default statement with colon + curly braces.

src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,3 +622,19 @@ switch ($value) {
622622
default ;
623623
echo 'Other';
624624
}
625+
626+
// Verify that case/default statements with a PHP close tag as scope opener are handled correctly by the sniff.
627+
switch ($foo):
628+
case "foo"?>
629+
<div>Some html</div>
630+
<?php break;
631+
case "bar" ; ?>
632+
<div>Some html</div>
633+
<?php break;
634+
default ?>
635+
<div>Some html</div>
636+
<?php break;
637+
default ; ?>
638+
<div>Some html</div>
639+
<?php break;
640+
endswitch;

src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc.fixed

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,3 +617,27 @@ switch ($value) {
617617
default:
618618
echo 'Other';
619619
}
620+
621+
// Verify that case/default statements with a PHP close tag as scope opener are handled correctly by the sniff.
622+
switch ($foo):
623+
case "foo":
624+
?>
625+
<div>Some html</div>
626+
<?php
627+
break;
628+
case "bar":
629+
?>
630+
<div>Some html</div>
631+
<?php
632+
break;
633+
default:
634+
?>
635+
<div>Some html</div>
636+
<?php
637+
break;
638+
default:
639+
?>
640+
<div>Some html</div>
641+
<?php
642+
break;
643+
endswitch;

0 commit comments

Comments
 (0)