@@ -5,7 +5,7 @@ discard block |
||
5 | 5 | const CONSTANT2 = 2; |
6 | 6 | |
7 | 7 | if ($something) { |
8 | - echo 'hi'; |
|
8 | + echo 'hi'; |
|
9 | 9 | } |
10 | 10 | |
11 | 11 | $var = myFunction(); |
@@ -16,9 +16,9 @@ discard block |
||
16 | 16 | |
17 | 17 | $c = new class extends Something{ |
18 | 18 | |
19 | - public function someMethod() |
|
20 | - { |
|
21 | - // ... |
|
22 | - } |
|
19 | + public function someMethod() |
|
20 | + { |
|
21 | + // ... |
|
22 | + } |
|
23 | 23 | |
24 | 24 | }; |
@@ -14,7 +14,7 @@ |
||
14 | 14 | echo $object -> define(); |
15 | 15 | Foo::define(); |
16 | 16 | |
17 | -$c = new class extends Something{ |
|
17 | +$c = new class extends Something { |
|
18 | 18 | |
19 | 19 | public function someMethod() |
20 | 20 | { |
@@ -4,5 +4,5 @@ |
||
4 | 4 | // phpcs:enable |
5 | 5 | $defined = true; |
6 | 6 | if (defined('MINSIZE') === false) { |
7 | - $defined = false; |
|
7 | + $defined = false; |
|
8 | 8 | } |
@@ -1,7 +1,7 @@ |
||
1 | 1 | <html> |
2 | 2 | <?php |
3 | 3 | function printHead() { |
4 | - echo '<head></head>'; |
|
4 | + echo '<head></head>'; |
|
5 | 5 | } |
6 | 6 | |
7 | 7 | printHead(); |
@@ -25,7 +25,7 @@ discard block |
||
25 | 25 | * |
26 | 26 | * @return array<int, int> |
27 | 27 | */ |
28 | - public function getErrorList($testFile='') |
|
28 | + public function getErrorList($testFile = '') |
|
29 | 29 | { |
30 | 30 | return []; |
31 | 31 | |
@@ -42,7 +42,7 @@ discard block |
||
42 | 42 | * |
43 | 43 | * @return array<int, int> |
44 | 44 | */ |
45 | - public function getWarningList($testFile='') |
|
45 | + public function getWarningList($testFile = '') |
|
46 | 46 | { |
47 | 47 | switch ($testFile) { |
48 | 48 | case 'SideEffectsUnitTest.3.inc': |
@@ -15,66 +15,66 @@ |
||
15 | 15 | { |
16 | 16 | |
17 | 17 | |
18 | - /** |
|
19 | - * Set CLI values before the file is tested. |
|
20 | - * |
|
21 | - * @param string $testFile The name of the file being tested. |
|
22 | - * @param \PHP_CodeSniffer\Config $config The config data for the test run. |
|
23 | - * |
|
24 | - * @return void |
|
25 | - */ |
|
26 | - public function setCliValues($testFile, $config) |
|
27 | - { |
|
28 | - if ($testFile === 'SideEffectsUnitTest.12.inc') { |
|
29 | - $config->annotations = false; |
|
30 | - } |
|
18 | + /** |
|
19 | + * Set CLI values before the file is tested. |
|
20 | + * |
|
21 | + * @param string $testFile The name of the file being tested. |
|
22 | + * @param \PHP_CodeSniffer\Config $config The config data for the test run. |
|
23 | + * |
|
24 | + * @return void |
|
25 | + */ |
|
26 | + public function setCliValues($testFile, $config) |
|
27 | + { |
|
28 | + if ($testFile === 'SideEffectsUnitTest.12.inc') { |
|
29 | + $config->annotations = false; |
|
30 | + } |
|
31 | 31 | |
32 | - }//end setCliValues() |
|
32 | + }//end setCliValues() |
|
33 | 33 | |
34 | 34 | |
35 | - /** |
|
36 | - * Returns the lines where errors should occur. |
|
37 | - * |
|
38 | - * The key of the array should represent the line number and the value |
|
39 | - * should represent the number of errors that should occur on that line. |
|
40 | - * |
|
41 | - * @param string $testFile The name of the file being tested. |
|
42 | - * |
|
43 | - * @return array<int, int> |
|
44 | - */ |
|
45 | - public function getErrorList($testFile='') |
|
46 | - { |
|
47 | - return []; |
|
35 | + /** |
|
36 | + * Returns the lines where errors should occur. |
|
37 | + * |
|
38 | + * The key of the array should represent the line number and the value |
|
39 | + * should represent the number of errors that should occur on that line. |
|
40 | + * |
|
41 | + * @param string $testFile The name of the file being tested. |
|
42 | + * |
|
43 | + * @return array<int, int> |
|
44 | + */ |
|
45 | + public function getErrorList($testFile='') |
|
46 | + { |
|
47 | + return []; |
|
48 | 48 | |
49 | - }//end getErrorList() |
|
49 | + }//end getErrorList() |
|
50 | 50 | |
51 | 51 | |
52 | - /** |
|
53 | - * Returns the lines where warnings should occur. |
|
54 | - * |
|
55 | - * The key of the array should represent the line number and the value |
|
56 | - * should represent the number of warnings that should occur on that line. |
|
57 | - * |
|
58 | - * @param string $testFile The name of the file being tested. |
|
59 | - * |
|
60 | - * @return array<int, int> |
|
61 | - */ |
|
62 | - public function getWarningList($testFile='') |
|
63 | - { |
|
64 | - switch ($testFile) { |
|
65 | - case 'SideEffectsUnitTest.3.inc': |
|
66 | - case 'SideEffectsUnitTest.4.inc': |
|
67 | - case 'SideEffectsUnitTest.5.inc': |
|
68 | - case 'SideEffectsUnitTest.10.inc': |
|
69 | - case 'SideEffectsUnitTest.12.inc': |
|
70 | - case 'SideEffectsUnitTest.15.inc': |
|
71 | - case 'SideEffectsUnitTest.16.inc': |
|
72 | - return [1 => 1]; |
|
73 | - default: |
|
74 | - return []; |
|
75 | - }//end switch |
|
52 | + /** |
|
53 | + * Returns the lines where warnings should occur. |
|
54 | + * |
|
55 | + * The key of the array should represent the line number and the value |
|
56 | + * should represent the number of warnings that should occur on that line. |
|
57 | + * |
|
58 | + * @param string $testFile The name of the file being tested. |
|
59 | + * |
|
60 | + * @return array<int, int> |
|
61 | + */ |
|
62 | + public function getWarningList($testFile='') |
|
63 | + { |
|
64 | + switch ($testFile) { |
|
65 | + case 'SideEffectsUnitTest.3.inc': |
|
66 | + case 'SideEffectsUnitTest.4.inc': |
|
67 | + case 'SideEffectsUnitTest.5.inc': |
|
68 | + case 'SideEffectsUnitTest.10.inc': |
|
69 | + case 'SideEffectsUnitTest.12.inc': |
|
70 | + case 'SideEffectsUnitTest.15.inc': |
|
71 | + case 'SideEffectsUnitTest.16.inc': |
|
72 | + return [1 => 1]; |
|
73 | + default: |
|
74 | + return []; |
|
75 | + }//end switch |
|
76 | 76 | |
77 | - }//end getWarningList() |
|
77 | + }//end getWarningList() |
|
78 | 78 | |
79 | 79 | |
80 | 80 | }//end class |
@@ -62,16 +62,16 @@ |
||
62 | 62 | public function getWarningList($testFile='') |
63 | 63 | { |
64 | 64 | switch ($testFile) { |
65 | - case 'SideEffectsUnitTest.3.inc': |
|
66 | - case 'SideEffectsUnitTest.4.inc': |
|
67 | - case 'SideEffectsUnitTest.5.inc': |
|
68 | - case 'SideEffectsUnitTest.10.inc': |
|
69 | - case 'SideEffectsUnitTest.12.inc': |
|
70 | - case 'SideEffectsUnitTest.15.inc': |
|
71 | - case 'SideEffectsUnitTest.16.inc': |
|
72 | - return [1 => 1]; |
|
73 | - default: |
|
74 | - return []; |
|
65 | + case 'SideEffectsUnitTest.3.inc': |
|
66 | + case 'SideEffectsUnitTest.4.inc': |
|
67 | + case 'SideEffectsUnitTest.5.inc': |
|
68 | + case 'SideEffectsUnitTest.10.inc': |
|
69 | + case 'SideEffectsUnitTest.12.inc': |
|
70 | + case 'SideEffectsUnitTest.15.inc': |
|
71 | + case 'SideEffectsUnitTest.16.inc': |
|
72 | + return [1 => 1]; |
|
73 | + default: |
|
74 | + return []; |
|
75 | 75 | }//end switch |
76 | 76 | |
77 | 77 | }//end getWarningList() |
@@ -4,7 +4,7 @@ |
||
4 | 4 | define("MAXSIZE", 100); |
5 | 5 | $defined = true; |
6 | 6 | if (defined('MINSIZE') === false) { |
7 | - $defined = false; |
|
7 | + $defined = false; |
|
8 | 8 | } |
9 | 9 | |
10 | 10 | // phpcs:enable PEAR |
@@ -25,7 +25,7 @@ |
||
25 | 25 | * |
26 | 26 | * @return array<int, int> |
27 | 27 | */ |
28 | - public function getErrorList($testFile='') |
|
28 | + public function getErrorList($testFile = '') |
|
29 | 29 | { |
30 | 30 | if ($testFile === 'ClassDeclarationUnitTest.2.inc') { |
31 | 31 | return []; |
@@ -15,43 +15,43 @@ |
||
15 | 15 | { |
16 | 16 | |
17 | 17 | |
18 | - /** |
|
19 | - * Returns the lines where errors should occur. |
|
20 | - * |
|
21 | - * The key of the array should represent the line number and the value |
|
22 | - * should represent the number of errors that should occur on that line. |
|
23 | - * |
|
24 | - * @param string $testFile The name of the file being tested. |
|
25 | - * |
|
26 | - * @return array<int, int> |
|
27 | - */ |
|
28 | - public function getErrorList($testFile='') |
|
29 | - { |
|
30 | - if ($testFile === 'ClassDeclarationUnitTest.2.inc') { |
|
31 | - return []; |
|
32 | - } |
|
33 | - |
|
34 | - return [ |
|
35 | - 2 => 1, |
|
36 | - 3 => 2, |
|
37 | - ]; |
|
38 | - |
|
39 | - }//end getErrorList() |
|
40 | - |
|
41 | - |
|
42 | - /** |
|
43 | - * Returns the lines where warnings should occur. |
|
44 | - * |
|
45 | - * The key of the array should represent the line number and the value |
|
46 | - * should represent the number of warnings that should occur on that line. |
|
47 | - * |
|
48 | - * @return array<int, int> |
|
49 | - */ |
|
50 | - public function getWarningList() |
|
51 | - { |
|
52 | - return []; |
|
53 | - |
|
54 | - }//end getWarningList() |
|
18 | + /** |
|
19 | + * Returns the lines where errors should occur. |
|
20 | + * |
|
21 | + * The key of the array should represent the line number and the value |
|
22 | + * should represent the number of errors that should occur on that line. |
|
23 | + * |
|
24 | + * @param string $testFile The name of the file being tested. |
|
25 | + * |
|
26 | + * @return array<int, int> |
|
27 | + */ |
|
28 | + public function getErrorList($testFile='') |
|
29 | + { |
|
30 | + if ($testFile === 'ClassDeclarationUnitTest.2.inc') { |
|
31 | + return []; |
|
32 | + } |
|
33 | + |
|
34 | + return [ |
|
35 | + 2 => 1, |
|
36 | + 3 => 2, |
|
37 | + ]; |
|
38 | + |
|
39 | + }//end getErrorList() |
|
40 | + |
|
41 | + |
|
42 | + /** |
|
43 | + * Returns the lines where warnings should occur. |
|
44 | + * |
|
45 | + * The key of the array should represent the line number and the value |
|
46 | + * should represent the number of warnings that should occur on that line. |
|
47 | + * |
|
48 | + * @return array<int, int> |
|
49 | + */ |
|
50 | + public function getWarningList() |
|
51 | + { |
|
52 | + return []; |
|
53 | + |
|
54 | + }//end getWarningList() |
|
55 | 55 | |
56 | 56 | |
57 | 57 | }//end class |
@@ -103,7 +103,7 @@ |
||
103 | 103 | ) { |
104 | 104 | do { |
105 | 105 | $i = $phpcsFile->findNext(T_PHPCS_ENABLE, ($i + 1)); |
106 | - } while ($i !== false |
|
106 | + }while ($i !== false |
|
107 | 107 | && empty($tokens[$i]['sniffCodes']) === false |
108 | 108 | && isset($tokens[$i]['sniffCodes']['PSR1']) === false |
109 | 109 | && isset($tokens[$i]['sniffCodes']['PSR1.Files']) === false |
@@ -17,283 +17,283 @@ |
||
17 | 17 | { |
18 | 18 | |
19 | 19 | |
20 | - /** |
|
21 | - * Returns an array of tokens this test wants to listen for. |
|
22 | - * |
|
23 | - * @return array |
|
24 | - */ |
|
25 | - public function register() |
|
26 | - { |
|
27 | - return [T_OPEN_TAG]; |
|
28 | - |
|
29 | - }//end register() |
|
30 | - |
|
31 | - |
|
32 | - /** |
|
33 | - * Processes this sniff, when one of its tokens is encountered. |
|
34 | - * |
|
35 | - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
36 | - * @param int $stackPtr The position of the current token in |
|
37 | - * the token stack. |
|
38 | - * |
|
39 | - * @return void |
|
40 | - */ |
|
41 | - public function process(File $phpcsFile, $stackPtr) |
|
42 | - { |
|
43 | - $tokens = $phpcsFile->getTokens(); |
|
44 | - $result = $this->searchForConflict($phpcsFile, 0, ($phpcsFile->numTokens - 1), $tokens); |
|
45 | - |
|
46 | - if ($result['symbol'] !== null && $result['effect'] !== null) { |
|
47 | - $error = 'A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is defined on line %s and the first side effect is on line %s.'; |
|
48 | - $data = [ |
|
49 | - $tokens[$result['symbol']]['line'], |
|
50 | - $tokens[$result['effect']]['line'], |
|
51 | - ]; |
|
52 | - $phpcsFile->addWarning($error, 0, 'FoundWithSymbols', $data); |
|
53 | - $phpcsFile->recordMetric($stackPtr, 'Declarations and side effects mixed', 'yes'); |
|
54 | - } else { |
|
55 | - $phpcsFile->recordMetric($stackPtr, 'Declarations and side effects mixed', 'no'); |
|
56 | - } |
|
57 | - |
|
58 | - // Ignore the rest of the file. |
|
59 | - return ($phpcsFile->numTokens + 1); |
|
60 | - |
|
61 | - }//end process() |
|
62 | - |
|
63 | - |
|
64 | - /** |
|
65 | - * Searches for symbol declarations and side effects. |
|
66 | - * |
|
67 | - * Returns the positions of both the first symbol declared and the first |
|
68 | - * side effect in the file. A NULL value for either indicates nothing was |
|
69 | - * found. |
|
70 | - * |
|
71 | - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
72 | - * @param int $start The token to start searching from. |
|
73 | - * @param int $end The token to search to. |
|
74 | - * @param array $tokens The stack of tokens that make up |
|
75 | - * the file. |
|
76 | - * |
|
77 | - * @return array |
|
78 | - */ |
|
79 | - private function searchForConflict($phpcsFile, $start, $end, $tokens) |
|
80 | - { |
|
81 | - $symbols = [ |
|
82 | - T_CLASS => T_CLASS, |
|
83 | - T_INTERFACE => T_INTERFACE, |
|
84 | - T_TRAIT => T_TRAIT, |
|
85 | - T_ENUM => T_ENUM, |
|
86 | - T_FUNCTION => T_FUNCTION, |
|
87 | - ]; |
|
88 | - |
|
89 | - $conditions = [ |
|
90 | - T_IF => T_IF, |
|
91 | - T_ELSE => T_ELSE, |
|
92 | - T_ELSEIF => T_ELSEIF, |
|
93 | - ]; |
|
94 | - |
|
95 | - $checkAnnotations = $phpcsFile->config->annotations; |
|
96 | - |
|
97 | - $firstSymbol = null; |
|
98 | - $firstEffect = null; |
|
99 | - for ($i = $start; $i <= $end; $i++) { |
|
100 | - // Respect phpcs:disable comments. |
|
101 | - if ($checkAnnotations === true |
|
102 | - && $tokens[$i]['code'] === T_PHPCS_DISABLE |
|
103 | - && (empty($tokens[$i]['sniffCodes']) === true |
|
104 | - || isset($tokens[$i]['sniffCodes']['PSR1']) === true |
|
105 | - || isset($tokens[$i]['sniffCodes']['PSR1.Files']) === true |
|
106 | - || isset($tokens[$i]['sniffCodes']['PSR1.Files.SideEffects']) === true) |
|
107 | - ) { |
|
108 | - do { |
|
109 | - $i = $phpcsFile->findNext(T_PHPCS_ENABLE, ($i + 1)); |
|
110 | - } while ($i !== false |
|
111 | - && empty($tokens[$i]['sniffCodes']) === false |
|
112 | - && isset($tokens[$i]['sniffCodes']['PSR1']) === false |
|
113 | - && isset($tokens[$i]['sniffCodes']['PSR1.Files']) === false |
|
114 | - && isset($tokens[$i]['sniffCodes']['PSR1.Files.SideEffects']) === false); |
|
115 | - |
|
116 | - if ($i === false) { |
|
117 | - // The entire rest of the file is disabled, |
|
118 | - // so return what we have so far. |
|
119 | - break; |
|
120 | - } |
|
121 | - |
|
122 | - continue; |
|
123 | - } |
|
124 | - |
|
125 | - // Ignore whitespace and comments. |
|
126 | - if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === true) { |
|
127 | - continue; |
|
128 | - } |
|
129 | - |
|
130 | - // Ignore PHP tags. |
|
131 | - if ($tokens[$i]['code'] === T_OPEN_TAG |
|
132 | - || $tokens[$i]['code'] === T_CLOSE_TAG |
|
133 | - ) { |
|
134 | - continue; |
|
135 | - } |
|
136 | - |
|
137 | - // Ignore shebang. |
|
138 | - if (substr($tokens[$i]['content'], 0, 2) === '#!') { |
|
139 | - continue; |
|
140 | - } |
|
141 | - |
|
142 | - // Ignore logical operators. |
|
143 | - if (isset(Tokens::$booleanOperators[$tokens[$i]['code']]) === true) { |
|
144 | - continue; |
|
145 | - } |
|
146 | - |
|
147 | - // Ignore entire namespace, declare, const and use statements. |
|
148 | - if ($tokens[$i]['code'] === T_NAMESPACE |
|
149 | - || $tokens[$i]['code'] === T_USE |
|
150 | - || $tokens[$i]['code'] === T_DECLARE |
|
151 | - || $tokens[$i]['code'] === T_CONST |
|
152 | - ) { |
|
153 | - if (isset($tokens[$i]['scope_opener']) === true) { |
|
154 | - $i = $tokens[$i]['scope_closer']; |
|
155 | - if ($tokens[$i]['code'] === T_ENDDECLARE) { |
|
156 | - $semicolon = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true); |
|
157 | - if ($semicolon !== false && $tokens[$semicolon]['code'] === T_SEMICOLON) { |
|
158 | - $i = $semicolon; |
|
159 | - } |
|
160 | - } |
|
161 | - } else { |
|
162 | - $semicolon = $phpcsFile->findNext(T_SEMICOLON, ($i + 1)); |
|
163 | - if ($semicolon !== false) { |
|
164 | - $i = $semicolon; |
|
165 | - } |
|
166 | - } |
|
167 | - |
|
168 | - continue; |
|
169 | - } |
|
170 | - |
|
171 | - // Ignore function/class prefixes. |
|
172 | - if (isset(Tokens::$methodPrefixes[$tokens[$i]['code']]) === true) { |
|
173 | - continue; |
|
174 | - } |
|
175 | - |
|
176 | - // Ignore anon classes. |
|
177 | - if ($tokens[$i]['code'] === T_ANON_CLASS) { |
|
178 | - $i = $tokens[$i]['scope_closer']; |
|
179 | - continue; |
|
180 | - } |
|
181 | - |
|
182 | - // Ignore attributes. |
|
183 | - if ($tokens[$i]['code'] === T_ATTRIBUTE |
|
184 | - && isset($tokens[$i]['attribute_closer']) === true |
|
185 | - ) { |
|
186 | - $i = $tokens[$i]['attribute_closer']; |
|
187 | - continue; |
|
188 | - } |
|
189 | - |
|
190 | - // Detect and skip over symbols. |
|
191 | - if (isset($symbols[$tokens[$i]['code']]) === true |
|
192 | - && isset($tokens[$i]['scope_closer']) === true |
|
193 | - ) { |
|
194 | - if ($firstSymbol === null) { |
|
195 | - $firstSymbol = $i; |
|
196 | - } |
|
197 | - |
|
198 | - $i = $tokens[$i]['scope_closer']; |
|
199 | - continue; |
|
200 | - } else if ($tokens[$i]['code'] === T_STRING |
|
201 | - && strtolower($tokens[$i]['content']) === 'define' |
|
202 | - ) { |
|
203 | - $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($i - 1), null, true); |
|
204 | - if ($tokens[$prev]['code'] !== T_OBJECT_OPERATOR |
|
205 | - && $tokens[$prev]['code'] !== T_NULLSAFE_OBJECT_OPERATOR |
|
206 | - && $tokens[$prev]['code'] !== T_DOUBLE_COLON |
|
207 | - && $tokens[$prev]['code'] !== T_FUNCTION |
|
208 | - ) { |
|
209 | - if ($firstSymbol === null) { |
|
210 | - $firstSymbol = $i; |
|
211 | - } |
|
212 | - |
|
213 | - $semicolon = $phpcsFile->findNext(T_SEMICOLON, ($i + 1)); |
|
214 | - if ($semicolon !== false) { |
|
215 | - $i = $semicolon; |
|
216 | - } |
|
217 | - |
|
218 | - continue; |
|
219 | - } |
|
220 | - }//end if |
|
221 | - |
|
222 | - // Special case for defined() as it can be used to see |
|
223 | - // if a constant (a symbol) should be defined or not and |
|
224 | - // doesn't need to use a full conditional block. |
|
225 | - if ($tokens[$i]['code'] === T_STRING |
|
226 | - && strtolower($tokens[$i]['content']) === 'defined' |
|
227 | - ) { |
|
228 | - $openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true); |
|
229 | - if ($openBracket !== false |
|
230 | - && $tokens[$openBracket]['code'] === T_OPEN_PARENTHESIS |
|
231 | - && isset($tokens[$openBracket]['parenthesis_closer']) === true |
|
232 | - ) { |
|
233 | - $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($i - 1), null, true); |
|
234 | - if ($tokens[$prev]['code'] !== T_OBJECT_OPERATOR |
|
235 | - && $tokens[$prev]['code'] !== T_NULLSAFE_OBJECT_OPERATOR |
|
236 | - && $tokens[$prev]['code'] !== T_DOUBLE_COLON |
|
237 | - && $tokens[$prev]['code'] !== T_FUNCTION |
|
238 | - ) { |
|
239 | - $i = $tokens[$openBracket]['parenthesis_closer']; |
|
240 | - continue; |
|
241 | - } |
|
242 | - } |
|
243 | - }//end if |
|
244 | - |
|
245 | - // Conditional statements are allowed in symbol files as long as the |
|
246 | - // contents is only a symbol definition. So don't count these as effects |
|
247 | - // in this case. |
|
248 | - if (isset($conditions[$tokens[$i]['code']]) === true) { |
|
249 | - if (isset($tokens[$i]['scope_opener']) === false) { |
|
250 | - // Probably an "else if", so just ignore. |
|
251 | - continue; |
|
252 | - } |
|
253 | - |
|
254 | - $result = $this->searchForConflict( |
|
255 | - $phpcsFile, |
|
256 | - ($tokens[$i]['scope_opener'] + 1), |
|
257 | - ($tokens[$i]['scope_closer'] - 1), |
|
258 | - $tokens |
|
259 | - ); |
|
260 | - |
|
261 | - if ($result['symbol'] !== null) { |
|
262 | - if ($firstSymbol === null) { |
|
263 | - $firstSymbol = $result['symbol']; |
|
264 | - } |
|
265 | - |
|
266 | - if ($result['effect'] !== null) { |
|
267 | - // Found a conflict. |
|
268 | - $firstEffect = $result['effect']; |
|
269 | - break; |
|
270 | - } |
|
271 | - } |
|
272 | - |
|
273 | - if ($firstEffect === null) { |
|
274 | - $firstEffect = $result['effect']; |
|
275 | - } |
|
276 | - |
|
277 | - $i = $tokens[$i]['scope_closer']; |
|
278 | - continue; |
|
279 | - }//end if |
|
280 | - |
|
281 | - if ($firstEffect === null) { |
|
282 | - $firstEffect = $i; |
|
283 | - } |
|
284 | - |
|
285 | - if ($firstSymbol !== null) { |
|
286 | - // We have a conflict we have to report, so no point continuing. |
|
287 | - break; |
|
288 | - } |
|
289 | - }//end for |
|
290 | - |
|
291 | - return [ |
|
292 | - 'symbol' => $firstSymbol, |
|
293 | - 'effect' => $firstEffect, |
|
294 | - ]; |
|
295 | - |
|
296 | - }//end searchForConflict() |
|
20 | + /** |
|
21 | + * Returns an array of tokens this test wants to listen for. |
|
22 | + * |
|
23 | + * @return array |
|
24 | + */ |
|
25 | + public function register() |
|
26 | + { |
|
27 | + return [T_OPEN_TAG]; |
|
28 | + |
|
29 | + }//end register() |
|
30 | + |
|
31 | + |
|
32 | + /** |
|
33 | + * Processes this sniff, when one of its tokens is encountered. |
|
34 | + * |
|
35 | + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
36 | + * @param int $stackPtr The position of the current token in |
|
37 | + * the token stack. |
|
38 | + * |
|
39 | + * @return void |
|
40 | + */ |
|
41 | + public function process(File $phpcsFile, $stackPtr) |
|
42 | + { |
|
43 | + $tokens = $phpcsFile->getTokens(); |
|
44 | + $result = $this->searchForConflict($phpcsFile, 0, ($phpcsFile->numTokens - 1), $tokens); |
|
45 | + |
|
46 | + if ($result['symbol'] !== null && $result['effect'] !== null) { |
|
47 | + $error = 'A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is defined on line %s and the first side effect is on line %s.'; |
|
48 | + $data = [ |
|
49 | + $tokens[$result['symbol']]['line'], |
|
50 | + $tokens[$result['effect']]['line'], |
|
51 | + ]; |
|
52 | + $phpcsFile->addWarning($error, 0, 'FoundWithSymbols', $data); |
|
53 | + $phpcsFile->recordMetric($stackPtr, 'Declarations and side effects mixed', 'yes'); |
|
54 | + } else { |
|
55 | + $phpcsFile->recordMetric($stackPtr, 'Declarations and side effects mixed', 'no'); |
|
56 | + } |
|
57 | + |
|
58 | + // Ignore the rest of the file. |
|
59 | + return ($phpcsFile->numTokens + 1); |
|
60 | + |
|
61 | + }//end process() |
|
62 | + |
|
63 | + |
|
64 | + /** |
|
65 | + * Searches for symbol declarations and side effects. |
|
66 | + * |
|
67 | + * Returns the positions of both the first symbol declared and the first |
|
68 | + * side effect in the file. A NULL value for either indicates nothing was |
|
69 | + * found. |
|
70 | + * |
|
71 | + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
72 | + * @param int $start The token to start searching from. |
|
73 | + * @param int $end The token to search to. |
|
74 | + * @param array $tokens The stack of tokens that make up |
|
75 | + * the file. |
|
76 | + * |
|
77 | + * @return array |
|
78 | + */ |
|
79 | + private function searchForConflict($phpcsFile, $start, $end, $tokens) |
|
80 | + { |
|
81 | + $symbols = [ |
|
82 | + T_CLASS => T_CLASS, |
|
83 | + T_INTERFACE => T_INTERFACE, |
|
84 | + T_TRAIT => T_TRAIT, |
|
85 | + T_ENUM => T_ENUM, |
|
86 | + T_FUNCTION => T_FUNCTION, |
|
87 | + ]; |
|
88 | + |
|
89 | + $conditions = [ |
|
90 | + T_IF => T_IF, |
|
91 | + T_ELSE => T_ELSE, |
|
92 | + T_ELSEIF => T_ELSEIF, |
|
93 | + ]; |
|
94 | + |
|
95 | + $checkAnnotations = $phpcsFile->config->annotations; |
|
96 | + |
|
97 | + $firstSymbol = null; |
|
98 | + $firstEffect = null; |
|
99 | + for ($i = $start; $i <= $end; $i++) { |
|
100 | + // Respect phpcs:disable comments. |
|
101 | + if ($checkAnnotations === true |
|
102 | + && $tokens[$i]['code'] === T_PHPCS_DISABLE |
|
103 | + && (empty($tokens[$i]['sniffCodes']) === true |
|
104 | + || isset($tokens[$i]['sniffCodes']['PSR1']) === true |
|
105 | + || isset($tokens[$i]['sniffCodes']['PSR1.Files']) === true |
|
106 | + || isset($tokens[$i]['sniffCodes']['PSR1.Files.SideEffects']) === true) |
|
107 | + ) { |
|
108 | + do { |
|
109 | + $i = $phpcsFile->findNext(T_PHPCS_ENABLE, ($i + 1)); |
|
110 | + } while ($i !== false |
|
111 | + && empty($tokens[$i]['sniffCodes']) === false |
|
112 | + && isset($tokens[$i]['sniffCodes']['PSR1']) === false |
|
113 | + && isset($tokens[$i]['sniffCodes']['PSR1.Files']) === false |
|
114 | + && isset($tokens[$i]['sniffCodes']['PSR1.Files.SideEffects']) === false); |
|
115 | + |
|
116 | + if ($i === false) { |
|
117 | + // The entire rest of the file is disabled, |
|
118 | + // so return what we have so far. |
|
119 | + break; |
|
120 | + } |
|
121 | + |
|
122 | + continue; |
|
123 | + } |
|
124 | + |
|
125 | + // Ignore whitespace and comments. |
|
126 | + if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === true) { |
|
127 | + continue; |
|
128 | + } |
|
129 | + |
|
130 | + // Ignore PHP tags. |
|
131 | + if ($tokens[$i]['code'] === T_OPEN_TAG |
|
132 | + || $tokens[$i]['code'] === T_CLOSE_TAG |
|
133 | + ) { |
|
134 | + continue; |
|
135 | + } |
|
136 | + |
|
137 | + // Ignore shebang. |
|
138 | + if (substr($tokens[$i]['content'], 0, 2) === '#!') { |
|
139 | + continue; |
|
140 | + } |
|
141 | + |
|
142 | + // Ignore logical operators. |
|
143 | + if (isset(Tokens::$booleanOperators[$tokens[$i]['code']]) === true) { |
|
144 | + continue; |
|
145 | + } |
|
146 | + |
|
147 | + // Ignore entire namespace, declare, const and use statements. |
|
148 | + if ($tokens[$i]['code'] === T_NAMESPACE |
|
149 | + || $tokens[$i]['code'] === T_USE |
|
150 | + || $tokens[$i]['code'] === T_DECLARE |
|
151 | + || $tokens[$i]['code'] === T_CONST |
|
152 | + ) { |
|
153 | + if (isset($tokens[$i]['scope_opener']) === true) { |
|
154 | + $i = $tokens[$i]['scope_closer']; |
|
155 | + if ($tokens[$i]['code'] === T_ENDDECLARE) { |
|
156 | + $semicolon = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true); |
|
157 | + if ($semicolon !== false && $tokens[$semicolon]['code'] === T_SEMICOLON) { |
|
158 | + $i = $semicolon; |
|
159 | + } |
|
160 | + } |
|
161 | + } else { |
|
162 | + $semicolon = $phpcsFile->findNext(T_SEMICOLON, ($i + 1)); |
|
163 | + if ($semicolon !== false) { |
|
164 | + $i = $semicolon; |
|
165 | + } |
|
166 | + } |
|
167 | + |
|
168 | + continue; |
|
169 | + } |
|
170 | + |
|
171 | + // Ignore function/class prefixes. |
|
172 | + if (isset(Tokens::$methodPrefixes[$tokens[$i]['code']]) === true) { |
|
173 | + continue; |
|
174 | + } |
|
175 | + |
|
176 | + // Ignore anon classes. |
|
177 | + if ($tokens[$i]['code'] === T_ANON_CLASS) { |
|
178 | + $i = $tokens[$i]['scope_closer']; |
|
179 | + continue; |
|
180 | + } |
|
181 | + |
|
182 | + // Ignore attributes. |
|
183 | + if ($tokens[$i]['code'] === T_ATTRIBUTE |
|
184 | + && isset($tokens[$i]['attribute_closer']) === true |
|
185 | + ) { |
|
186 | + $i = $tokens[$i]['attribute_closer']; |
|
187 | + continue; |
|
188 | + } |
|
189 | + |
|
190 | + // Detect and skip over symbols. |
|
191 | + if (isset($symbols[$tokens[$i]['code']]) === true |
|
192 | + && isset($tokens[$i]['scope_closer']) === true |
|
193 | + ) { |
|
194 | + if ($firstSymbol === null) { |
|
195 | + $firstSymbol = $i; |
|
196 | + } |
|
197 | + |
|
198 | + $i = $tokens[$i]['scope_closer']; |
|
199 | + continue; |
|
200 | + } else if ($tokens[$i]['code'] === T_STRING |
|
201 | + && strtolower($tokens[$i]['content']) === 'define' |
|
202 | + ) { |
|
203 | + $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($i - 1), null, true); |
|
204 | + if ($tokens[$prev]['code'] !== T_OBJECT_OPERATOR |
|
205 | + && $tokens[$prev]['code'] !== T_NULLSAFE_OBJECT_OPERATOR |
|
206 | + && $tokens[$prev]['code'] !== T_DOUBLE_COLON |
|
207 | + && $tokens[$prev]['code'] !== T_FUNCTION |
|
208 | + ) { |
|
209 | + if ($firstSymbol === null) { |
|
210 | + $firstSymbol = $i; |
|
211 | + } |
|
212 | + |
|
213 | + $semicolon = $phpcsFile->findNext(T_SEMICOLON, ($i + 1)); |
|
214 | + if ($semicolon !== false) { |
|
215 | + $i = $semicolon; |
|
216 | + } |
|
217 | + |
|
218 | + continue; |
|
219 | + } |
|
220 | + }//end if |
|
221 | + |
|
222 | + // Special case for defined() as it can be used to see |
|
223 | + // if a constant (a symbol) should be defined or not and |
|
224 | + // doesn't need to use a full conditional block. |
|
225 | + if ($tokens[$i]['code'] === T_STRING |
|
226 | + && strtolower($tokens[$i]['content']) === 'defined' |
|
227 | + ) { |
|
228 | + $openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true); |
|
229 | + if ($openBracket !== false |
|
230 | + && $tokens[$openBracket]['code'] === T_OPEN_PARENTHESIS |
|
231 | + && isset($tokens[$openBracket]['parenthesis_closer']) === true |
|
232 | + ) { |
|
233 | + $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($i - 1), null, true); |
|
234 | + if ($tokens[$prev]['code'] !== T_OBJECT_OPERATOR |
|
235 | + && $tokens[$prev]['code'] !== T_NULLSAFE_OBJECT_OPERATOR |
|
236 | + && $tokens[$prev]['code'] !== T_DOUBLE_COLON |
|
237 | + && $tokens[$prev]['code'] !== T_FUNCTION |
|
238 | + ) { |
|
239 | + $i = $tokens[$openBracket]['parenthesis_closer']; |
|
240 | + continue; |
|
241 | + } |
|
242 | + } |
|
243 | + }//end if |
|
244 | + |
|
245 | + // Conditional statements are allowed in symbol files as long as the |
|
246 | + // contents is only a symbol definition. So don't count these as effects |
|
247 | + // in this case. |
|
248 | + if (isset($conditions[$tokens[$i]['code']]) === true) { |
|
249 | + if (isset($tokens[$i]['scope_opener']) === false) { |
|
250 | + // Probably an "else if", so just ignore. |
|
251 | + continue; |
|
252 | + } |
|
253 | + |
|
254 | + $result = $this->searchForConflict( |
|
255 | + $phpcsFile, |
|
256 | + ($tokens[$i]['scope_opener'] + 1), |
|
257 | + ($tokens[$i]['scope_closer'] - 1), |
|
258 | + $tokens |
|
259 | + ); |
|
260 | + |
|
261 | + if ($result['symbol'] !== null) { |
|
262 | + if ($firstSymbol === null) { |
|
263 | + $firstSymbol = $result['symbol']; |
|
264 | + } |
|
265 | + |
|
266 | + if ($result['effect'] !== null) { |
|
267 | + // Found a conflict. |
|
268 | + $firstEffect = $result['effect']; |
|
269 | + break; |
|
270 | + } |
|
271 | + } |
|
272 | + |
|
273 | + if ($firstEffect === null) { |
|
274 | + $firstEffect = $result['effect']; |
|
275 | + } |
|
276 | + |
|
277 | + $i = $tokens[$i]['scope_closer']; |
|
278 | + continue; |
|
279 | + }//end if |
|
280 | + |
|
281 | + if ($firstEffect === null) { |
|
282 | + $firstEffect = $i; |
|
283 | + } |
|
284 | + |
|
285 | + if ($firstSymbol !== null) { |
|
286 | + // We have a conflict we have to report, so no point continuing. |
|
287 | + break; |
|
288 | + } |
|
289 | + }//end for |
|
290 | + |
|
291 | + return [ |
|
292 | + 'symbol' => $firstSymbol, |
|
293 | + 'effect' => $firstEffect, |
|
294 | + ]; |
|
295 | + |
|
296 | + }//end searchForConflict() |
|
297 | 297 | |
298 | 298 | |
299 | 299 | }//end class |
@@ -2,69 +2,69 @@ |
||
2 | 2 | |
3 | 3 | function test() |
4 | 4 | { |
5 | - // Body here. |
|
5 | + // Body here. |
|
6 | 6 | } |
7 | 7 | |
8 | 8 | function test() |
9 | 9 | { |
10 | - echo 'foo';} |
|
10 | + echo 'foo';} |
|
11 | 11 | |
12 | 12 | function test() |
13 | 13 | { |
14 | - // Body here. |
|
14 | + // Body here. |
|
15 | 15 | |
16 | 16 | } |
17 | 17 | |
18 | 18 | function test() |
19 | 19 | { |
20 | - // Body here. |
|
20 | + // Body here. |
|
21 | 21 | |
22 | 22 | |
23 | 23 | } |
24 | 24 | |
25 | 25 | class MyClass |
26 | 26 | { |
27 | - function test() |
|
28 | - { |
|
29 | - // Body here. |
|
30 | - } |
|
27 | + function test() |
|
28 | + { |
|
29 | + // Body here. |
|
30 | + } |
|
31 | 31 | |
32 | - function test() |
|
33 | - { |
|
34 | - echo 'foo';} |
|
32 | + function test() |
|
33 | + { |
|
34 | + echo 'foo';} |
|
35 | 35 | |
36 | - function test() |
|
37 | - { |
|
38 | - // Body here. |
|
36 | + function test() |
|
37 | + { |
|
38 | + // Body here. |
|
39 | 39 | |
40 | - } |
|
40 | + } |
|
41 | 41 | |
42 | - function test() |
|
43 | - { |
|
44 | - // Body here. |
|
42 | + function test() |
|
43 | + { |
|
44 | + // Body here. |
|
45 | 45 | |
46 | 46 | |
47 | - } |
|
47 | + } |
|
48 | 48 | } |
49 | 49 | |
50 | 50 | $foo = function test() |
51 | 51 | { |
52 | - // Body here. |
|
52 | + // Body here. |
|
53 | 53 | }; |
54 | 54 | |
55 | 55 | $foo = function test() |
56 | 56 | { |
57 | - echo 'foo';}; |
|
57 | + echo 'foo';}; |
|
58 | 58 | |
59 | 59 | $foo = function test() |
60 | 60 | { |
61 | - // Body here. |
|
61 | + // Body here. |
|
62 | 62 | |
63 | 63 | }; |
64 | 64 | |
65 | 65 | $foo = function test() |
66 | 66 | { |
67 | - // Body here. |
|
67 | + // Body here. |
|
68 | 68 | |
69 | 69 | |
70 | 70 | }; |
@@ -7,7 +7,7 @@ discard block |
||
7 | 7 | |
8 | 8 | function test() |
9 | 9 | { |
10 | - echo 'foo';} |
|
10 | + echo 'foo'; } |
|
11 | 11 | |
12 | 12 | function test() |
13 | 13 | { |
@@ -31,7 +31,7 @@ discard block |
||
31 | 31 | |
32 | 32 | function test() |
33 | 33 | { |
34 | - echo 'foo';} |
|
34 | + echo 'foo'; } |
|
35 | 35 | |
36 | 36 | function test() |
37 | 37 | { |
@@ -54,7 +54,7 @@ discard block |
||
54 | 54 | |
55 | 55 | $foo = function test() |
56 | 56 | { |
57 | - echo 'foo';}; |
|
57 | + echo 'foo'; }; |
|
58 | 58 | |
59 | 59 | $foo = function test() |
60 | 60 | { |
@@ -15,41 +15,41 @@ |
||
15 | 15 | { |
16 | 16 | |
17 | 17 | |
18 | - /** |
|
19 | - * Returns the lines where errors should occur. |
|
20 | - * |
|
21 | - * The key of the array should represent the line number and the value |
|
22 | - * should represent the number of errors that should occur on that line. |
|
23 | - * |
|
24 | - * @return array<int, int> |
|
25 | - */ |
|
26 | - public function getErrorList() |
|
27 | - { |
|
28 | - return [ |
|
29 | - 16 => 1, |
|
30 | - 23 => 1, |
|
31 | - 40 => 1, |
|
32 | - 47 => 1, |
|
33 | - 63 => 1, |
|
34 | - 70 => 1, |
|
35 | - ]; |
|
36 | - |
|
37 | - }//end getErrorList() |
|
38 | - |
|
39 | - |
|
40 | - /** |
|
41 | - * Returns the lines where warnings should occur. |
|
42 | - * |
|
43 | - * The key of the array should represent the line number and the value |
|
44 | - * should represent the number of warnings that should occur on that line. |
|
45 | - * |
|
46 | - * @return array<int, int> |
|
47 | - */ |
|
48 | - public function getWarningList() |
|
49 | - { |
|
50 | - return []; |
|
51 | - |
|
52 | - }//end getWarningList() |
|
18 | + /** |
|
19 | + * Returns the lines where errors should occur. |
|
20 | + * |
|
21 | + * The key of the array should represent the line number and the value |
|
22 | + * should represent the number of errors that should occur on that line. |
|
23 | + * |
|
24 | + * @return array<int, int> |
|
25 | + */ |
|
26 | + public function getErrorList() |
|
27 | + { |
|
28 | + return [ |
|
29 | + 16 => 1, |
|
30 | + 23 => 1, |
|
31 | + 40 => 1, |
|
32 | + 47 => 1, |
|
33 | + 63 => 1, |
|
34 | + 70 => 1, |
|
35 | + ]; |
|
36 | + |
|
37 | + }//end getErrorList() |
|
38 | + |
|
39 | + |
|
40 | + /** |
|
41 | + * Returns the lines where warnings should occur. |
|
42 | + * |
|
43 | + * The key of the array should represent the line number and the value |
|
44 | + * should represent the number of warnings that should occur on that line. |
|
45 | + * |
|
46 | + * @return array<int, int> |
|
47 | + */ |
|
48 | + public function getWarningList() |
|
49 | + { |
|
50 | + return []; |
|
51 | + |
|
52 | + }//end getWarningList() |
|
53 | 53 | |
54 | 54 | |
55 | 55 | }//end class |