Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed bug #19616 : Nested switches cause false error in PSR2

  • Loading branch information...
commit 1499c3077914e678b30659ea8c5ddfc69954aceb 1 parent b899439
Greg Sherwood authored September 27, 2012
46  CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/SwitchDeclarationSniff.php
@@ -67,13 +67,7 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
67 67
         $caseCount     = 0;
68 68
         $foundDefault  = false;
69 69
 
70  
-        while (($nextCase = $phpcsFile->findNext(array(T_CASE, T_DEFAULT, T_SWITCH), ($nextCase + 1), $switch['scope_closer'])) !== false) {
71  
-            // Skip nested SWITCH statements; they are handled on their own.
72  
-            if ($tokens[$nextCase]['code'] === T_SWITCH) {
73  
-                $nextCase = $tokens[$nextCase]['scope_closer'];
74  
-                continue;
75  
-            }
76  
-
  70
+        while (($nextCase = $this->_findNextCase($phpcsFile, ($nextCase + 1), $switch['scope_closer'])) !== false) {
77 71
             if ($tokens[$nextCase]['code'] === T_DEFAULT) {
78 72
                 $type         = 'default';
79 73
                 $foundDefault = true;
@@ -151,12 +145,7 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
151 145
                 // This case statement has content. If the next case or default comes
152 146
                 // before the closer, it means we dont have a terminating statement
153 147
                 // and instead need a comment.
154  
-                $nextCode = $phpcsFile->findNext(
155  
-                    array(T_CASE, T_DEFAULT),
156  
-                    ($tokens[$nextCase]['scope_opener'] + 1),
157  
-                    $nextCloser
158  
-                );
159  
-
  148
+                $nextCode = $this->_findNextCase($phpcsFile, ($tokens[$nextCase]['scope_opener'] + 1), $nextCloser);
160 149
                 if ($nextCode !== false) {
161 150
                     $prevCode = $phpcsFile->findPrevious(T_WHITESPACE, ($nextCode - 1), $nextCase, true);
162 151
                     if ($tokens[$prevCode]['code'] !== T_COMMENT) {
@@ -164,12 +153,41 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
164 153
                         $phpcsFile->addError($error, $nextCase, 'TerminatingComment');
165 154
                     }
166 155
                 }
167  
-            }//end if
  156
+            }
168 157
         }//end while
169 158
 
170 159
     }//end process()
171 160
 
172 161
 
  162
+    /**
  163
+     * Find the next CASE or DEFAULT statement from a point in the file.
  164
+     *
  165
+     * Note that nested switches are ignored.
  166
+     *
  167
+     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  168
+     * @param int                  $stackPtr  The position to start looking at.
  169
+     * @param int                  $end       The position to stop looking at.
  170
+     *
  171
+     * @return int | bool
  172
+     */
  173
+    private function _findNextCase(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $end)
  174
+    {
  175
+        $tokens = $phpcsFile->getTokens();
  176
+        while (($stackPtr = $phpcsFile->findNext(array(T_CASE, T_DEFAULT, T_SWITCH), $stackPtr, $end)) !== false) {
  177
+            // Skip nested SWITCH statements; they are handled on their own.
  178
+            if ($tokens[$stackPtr]['code'] === T_SWITCH) {
  179
+                $stackPtr = $tokens[$stackPtr]['scope_closer'];
  180
+                continue;
  181
+            }
  182
+
  183
+            break;
  184
+        }
  185
+
  186
+        return $stackPtr;
  187
+
  188
+    }//end _findNextCase()
  189
+
  190
+
173 191
 }//end class
174 192
 
175 193
 ?>
10  CodeSniffer/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc
@@ -57,4 +57,14 @@ switch (true) {
57 57
     case is_object($value):
58 58
         return 'object';
59 59
 }
  60
+
  61
+switch (0) {
  62
+    case 0:
  63
+        switch (1) {
  64
+            case 1:
  65
+                echo 'a';
  66
+                break;
  67
+        }
  68
+        break;
  69
+}
60 70
 ?>
30  package.xml
@@ -17,8 +17,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
17 17
  <date>2012-09-26</date>
18 18
  <time>14:13:00</time>
19 19
  <version>
20  
-  <release>1.4.0</release>
21  
-  <api>1.4.0</api>
  20
+  <release>1.4.1</release>
  21
+  <api>1.4.1</api>
22 22
  </version>
23 23
  <stability>
24 24
   <release>stable</release>
@@ -26,31 +26,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
26 26
  </stability>
27 27
  <license uri="http://matrix.squiz.net/developer/tools/php_cs/licence">BSD License</license>
28 28
  <notes>
29  
-  - Added PSR1 and PSR2 coding standards that can be used to check your code against these guidelines
30  
-  - PHP 5.4 short array syntax is now detected and tokens are assigned to the open and close characters
31  
-    -- New tokens are T_OPEN_SHORT_ARRAY and T_CLOSE_SHORT_ARRAY as PHP does not define its own
32  
-  - Added the ability to explain a coding standard by listing the sniffs that it includes
33  
-    -- The sniff list includes all imported and native sniffs
34  
-    -- Explain a standard by using the -e and --standard=[standard] command line arguments
35  
-    -- E.g., phpcs -e --standard=Squiz
36  
-    -- Thanks to Ben Selby for the idea
37  
-  - Added report to show results using notify-send
38  
-    -- Use --report=notifysend to generate the report
39  
-    -- Thanks to Christian Weiske for the contribution
40  
-  - The JS tokenizer now recognises RETURN as a valid closer for CASE and DEFAULT inside switch statements
41  
-  - AbstractPatternSniff now sets the ignoreComments option using a public var rather than through the constructor
42  
-    -- This allows the setting to be overwritten in ruleset.xml files
43  
-    -- Old method remains for backwards compatibility
44  
-  - Generic LowerCaseConstantSniff and UpperCaseConstantSniff no longer report errors on classes named True, False or Null
45  
-  - PEAR ValidFunctionNameSniff no longer enforces exact case matching for PHP magic methods
46  
-  - Squiz SwitchDeclarationSniff now allows RETURN statements to close a CASE or DEFAULT statement
47  
-  - Squiz BlockCommentSniff now correctly reports an error for blank lines before blocks at the start of a control structure
48  
-  - Fixed a PHP notice generated when loading custom array settings from a rulset.xml file
49  
-  - Fixed bug #17908 : CodeSniffer does not recognise optional @params
50  
-    -- Thanks to Pete Walker for the patch
51  
-  - Fixed bug #19538 : Function indentation code sniffer checks inside short arrays
52  
-  - Fixed bug #19565 : Non-Executable Code Sniff Broken for Case Statements with both return and break
53  
-  - Fixed bug #19612 : Invalid @package suggestion
  29
+  - Fixed bug #19616 : Nested switches cause false error in PSR2
54 30
  </notes>
55 31
  <contents>
56 32
   <dir name="/">

0 notes on commit 1499c30

Ton Sharp

Private method makes not possible to extend current Sniff.

Greg Sherwood

This is not the sort of thing you need to override. It is just looking for the next CASE statement. So if you need to override this bit, you probably need to override the process() method instead, or just write a new sniff. If you have a reason for changing it, let me know.

Please sign in to comment.
Something went wrong with that request. Please try again.