GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — develop ( ebb7bf...0a5ff4 )
by Chris
02:41 queued 11s
created

SwitchDeclarationSniff::process()   F

Complexity

Conditions 33
Paths > 20000

Size

Total Lines 157
Code Lines 98

Duplication

Lines 157
Ratio 100 %

Importance

Changes 0
Metric Value
cc 33
eloc 98
nc 26042
nop 2
dl 157
loc 157
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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:

1
<?php
2
/**
3
 * PSR2_Sniffs_ControlStructures_SwitchDeclarationSniff.
4
 *
5
 * PHP version 5
6
 *
7
 * @category  PHP
8
 * @package   PHP_CodeSniffer
9
 * @author    Greg Sherwood <[email protected]>
10
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
 * @link      http://pear.php.net/package/PHP_CodeSniffer
13
 */
14
15
namespace PSR2R\Sniffs\ControlStructures;
16
17
use PHP_CodeSniffer_File;
18
use PHP_CodeSniffer_Sniff;
19
20
/**
21
 * PSR2_Sniffs_ControlStructures_SwitchDeclarationSniff.
22
 *
23
 * Ensures all switch statements are defined correctly.
24
 *
25
 * @author Greg Sherwood <[email protected]>
26
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
27
 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
28
 * @version Release: @package_version@
29
 * @link http://pear.php.net/package/PHP_CodeSniffer
30
 */
31
class SwitchDeclarationSniff implements PHP_CodeSniffer_Sniff {
32
33
	/**
34
	 * The number of spaces code should be indented.
35
	 *
36
	 * @var int
37
	 */
38
	public $indent = 4;
39
40
41
	/**
42
	 * @inheritDoc
43
	 */
44
	public function register() {
45
		return [T_SWITCH];
46
47
	}
48
49
50
	/**
51
	 * @inheritDoc
52
	 */
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
211
212
	/**
213
	 * Find the next CASE or DEFAULT statement from a point in the file.
214
	 *
215
	 * Note that nested switches are ignored.
216
	 *
217
	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
218
	 * @param int $stackPtr The position to start looking at.
219
	 * @param int $end The position to stop looking at.
220
	 *
221
	 * @return int | bool
222
	 */
223
	protected function findNextCase(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $end) {
224
		$tokens = $phpcsFile->getTokens();
225
		while (($stackPtr = $phpcsFile->findNext([T_CASE, T_DEFAULT, T_SWITCH], $stackPtr, $end)) !== false) {
226
			// Skip nested SWITCH statements; they are handled on their own.
227
			if ($tokens[$stackPtr]['code'] === T_SWITCH) {
228
				$stackPtr = $tokens[$stackPtr]['scope_closer'];
229
				continue;
230
			}
231
232
			break;
233
		}
234
235
		return $stackPtr;
236
237
	}
238
239
}
240