| Conditions | 33 |
| Paths | > 20000 |
| Total Lines | 157 |
| Code Lines | 98 |
| Lines | 157 |
| Ratio | 100 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 53 | public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { |
||
| 54 | $tokens = $phpcsFile->getTokens(); |
||
| 55 | |||
| 56 | // TODO: Auto-detect spaces vs tabs, maybe using a trait method indent($index, $this->indent) |
||
| 57 | $this->indent = 1; |
||
| 58 | |||
| 59 | // We can't process SWITCH statements unless we know where they start and end. |
||
| 60 | if (isset($tokens[$stackPtr]['scope_opener']) === false |
||
| 61 | || isset($tokens[$stackPtr]['scope_closer']) === false |
||
| 62 | ) { |
||
| 63 | return; |
||
| 64 | } |
||
| 65 | |||
| 66 | $switch = $tokens[$stackPtr]; |
||
| 67 | $nextCase = $stackPtr; |
||
| 68 | $caseAlignment = ($switch['column'] + $this->indent); |
||
| 69 | $caseCount = 0; |
||
| 70 | $foundDefault = false; |
||
| 71 | |||
| 72 | while (($nextCase = $this->findNextCase($phpcsFile, ($nextCase + 1), $switch['scope_closer'])) !== false) { |
||
| 73 | if ($tokens[$nextCase]['code'] === T_DEFAULT) { |
||
| 74 | $type = 'default'; |
||
| 75 | $foundDefault = true; |
||
| 76 | } else { |
||
| 77 | $type = 'case'; |
||
| 78 | $caseCount++; |
||
| 79 | } |
||
| 80 | |||
| 81 | if ($tokens[$nextCase]['content'] !== strtolower($tokens[$nextCase]['content'])) { |
||
| 82 | $expected = strtolower($tokens[$nextCase]['content']); |
||
| 83 | $error = strtoupper($type) . ' keyword must be lowercase; expected "%s" but found "%s"'; |
||
| 84 | $data = [ |
||
| 85 | $expected, |
||
| 86 | $tokens[$nextCase]['content'], |
||
| 87 | ]; |
||
| 88 | |||
| 89 | $fix = $phpcsFile->addFixableError($error, $nextCase, $type . 'NotLower', $data); |
||
| 90 | if ($fix === true) { |
||
| 91 | $phpcsFile->fixer->replaceToken($nextCase, $expected); |
||
| 92 | } |
||
| 93 | } |
||
| 94 | |||
| 95 | if ($type === 'case' |
||
| 96 | && ($tokens[($nextCase + 1)]['code'] !== T_WHITESPACE |
||
| 97 | || $tokens[($nextCase + 1)]['content'] !== ' ') |
||
| 98 | ) { |
||
| 99 | $error = 'CASE keyword must be followed by a single space'; |
||
| 100 | $fix = $phpcsFile->addFixableError($error, $nextCase, 'SpacingAfterCase'); |
||
| 101 | if ($fix === true) { |
||
| 102 | if ($tokens[($nextCase + 1)]['code'] !== T_WHITESPACE) { |
||
| 103 | $phpcsFile->fixer->addContent($nextCase, ' '); |
||
| 104 | } else { |
||
| 105 | $phpcsFile->fixer->replaceToken(($nextCase + 1), ' '); |
||
| 106 | } |
||
| 107 | } |
||
| 108 | } |
||
| 109 | |||
| 110 | $opener = $tokens[$nextCase]['scope_opener']; |
||
| 111 | if ($tokens[$opener]['code'] === T_COLON) { |
||
| 112 | if ($tokens[($opener - 1)]['code'] === T_WHITESPACE) { |
||
| 113 | $error = 'There must be no space before the colon in a ' . strtoupper($type) . ' statement'; |
||
| 114 | $fix = $phpcsFile->addFixableError($error, $nextCase, 'SpaceBeforeColon' . strtoupper($type)); |
||
| 115 | if ($fix === true) { |
||
| 116 | $phpcsFile->fixer->replaceToken(($opener - 1), ''); |
||
| 117 | } |
||
| 118 | } |
||
| 119 | |||
| 120 | $next = $phpcsFile->findNext(T_WHITESPACE, ($opener + 1), null, true); |
||
| 121 | if ($tokens[$next]['line'] === $tokens[$opener]['line'] |
||
| 122 | && $tokens[$next]['code'] === T_COMMENT |
||
| 123 | ) { |
||
| 124 | // Skip comments on the same line. |
||
| 125 | $next = $phpcsFile->findNext(T_WHITESPACE, ($next + 1), null, true); |
||
| 126 | } |
||
| 127 | |||
| 128 | if ($tokens[$next]['line'] !== ($tokens[$opener]['line'] + 1)) { |
||
| 129 | $error = 'The ' . strtoupper($type) . ' body must start on the line following the statement'; |
||
| 130 | $fix = $phpcsFile->addFixableError($error, $nextCase, 'SpaceBeforeColon' . strtoupper($type)); |
||
| 131 | if ($fix === true) { |
||
| 132 | if ($tokens[$next]['line'] === $tokens[$opener]['line']) { |
||
| 133 | $padding = str_repeat(' ', ($caseAlignment + $this->indent - 1)); |
||
| 134 | $phpcsFile->fixer->addContentBefore($next, $phpcsFile->eolChar . $padding); |
||
| 135 | } else { |
||
| 136 | $phpcsFile->fixer->beginChangeset(); |
||
| 137 | for ($i = ($opener + 1); $i < $next; $i++) { |
||
| 138 | if ($tokens[$i]['line'] === $tokens[$next]['line']) { |
||
| 139 | break; |
||
| 140 | } |
||
| 141 | |||
| 142 | $phpcsFile->fixer->replaceToken($i, ''); |
||
| 143 | } |
||
| 144 | |||
| 145 | $phpcsFile->fixer->addNewLineBefore($i); |
||
| 146 | $phpcsFile->fixer->endChangeset(); |
||
| 147 | } |
||
| 148 | } |
||
| 149 | } |
||
| 150 | } else { |
||
| 151 | $error = strtoupper($type) . ' statements must be defined using a colon'; |
||
| 152 | $phpcsFile->addError($error, $nextCase, 'WrongOpener' . $type); |
||
| 153 | } |
||
| 154 | |||
| 155 | $nextCloser = $tokens[$nextCase]['scope_closer']; |
||
| 156 | if ($tokens[$nextCloser]['scope_condition'] === $nextCase) { |
||
| 157 | // Only need to check some things once, even if the |
||
| 158 | // closer is shared between multiple case statements, or even |
||
| 159 | // the default case. |
||
| 160 | $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($nextCloser - 1), $nextCase, true); |
||
| 161 | if ($tokens[$prev]['line'] === $tokens[$nextCloser]['line']) { |
||
| 162 | $error = 'Terminating statement must be on a line by itself'; |
||
| 163 | $fix = $phpcsFile->addFixableError($error, $nextCloser, 'BreakNotNewLine'); |
||
| 164 | if ($fix === true) { |
||
| 165 | $phpcsFile->fixer->addNewLine($prev); |
||
| 166 | $phpcsFile->fixer->replaceToken($nextCloser, trim($tokens[$nextCloser]['content'])); |
||
| 167 | } |
||
| 168 | } else { |
||
| 169 | $diff = ($caseAlignment + $this->indent - $tokens[$nextCloser]['column']); |
||
| 170 | if ($diff !== 0) { |
||
| 171 | $error = 'Terminating statement must be indented to the same level as the CASE body'; |
||
| 172 | $fix = $phpcsFile->addFixableError($error, $nextCloser, 'BreakIndent'); |
||
| 173 | if ($fix === true) { |
||
| 174 | if ($diff > 0) { |
||
| 175 | $phpcsFile->fixer->addContentBefore($nextCloser, str_repeat(' ', $diff)); |
||
| 176 | } else { |
||
| 177 | $phpcsFile->fixer->substrToken(($nextCloser - 1), 0, $diff); |
||
| 178 | } |
||
| 179 | } |
||
| 180 | } |
||
| 181 | } |
||
| 182 | } |
||
| 183 | |||
| 184 | // We only want cases from here on in. |
||
| 185 | if ($type !== 'case') { |
||
| 186 | continue; |
||
| 187 | } |
||
| 188 | |||
| 189 | $nextCode = $phpcsFile->findNext(T_WHITESPACE, |
||
| 190 | ($tokens[$nextCase]['scope_opener'] + 1), |
||
| 191 | $nextCloser, |
||
| 192 | true); |
||
| 193 | |||
| 194 | if ($tokens[$nextCode]['code'] !== T_CASE && $tokens[$nextCode]['code'] !== T_DEFAULT) { |
||
| 195 | // This case statement has content. If the next case or default comes |
||
| 196 | // before the closer, it means we dont have a terminating statement |
||
| 197 | // and instead need a comment. |
||
| 198 | $nextCode = $this->findNextCase($phpcsFile, ($tokens[$nextCase]['scope_opener'] + 1), $nextCloser); |
||
| 199 | if ($nextCode !== false) { |
||
| 200 | $prevCode = $phpcsFile->findPrevious(T_WHITESPACE, ($nextCode - 1), $nextCase, true); |
||
| 201 | if ($tokens[$prevCode]['code'] !== T_COMMENT) { |
||
| 202 | $error = 'There must be a comment when fall-through is intentional in a non-empty case body'; |
||
| 203 | $phpcsFile->addError($error, $nextCase, 'TerminatingComment'); |
||
| 204 | } |
||
| 205 | } |
||
| 206 | } |
||
| 207 | } |
||
| 208 | |||
| 209 | } |
||
| 210 | |||
| 240 |