@@ -16,36 +16,36 @@ |
||
16 | 16 | { |
17 | 17 | |
18 | 18 | |
19 | - /** |
|
20 | - * Returns an array of tokens this test wants to listen for. |
|
21 | - * |
|
22 | - * @return array |
|
23 | - */ |
|
24 | - public function register() |
|
25 | - { |
|
26 | - return [ |
|
27 | - T_START_HEREDOC, |
|
28 | - T_START_NOWDOC, |
|
29 | - ]; |
|
30 | - |
|
31 | - }//end register() |
|
32 | - |
|
33 | - |
|
34 | - /** |
|
35 | - * Processes this test, when one of its tokens is encountered. |
|
36 | - * |
|
37 | - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
38 | - * @param int $stackPtr The position of the current token in the |
|
39 | - * stack passed in $tokens. |
|
40 | - * |
|
41 | - * @return void |
|
42 | - */ |
|
43 | - public function process(File $phpcsFile, $stackPtr) |
|
44 | - { |
|
45 | - $error = 'Use of heredoc and nowdoc syntax ("<<<") is not allowed; use standard strings or inline HTML instead'; |
|
46 | - $phpcsFile->addError($error, $stackPtr, 'NotAllowed'); |
|
47 | - |
|
48 | - }//end process() |
|
19 | + /** |
|
20 | + * Returns an array of tokens this test wants to listen for. |
|
21 | + * |
|
22 | + * @return array |
|
23 | + */ |
|
24 | + public function register() |
|
25 | + { |
|
26 | + return [ |
|
27 | + T_START_HEREDOC, |
|
28 | + T_START_NOWDOC, |
|
29 | + ]; |
|
30 | + |
|
31 | + }//end register() |
|
32 | + |
|
33 | + |
|
34 | + /** |
|
35 | + * Processes this test, when one of its tokens is encountered. |
|
36 | + * |
|
37 | + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
38 | + * @param int $stackPtr The position of the current token in the |
|
39 | + * stack passed in $tokens. |
|
40 | + * |
|
41 | + * @return void |
|
42 | + */ |
|
43 | + public function process(File $phpcsFile, $stackPtr) |
|
44 | + { |
|
45 | + $error = 'Use of heredoc and nowdoc syntax ("<<<") is not allowed; use standard strings or inline HTML instead'; |
|
46 | + $phpcsFile->addError($error, $stackPtr, 'NotAllowed'); |
|
47 | + |
|
48 | + }//end process() |
|
49 | 49 | |
50 | 50 | |
51 | 51 | }//end class |
@@ -121,7 +121,7 @@ discard block |
||
121 | 121 | $i = $stackPtr; |
122 | 122 | do { |
123 | 123 | $i++; |
124 | - } while ($tokens[$i]['line'] !== ($tokens[$stackPtr]['line'] + 1)); |
|
124 | + }while ($tokens[$i]['line'] !== ($tokens[$stackPtr]['line'] + 1)); |
|
125 | 125 | |
126 | 126 | $error = 'Blank line found at start of embedded PHP content'; |
127 | 127 | $fix = $phpcsFile->addFixableError($error, $i, 'SpacingBefore'); |
@@ -156,7 +156,7 @@ discard block |
||
156 | 156 | $indent, |
157 | 157 | $contentColumn, |
158 | 158 | ]; |
159 | - $fix = $phpcsFile->addFixableError($error, $firstContent, 'Indent', $data); |
|
159 | + $fix = $phpcsFile->addFixableError($error, $firstContent, 'Indent', $data); |
|
160 | 160 | if ($fix === true) { |
161 | 161 | $padding = str_repeat(' ', $indent); |
162 | 162 | if ($contentColumn === 0) { |
@@ -214,7 +214,7 @@ discard block |
||
214 | 214 | $expected, |
215 | 215 | $found, |
216 | 216 | ]; |
217 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'OpenTagIndent', $data); |
|
217 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'OpenTagIndent', $data); |
|
218 | 218 | if ($fix === true) { |
219 | 219 | $phpcsFile->fixer->replaceToken(($stackPtr - 1), str_repeat(' ', $expected)); |
220 | 220 | } |
@@ -264,7 +264,7 @@ discard block |
||
264 | 264 | $i = $closingTag; |
265 | 265 | do { |
266 | 266 | $i--; |
267 | - } while ($tokens[$i]['line'] !== ($tokens[$closingTag]['line'] - 1)); |
|
267 | + }while ($tokens[$i]['line'] !== ($tokens[$closingTag]['line'] - 1)); |
|
268 | 268 | |
269 | 269 | $error = 'Blank line found at end of embedded PHP content'; |
270 | 270 | $fix = $phpcsFile->addFixableError($error, $i, 'SpacingAfter'); |
@@ -17,386 +17,386 @@ |
||
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 test, 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 the |
|
37 | - * stack passed in $tokens. |
|
38 | - * |
|
39 | - * @return void |
|
40 | - */ |
|
41 | - public function process(File $phpcsFile, $stackPtr) |
|
42 | - { |
|
43 | - $tokens = $phpcsFile->getTokens(); |
|
44 | - |
|
45 | - // If the close php tag is on the same line as the opening |
|
46 | - // then we have an inline embedded PHP block. |
|
47 | - $closeTag = $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr); |
|
48 | - if ($closeTag === false || $tokens[$stackPtr]['line'] !== $tokens[$closeTag]['line']) { |
|
49 | - $this->validateMultilineEmbeddedPhp($phpcsFile, $stackPtr); |
|
50 | - } else { |
|
51 | - $this->validateInlineEmbeddedPhp($phpcsFile, $stackPtr); |
|
52 | - } |
|
53 | - |
|
54 | - }//end process() |
|
55 | - |
|
56 | - |
|
57 | - /** |
|
58 | - * Validates embedded PHP that exists on multiple lines. |
|
59 | - * |
|
60 | - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
61 | - * @param int $stackPtr The position of the current token in the |
|
62 | - * stack passed in $tokens. |
|
63 | - * |
|
64 | - * @return void |
|
65 | - */ |
|
66 | - private function validateMultilineEmbeddedPhp($phpcsFile, $stackPtr) |
|
67 | - { |
|
68 | - $tokens = $phpcsFile->getTokens(); |
|
69 | - |
|
70 | - $prevTag = $phpcsFile->findPrevious(T_OPEN_TAG, ($stackPtr - 1)); |
|
71 | - if ($prevTag === false) { |
|
72 | - // This is the first open tag. |
|
73 | - return; |
|
74 | - } |
|
75 | - |
|
76 | - $firstContent = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true); |
|
77 | - $closingTag = $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr); |
|
78 | - if ($closingTag !== false) { |
|
79 | - $nextContent = $phpcsFile->findNext(T_WHITESPACE, ($closingTag + 1), $phpcsFile->numTokens, true); |
|
80 | - if ($nextContent === false) { |
|
81 | - // Final closing tag. It will be handled elsewhere. |
|
82 | - return; |
|
83 | - } |
|
84 | - |
|
85 | - // We have an opening and a closing tag, that lie within other content. |
|
86 | - if ($firstContent === $closingTag) { |
|
87 | - $error = 'Empty embedded PHP tag found'; |
|
88 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Empty'); |
|
89 | - if ($fix === true) { |
|
90 | - $phpcsFile->fixer->beginChangeset(); |
|
91 | - for ($i = $stackPtr; $i <= $closingTag; $i++) { |
|
92 | - $phpcsFile->fixer->replaceToken($i, ''); |
|
93 | - } |
|
94 | - |
|
95 | - $phpcsFile->fixer->endChangeset(); |
|
96 | - } |
|
97 | - |
|
98 | - return; |
|
99 | - } |
|
100 | - }//end if |
|
101 | - |
|
102 | - if ($tokens[$firstContent]['line'] === $tokens[$stackPtr]['line']) { |
|
103 | - $error = 'Opening PHP tag must be on a line by itself'; |
|
104 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'ContentAfterOpen'); |
|
105 | - if ($fix === true) { |
|
106 | - $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr, true); |
|
107 | - $padding = (strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']))); |
|
108 | - $phpcsFile->fixer->beginChangeset(); |
|
109 | - $phpcsFile->fixer->addNewline($stackPtr); |
|
110 | - $phpcsFile->fixer->addContent($stackPtr, str_repeat(' ', $padding)); |
|
111 | - $phpcsFile->fixer->endChangeset(); |
|
112 | - } |
|
113 | - } else { |
|
114 | - // Check the indent of the first line, except if it is a scope closer. |
|
115 | - if (isset($tokens[$firstContent]['scope_closer']) === false |
|
116 | - || $tokens[$firstContent]['scope_closer'] !== $firstContent |
|
117 | - ) { |
|
118 | - // Check for a blank line at the top. |
|
119 | - if ($tokens[$firstContent]['line'] > ($tokens[$stackPtr]['line'] + 1)) { |
|
120 | - // Find a token on the blank line to throw the error on. |
|
121 | - $i = $stackPtr; |
|
122 | - do { |
|
123 | - $i++; |
|
124 | - } while ($tokens[$i]['line'] !== ($tokens[$stackPtr]['line'] + 1)); |
|
125 | - |
|
126 | - $error = 'Blank line found at start of embedded PHP content'; |
|
127 | - $fix = $phpcsFile->addFixableError($error, $i, 'SpacingBefore'); |
|
128 | - if ($fix === true) { |
|
129 | - $phpcsFile->fixer->beginChangeset(); |
|
130 | - for ($i = ($stackPtr + 1); $i < $firstContent; $i++) { |
|
131 | - if ($tokens[$i]['line'] === $tokens[$firstContent]['line'] |
|
132 | - || $tokens[$i]['line'] === $tokens[$stackPtr]['line'] |
|
133 | - ) { |
|
134 | - continue; |
|
135 | - } |
|
136 | - |
|
137 | - $phpcsFile->fixer->replaceToken($i, ''); |
|
138 | - } |
|
139 | - |
|
140 | - $phpcsFile->fixer->endChangeset(); |
|
141 | - } |
|
142 | - }//end if |
|
143 | - |
|
144 | - $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr); |
|
145 | - if ($first === false) { |
|
146 | - $first = $phpcsFile->findFirstOnLine(T_INLINE_HTML, $stackPtr); |
|
147 | - $indent = (strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']))); |
|
148 | - } else { |
|
149 | - $indent = ($tokens[($first + 1)]['column'] - 1); |
|
150 | - } |
|
151 | - |
|
152 | - $contentColumn = ($tokens[$firstContent]['column'] - 1); |
|
153 | - if ($contentColumn !== $indent) { |
|
154 | - $error = 'First line of embedded PHP code must be indented %s spaces; %s found'; |
|
155 | - $data = [ |
|
156 | - $indent, |
|
157 | - $contentColumn, |
|
158 | - ]; |
|
159 | - $fix = $phpcsFile->addFixableError($error, $firstContent, 'Indent', $data); |
|
160 | - if ($fix === true) { |
|
161 | - $padding = str_repeat(' ', $indent); |
|
162 | - if ($contentColumn === 0) { |
|
163 | - $phpcsFile->fixer->addContentBefore($firstContent, $padding); |
|
164 | - } else { |
|
165 | - $phpcsFile->fixer->replaceToken(($firstContent - 1), $padding); |
|
166 | - } |
|
167 | - } |
|
168 | - } |
|
169 | - }//end if |
|
170 | - }//end if |
|
171 | - |
|
172 | - $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); |
|
173 | - if ($tokens[$lastContent]['line'] === $tokens[$stackPtr]['line'] |
|
174 | - && trim($tokens[$lastContent]['content']) !== '' |
|
175 | - ) { |
|
176 | - $error = 'Opening PHP tag must be on a line by itself'; |
|
177 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'ContentBeforeOpen'); |
|
178 | - if ($fix === true) { |
|
179 | - $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr); |
|
180 | - if ($first === false) { |
|
181 | - $first = $phpcsFile->findFirstOnLine(T_INLINE_HTML, $stackPtr); |
|
182 | - $padding = (strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']))); |
|
183 | - } else { |
|
184 | - $padding = ($tokens[($first + 1)]['column'] - 1); |
|
185 | - } |
|
186 | - |
|
187 | - $phpcsFile->fixer->addContentBefore($stackPtr, $phpcsFile->eolChar.str_repeat(' ', $padding)); |
|
188 | - } |
|
189 | - } else { |
|
190 | - // Find the first token on the first non-empty line we find. |
|
191 | - for ($first = ($stackPtr - 1); $first > 0; $first--) { |
|
192 | - if ($tokens[$first]['line'] === $tokens[$stackPtr]['line']) { |
|
193 | - continue; |
|
194 | - } else if (trim($tokens[$first]['content']) !== '') { |
|
195 | - $first = $phpcsFile->findFirstOnLine([], $first, true); |
|
196 | - break; |
|
197 | - } |
|
198 | - } |
|
199 | - |
|
200 | - $expected = 0; |
|
201 | - if ($tokens[$first]['code'] === T_INLINE_HTML |
|
202 | - && trim($tokens[$first]['content']) !== '' |
|
203 | - ) { |
|
204 | - $expected = (strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']))); |
|
205 | - } else if ($tokens[$first]['code'] === T_WHITESPACE) { |
|
206 | - $expected = ($tokens[($first + 1)]['column'] - 1); |
|
207 | - } |
|
208 | - |
|
209 | - $expected += 4; |
|
210 | - $found = ($tokens[$stackPtr]['column'] - 1); |
|
211 | - if ($found > $expected) { |
|
212 | - $error = 'Opening PHP tag indent incorrect; expected no more than %s spaces but found %s'; |
|
213 | - $data = [ |
|
214 | - $expected, |
|
215 | - $found, |
|
216 | - ]; |
|
217 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'OpenTagIndent', $data); |
|
218 | - if ($fix === true) { |
|
219 | - $phpcsFile->fixer->replaceToken(($stackPtr - 1), str_repeat(' ', $expected)); |
|
220 | - } |
|
221 | - } |
|
222 | - }//end if |
|
223 | - |
|
224 | - if ($closingTag === false) { |
|
225 | - return; |
|
226 | - } |
|
227 | - |
|
228 | - $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, ($closingTag - 1), ($stackPtr + 1), true); |
|
229 | - $nextContent = $phpcsFile->findNext(T_WHITESPACE, ($closingTag + 1), null, true); |
|
230 | - |
|
231 | - if ($tokens[$lastContent]['line'] === $tokens[$closingTag]['line']) { |
|
232 | - $error = 'Closing PHP tag must be on a line by itself'; |
|
233 | - $fix = $phpcsFile->addFixableError($error, $closingTag, 'ContentBeforeEnd'); |
|
234 | - if ($fix === true) { |
|
235 | - $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $closingTag, true); |
|
236 | - $phpcsFile->fixer->beginChangeset(); |
|
237 | - $phpcsFile->fixer->addContentBefore($closingTag, str_repeat(' ', ($tokens[$first]['column'] - 1))); |
|
238 | - $phpcsFile->fixer->addNewlineBefore($closingTag); |
|
239 | - $phpcsFile->fixer->endChangeset(); |
|
240 | - } |
|
241 | - } else if ($tokens[$nextContent]['line'] === $tokens[$closingTag]['line']) { |
|
242 | - $error = 'Closing PHP tag must be on a line by itself'; |
|
243 | - $fix = $phpcsFile->addFixableError($error, $closingTag, 'ContentAfterEnd'); |
|
244 | - if ($fix === true) { |
|
245 | - $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $closingTag, true); |
|
246 | - $phpcsFile->fixer->beginChangeset(); |
|
247 | - $phpcsFile->fixer->addNewline($closingTag); |
|
248 | - $phpcsFile->fixer->addContent($closingTag, str_repeat(' ', ($tokens[$first]['column'] - 1))); |
|
249 | - $phpcsFile->fixer->endChangeset(); |
|
250 | - } |
|
251 | - }//end if |
|
252 | - |
|
253 | - $next = $phpcsFile->findNext(T_OPEN_TAG, ($closingTag + 1)); |
|
254 | - if ($next === false) { |
|
255 | - return; |
|
256 | - } |
|
257 | - |
|
258 | - // Check for a blank line at the bottom. |
|
259 | - if ((isset($tokens[$lastContent]['scope_closer']) === false |
|
260 | - || $tokens[$lastContent]['scope_closer'] !== $lastContent) |
|
261 | - && $tokens[$lastContent]['line'] < ($tokens[$closingTag]['line'] - 1) |
|
262 | - ) { |
|
263 | - // Find a token on the blank line to throw the error on. |
|
264 | - $i = $closingTag; |
|
265 | - do { |
|
266 | - $i--; |
|
267 | - } while ($tokens[$i]['line'] !== ($tokens[$closingTag]['line'] - 1)); |
|
268 | - |
|
269 | - $error = 'Blank line found at end of embedded PHP content'; |
|
270 | - $fix = $phpcsFile->addFixableError($error, $i, 'SpacingAfter'); |
|
271 | - if ($fix === true) { |
|
272 | - $phpcsFile->fixer->beginChangeset(); |
|
273 | - for ($i = ($lastContent + 1); $i < $closingTag; $i++) { |
|
274 | - if ($tokens[$i]['line'] === $tokens[$lastContent]['line'] |
|
275 | - || $tokens[$i]['line'] === $tokens[$closingTag]['line'] |
|
276 | - ) { |
|
277 | - continue; |
|
278 | - } |
|
279 | - |
|
280 | - $phpcsFile->fixer->replaceToken($i, ''); |
|
281 | - } |
|
282 | - |
|
283 | - $phpcsFile->fixer->endChangeset(); |
|
284 | - } |
|
285 | - }//end if |
|
286 | - |
|
287 | - }//end validateMultilineEmbeddedPhp() |
|
288 | - |
|
289 | - |
|
290 | - /** |
|
291 | - * Validates embedded PHP that exists on one line. |
|
292 | - * |
|
293 | - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
294 | - * @param int $stackPtr The position of the current token in the |
|
295 | - * stack passed in $tokens. |
|
296 | - * |
|
297 | - * @return void |
|
298 | - */ |
|
299 | - private function validateInlineEmbeddedPhp($phpcsFile, $stackPtr) |
|
300 | - { |
|
301 | - $tokens = $phpcsFile->getTokens(); |
|
302 | - |
|
303 | - // We only want one line PHP sections, so return if the closing tag is |
|
304 | - // on the next line. |
|
305 | - $closeTag = $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr, null, false); |
|
306 | - if ($tokens[$stackPtr]['line'] !== $tokens[$closeTag]['line']) { |
|
307 | - return; |
|
308 | - } |
|
309 | - |
|
310 | - // Check that there is one, and only one space at the start of the statement. |
|
311 | - $firstContent = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), $closeTag, true); |
|
312 | - |
|
313 | - if ($firstContent === false) { |
|
314 | - $error = 'Empty embedded PHP tag found'; |
|
315 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Empty'); |
|
316 | - if ($fix === true) { |
|
317 | - $phpcsFile->fixer->beginChangeset(); |
|
318 | - for ($i = $stackPtr; $i <= $closeTag; $i++) { |
|
319 | - $phpcsFile->fixer->replaceToken($i, ''); |
|
320 | - } |
|
321 | - |
|
322 | - $phpcsFile->fixer->endChangeset(); |
|
323 | - } |
|
324 | - |
|
325 | - return; |
|
326 | - } |
|
327 | - |
|
328 | - // The open tag token always contains a single space after it. |
|
329 | - $leadingSpace = 1; |
|
330 | - if ($tokens[($stackPtr + 1)]['code'] === T_WHITESPACE) { |
|
331 | - $leadingSpace = ($tokens[($stackPtr + 1)]['length'] + 1); |
|
332 | - } |
|
333 | - |
|
334 | - if ($leadingSpace !== 1) { |
|
335 | - $error = 'Expected 1 space after opening PHP tag; %s found'; |
|
336 | - $data = [$leadingSpace]; |
|
337 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingAfterOpen', $data); |
|
338 | - if ($fix === true) { |
|
339 | - $phpcsFile->fixer->replaceToken(($stackPtr + 1), ''); |
|
340 | - } |
|
341 | - } |
|
342 | - |
|
343 | - $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($closeTag - 1), $stackPtr, true); |
|
344 | - if ($prev !== $stackPtr) { |
|
345 | - if ((isset($tokens[$prev]['scope_opener']) === false |
|
346 | - || $tokens[$prev]['scope_opener'] !== $prev) |
|
347 | - && (isset($tokens[$prev]['scope_closer']) === false |
|
348 | - || $tokens[$prev]['scope_closer'] !== $prev) |
|
349 | - && $tokens[$prev]['code'] !== T_SEMICOLON |
|
350 | - ) { |
|
351 | - $error = 'Inline PHP statement must end with a semicolon'; |
|
352 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSemicolon'); |
|
353 | - if ($fix === true) { |
|
354 | - $phpcsFile->fixer->addContent($prev, ';'); |
|
355 | - } |
|
356 | - } else if ($tokens[$prev]['code'] === T_SEMICOLON) { |
|
357 | - $statementCount = 1; |
|
358 | - for ($i = ($stackPtr + 1); $i < $prev; $i++) { |
|
359 | - if ($tokens[$i]['code'] === T_SEMICOLON) { |
|
360 | - $statementCount++; |
|
361 | - } |
|
362 | - } |
|
363 | - |
|
364 | - if ($statementCount > 1) { |
|
365 | - $error = 'Inline PHP statement must contain a single statement; %s found'; |
|
366 | - $data = [$statementCount]; |
|
367 | - $phpcsFile->addError($error, $stackPtr, 'MultipleStatements', $data); |
|
368 | - } |
|
369 | - } |
|
370 | - }//end if |
|
371 | - |
|
372 | - $trailingSpace = 0; |
|
373 | - if ($tokens[($closeTag - 1)]['code'] === T_WHITESPACE) { |
|
374 | - $trailingSpace = $tokens[($closeTag - 1)]['length']; |
|
375 | - } else if (($tokens[($closeTag - 1)]['code'] === T_COMMENT |
|
376 | - || isset(Tokens::$phpcsCommentTokens[$tokens[($closeTag - 1)]['code']]) === true) |
|
377 | - && substr($tokens[($closeTag - 1)]['content'], -1) === ' ' |
|
378 | - ) { |
|
379 | - $trailingSpace = (strlen($tokens[($closeTag - 1)]['content']) - strlen(rtrim($tokens[($closeTag - 1)]['content']))); |
|
380 | - } |
|
381 | - |
|
382 | - if ($trailingSpace !== 1) { |
|
383 | - $error = 'Expected 1 space before closing PHP tag; %s found'; |
|
384 | - $data = [$trailingSpace]; |
|
385 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingBeforeClose', $data); |
|
386 | - if ($fix === true) { |
|
387 | - if ($trailingSpace === 0) { |
|
388 | - $phpcsFile->fixer->addContentBefore($closeTag, ' '); |
|
389 | - } else if ($tokens[($closeTag - 1)]['code'] === T_COMMENT |
|
390 | - || isset(Tokens::$phpcsCommentTokens[$tokens[($closeTag - 1)]['code']]) === true |
|
391 | - ) { |
|
392 | - $phpcsFile->fixer->replaceToken(($closeTag - 1), rtrim($tokens[($closeTag - 1)]['content']).' '); |
|
393 | - } else { |
|
394 | - $phpcsFile->fixer->replaceToken(($closeTag - 1), ' '); |
|
395 | - } |
|
396 | - } |
|
397 | - } |
|
398 | - |
|
399 | - }//end validateInlineEmbeddedPhp() |
|
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 test, 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 the |
|
37 | + * stack passed in $tokens. |
|
38 | + * |
|
39 | + * @return void |
|
40 | + */ |
|
41 | + public function process(File $phpcsFile, $stackPtr) |
|
42 | + { |
|
43 | + $tokens = $phpcsFile->getTokens(); |
|
44 | + |
|
45 | + // If the close php tag is on the same line as the opening |
|
46 | + // then we have an inline embedded PHP block. |
|
47 | + $closeTag = $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr); |
|
48 | + if ($closeTag === false || $tokens[$stackPtr]['line'] !== $tokens[$closeTag]['line']) { |
|
49 | + $this->validateMultilineEmbeddedPhp($phpcsFile, $stackPtr); |
|
50 | + } else { |
|
51 | + $this->validateInlineEmbeddedPhp($phpcsFile, $stackPtr); |
|
52 | + } |
|
53 | + |
|
54 | + }//end process() |
|
55 | + |
|
56 | + |
|
57 | + /** |
|
58 | + * Validates embedded PHP that exists on multiple lines. |
|
59 | + * |
|
60 | + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
61 | + * @param int $stackPtr The position of the current token in the |
|
62 | + * stack passed in $tokens. |
|
63 | + * |
|
64 | + * @return void |
|
65 | + */ |
|
66 | + private function validateMultilineEmbeddedPhp($phpcsFile, $stackPtr) |
|
67 | + { |
|
68 | + $tokens = $phpcsFile->getTokens(); |
|
69 | + |
|
70 | + $prevTag = $phpcsFile->findPrevious(T_OPEN_TAG, ($stackPtr - 1)); |
|
71 | + if ($prevTag === false) { |
|
72 | + // This is the first open tag. |
|
73 | + return; |
|
74 | + } |
|
75 | + |
|
76 | + $firstContent = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true); |
|
77 | + $closingTag = $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr); |
|
78 | + if ($closingTag !== false) { |
|
79 | + $nextContent = $phpcsFile->findNext(T_WHITESPACE, ($closingTag + 1), $phpcsFile->numTokens, true); |
|
80 | + if ($nextContent === false) { |
|
81 | + // Final closing tag. It will be handled elsewhere. |
|
82 | + return; |
|
83 | + } |
|
84 | + |
|
85 | + // We have an opening and a closing tag, that lie within other content. |
|
86 | + if ($firstContent === $closingTag) { |
|
87 | + $error = 'Empty embedded PHP tag found'; |
|
88 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Empty'); |
|
89 | + if ($fix === true) { |
|
90 | + $phpcsFile->fixer->beginChangeset(); |
|
91 | + for ($i = $stackPtr; $i <= $closingTag; $i++) { |
|
92 | + $phpcsFile->fixer->replaceToken($i, ''); |
|
93 | + } |
|
94 | + |
|
95 | + $phpcsFile->fixer->endChangeset(); |
|
96 | + } |
|
97 | + |
|
98 | + return; |
|
99 | + } |
|
100 | + }//end if |
|
101 | + |
|
102 | + if ($tokens[$firstContent]['line'] === $tokens[$stackPtr]['line']) { |
|
103 | + $error = 'Opening PHP tag must be on a line by itself'; |
|
104 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'ContentAfterOpen'); |
|
105 | + if ($fix === true) { |
|
106 | + $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr, true); |
|
107 | + $padding = (strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']))); |
|
108 | + $phpcsFile->fixer->beginChangeset(); |
|
109 | + $phpcsFile->fixer->addNewline($stackPtr); |
|
110 | + $phpcsFile->fixer->addContent($stackPtr, str_repeat(' ', $padding)); |
|
111 | + $phpcsFile->fixer->endChangeset(); |
|
112 | + } |
|
113 | + } else { |
|
114 | + // Check the indent of the first line, except if it is a scope closer. |
|
115 | + if (isset($tokens[$firstContent]['scope_closer']) === false |
|
116 | + || $tokens[$firstContent]['scope_closer'] !== $firstContent |
|
117 | + ) { |
|
118 | + // Check for a blank line at the top. |
|
119 | + if ($tokens[$firstContent]['line'] > ($tokens[$stackPtr]['line'] + 1)) { |
|
120 | + // Find a token on the blank line to throw the error on. |
|
121 | + $i = $stackPtr; |
|
122 | + do { |
|
123 | + $i++; |
|
124 | + } while ($tokens[$i]['line'] !== ($tokens[$stackPtr]['line'] + 1)); |
|
125 | + |
|
126 | + $error = 'Blank line found at start of embedded PHP content'; |
|
127 | + $fix = $phpcsFile->addFixableError($error, $i, 'SpacingBefore'); |
|
128 | + if ($fix === true) { |
|
129 | + $phpcsFile->fixer->beginChangeset(); |
|
130 | + for ($i = ($stackPtr + 1); $i < $firstContent; $i++) { |
|
131 | + if ($tokens[$i]['line'] === $tokens[$firstContent]['line'] |
|
132 | + || $tokens[$i]['line'] === $tokens[$stackPtr]['line'] |
|
133 | + ) { |
|
134 | + continue; |
|
135 | + } |
|
136 | + |
|
137 | + $phpcsFile->fixer->replaceToken($i, ''); |
|
138 | + } |
|
139 | + |
|
140 | + $phpcsFile->fixer->endChangeset(); |
|
141 | + } |
|
142 | + }//end if |
|
143 | + |
|
144 | + $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr); |
|
145 | + if ($first === false) { |
|
146 | + $first = $phpcsFile->findFirstOnLine(T_INLINE_HTML, $stackPtr); |
|
147 | + $indent = (strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']))); |
|
148 | + } else { |
|
149 | + $indent = ($tokens[($first + 1)]['column'] - 1); |
|
150 | + } |
|
151 | + |
|
152 | + $contentColumn = ($tokens[$firstContent]['column'] - 1); |
|
153 | + if ($contentColumn !== $indent) { |
|
154 | + $error = 'First line of embedded PHP code must be indented %s spaces; %s found'; |
|
155 | + $data = [ |
|
156 | + $indent, |
|
157 | + $contentColumn, |
|
158 | + ]; |
|
159 | + $fix = $phpcsFile->addFixableError($error, $firstContent, 'Indent', $data); |
|
160 | + if ($fix === true) { |
|
161 | + $padding = str_repeat(' ', $indent); |
|
162 | + if ($contentColumn === 0) { |
|
163 | + $phpcsFile->fixer->addContentBefore($firstContent, $padding); |
|
164 | + } else { |
|
165 | + $phpcsFile->fixer->replaceToken(($firstContent - 1), $padding); |
|
166 | + } |
|
167 | + } |
|
168 | + } |
|
169 | + }//end if |
|
170 | + }//end if |
|
171 | + |
|
172 | + $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); |
|
173 | + if ($tokens[$lastContent]['line'] === $tokens[$stackPtr]['line'] |
|
174 | + && trim($tokens[$lastContent]['content']) !== '' |
|
175 | + ) { |
|
176 | + $error = 'Opening PHP tag must be on a line by itself'; |
|
177 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'ContentBeforeOpen'); |
|
178 | + if ($fix === true) { |
|
179 | + $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr); |
|
180 | + if ($first === false) { |
|
181 | + $first = $phpcsFile->findFirstOnLine(T_INLINE_HTML, $stackPtr); |
|
182 | + $padding = (strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']))); |
|
183 | + } else { |
|
184 | + $padding = ($tokens[($first + 1)]['column'] - 1); |
|
185 | + } |
|
186 | + |
|
187 | + $phpcsFile->fixer->addContentBefore($stackPtr, $phpcsFile->eolChar.str_repeat(' ', $padding)); |
|
188 | + } |
|
189 | + } else { |
|
190 | + // Find the first token on the first non-empty line we find. |
|
191 | + for ($first = ($stackPtr - 1); $first > 0; $first--) { |
|
192 | + if ($tokens[$first]['line'] === $tokens[$stackPtr]['line']) { |
|
193 | + continue; |
|
194 | + } else if (trim($tokens[$first]['content']) !== '') { |
|
195 | + $first = $phpcsFile->findFirstOnLine([], $first, true); |
|
196 | + break; |
|
197 | + } |
|
198 | + } |
|
199 | + |
|
200 | + $expected = 0; |
|
201 | + if ($tokens[$first]['code'] === T_INLINE_HTML |
|
202 | + && trim($tokens[$first]['content']) !== '' |
|
203 | + ) { |
|
204 | + $expected = (strlen($tokens[$first]['content']) - strlen(ltrim($tokens[$first]['content']))); |
|
205 | + } else if ($tokens[$first]['code'] === T_WHITESPACE) { |
|
206 | + $expected = ($tokens[($first + 1)]['column'] - 1); |
|
207 | + } |
|
208 | + |
|
209 | + $expected += 4; |
|
210 | + $found = ($tokens[$stackPtr]['column'] - 1); |
|
211 | + if ($found > $expected) { |
|
212 | + $error = 'Opening PHP tag indent incorrect; expected no more than %s spaces but found %s'; |
|
213 | + $data = [ |
|
214 | + $expected, |
|
215 | + $found, |
|
216 | + ]; |
|
217 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'OpenTagIndent', $data); |
|
218 | + if ($fix === true) { |
|
219 | + $phpcsFile->fixer->replaceToken(($stackPtr - 1), str_repeat(' ', $expected)); |
|
220 | + } |
|
221 | + } |
|
222 | + }//end if |
|
223 | + |
|
224 | + if ($closingTag === false) { |
|
225 | + return; |
|
226 | + } |
|
227 | + |
|
228 | + $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, ($closingTag - 1), ($stackPtr + 1), true); |
|
229 | + $nextContent = $phpcsFile->findNext(T_WHITESPACE, ($closingTag + 1), null, true); |
|
230 | + |
|
231 | + if ($tokens[$lastContent]['line'] === $tokens[$closingTag]['line']) { |
|
232 | + $error = 'Closing PHP tag must be on a line by itself'; |
|
233 | + $fix = $phpcsFile->addFixableError($error, $closingTag, 'ContentBeforeEnd'); |
|
234 | + if ($fix === true) { |
|
235 | + $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $closingTag, true); |
|
236 | + $phpcsFile->fixer->beginChangeset(); |
|
237 | + $phpcsFile->fixer->addContentBefore($closingTag, str_repeat(' ', ($tokens[$first]['column'] - 1))); |
|
238 | + $phpcsFile->fixer->addNewlineBefore($closingTag); |
|
239 | + $phpcsFile->fixer->endChangeset(); |
|
240 | + } |
|
241 | + } else if ($tokens[$nextContent]['line'] === $tokens[$closingTag]['line']) { |
|
242 | + $error = 'Closing PHP tag must be on a line by itself'; |
|
243 | + $fix = $phpcsFile->addFixableError($error, $closingTag, 'ContentAfterEnd'); |
|
244 | + if ($fix === true) { |
|
245 | + $first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $closingTag, true); |
|
246 | + $phpcsFile->fixer->beginChangeset(); |
|
247 | + $phpcsFile->fixer->addNewline($closingTag); |
|
248 | + $phpcsFile->fixer->addContent($closingTag, str_repeat(' ', ($tokens[$first]['column'] - 1))); |
|
249 | + $phpcsFile->fixer->endChangeset(); |
|
250 | + } |
|
251 | + }//end if |
|
252 | + |
|
253 | + $next = $phpcsFile->findNext(T_OPEN_TAG, ($closingTag + 1)); |
|
254 | + if ($next === false) { |
|
255 | + return; |
|
256 | + } |
|
257 | + |
|
258 | + // Check for a blank line at the bottom. |
|
259 | + if ((isset($tokens[$lastContent]['scope_closer']) === false |
|
260 | + || $tokens[$lastContent]['scope_closer'] !== $lastContent) |
|
261 | + && $tokens[$lastContent]['line'] < ($tokens[$closingTag]['line'] - 1) |
|
262 | + ) { |
|
263 | + // Find a token on the blank line to throw the error on. |
|
264 | + $i = $closingTag; |
|
265 | + do { |
|
266 | + $i--; |
|
267 | + } while ($tokens[$i]['line'] !== ($tokens[$closingTag]['line'] - 1)); |
|
268 | + |
|
269 | + $error = 'Blank line found at end of embedded PHP content'; |
|
270 | + $fix = $phpcsFile->addFixableError($error, $i, 'SpacingAfter'); |
|
271 | + if ($fix === true) { |
|
272 | + $phpcsFile->fixer->beginChangeset(); |
|
273 | + for ($i = ($lastContent + 1); $i < $closingTag; $i++) { |
|
274 | + if ($tokens[$i]['line'] === $tokens[$lastContent]['line'] |
|
275 | + || $tokens[$i]['line'] === $tokens[$closingTag]['line'] |
|
276 | + ) { |
|
277 | + continue; |
|
278 | + } |
|
279 | + |
|
280 | + $phpcsFile->fixer->replaceToken($i, ''); |
|
281 | + } |
|
282 | + |
|
283 | + $phpcsFile->fixer->endChangeset(); |
|
284 | + } |
|
285 | + }//end if |
|
286 | + |
|
287 | + }//end validateMultilineEmbeddedPhp() |
|
288 | + |
|
289 | + |
|
290 | + /** |
|
291 | + * Validates embedded PHP that exists on one line. |
|
292 | + * |
|
293 | + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
294 | + * @param int $stackPtr The position of the current token in the |
|
295 | + * stack passed in $tokens. |
|
296 | + * |
|
297 | + * @return void |
|
298 | + */ |
|
299 | + private function validateInlineEmbeddedPhp($phpcsFile, $stackPtr) |
|
300 | + { |
|
301 | + $tokens = $phpcsFile->getTokens(); |
|
302 | + |
|
303 | + // We only want one line PHP sections, so return if the closing tag is |
|
304 | + // on the next line. |
|
305 | + $closeTag = $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr, null, false); |
|
306 | + if ($tokens[$stackPtr]['line'] !== $tokens[$closeTag]['line']) { |
|
307 | + return; |
|
308 | + } |
|
309 | + |
|
310 | + // Check that there is one, and only one space at the start of the statement. |
|
311 | + $firstContent = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), $closeTag, true); |
|
312 | + |
|
313 | + if ($firstContent === false) { |
|
314 | + $error = 'Empty embedded PHP tag found'; |
|
315 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Empty'); |
|
316 | + if ($fix === true) { |
|
317 | + $phpcsFile->fixer->beginChangeset(); |
|
318 | + for ($i = $stackPtr; $i <= $closeTag; $i++) { |
|
319 | + $phpcsFile->fixer->replaceToken($i, ''); |
|
320 | + } |
|
321 | + |
|
322 | + $phpcsFile->fixer->endChangeset(); |
|
323 | + } |
|
324 | + |
|
325 | + return; |
|
326 | + } |
|
327 | + |
|
328 | + // The open tag token always contains a single space after it. |
|
329 | + $leadingSpace = 1; |
|
330 | + if ($tokens[($stackPtr + 1)]['code'] === T_WHITESPACE) { |
|
331 | + $leadingSpace = ($tokens[($stackPtr + 1)]['length'] + 1); |
|
332 | + } |
|
333 | + |
|
334 | + if ($leadingSpace !== 1) { |
|
335 | + $error = 'Expected 1 space after opening PHP tag; %s found'; |
|
336 | + $data = [$leadingSpace]; |
|
337 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingAfterOpen', $data); |
|
338 | + if ($fix === true) { |
|
339 | + $phpcsFile->fixer->replaceToken(($stackPtr + 1), ''); |
|
340 | + } |
|
341 | + } |
|
342 | + |
|
343 | + $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($closeTag - 1), $stackPtr, true); |
|
344 | + if ($prev !== $stackPtr) { |
|
345 | + if ((isset($tokens[$prev]['scope_opener']) === false |
|
346 | + || $tokens[$prev]['scope_opener'] !== $prev) |
|
347 | + && (isset($tokens[$prev]['scope_closer']) === false |
|
348 | + || $tokens[$prev]['scope_closer'] !== $prev) |
|
349 | + && $tokens[$prev]['code'] !== T_SEMICOLON |
|
350 | + ) { |
|
351 | + $error = 'Inline PHP statement must end with a semicolon'; |
|
352 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSemicolon'); |
|
353 | + if ($fix === true) { |
|
354 | + $phpcsFile->fixer->addContent($prev, ';'); |
|
355 | + } |
|
356 | + } else if ($tokens[$prev]['code'] === T_SEMICOLON) { |
|
357 | + $statementCount = 1; |
|
358 | + for ($i = ($stackPtr + 1); $i < $prev; $i++) { |
|
359 | + if ($tokens[$i]['code'] === T_SEMICOLON) { |
|
360 | + $statementCount++; |
|
361 | + } |
|
362 | + } |
|
363 | + |
|
364 | + if ($statementCount > 1) { |
|
365 | + $error = 'Inline PHP statement must contain a single statement; %s found'; |
|
366 | + $data = [$statementCount]; |
|
367 | + $phpcsFile->addError($error, $stackPtr, 'MultipleStatements', $data); |
|
368 | + } |
|
369 | + } |
|
370 | + }//end if |
|
371 | + |
|
372 | + $trailingSpace = 0; |
|
373 | + if ($tokens[($closeTag - 1)]['code'] === T_WHITESPACE) { |
|
374 | + $trailingSpace = $tokens[($closeTag - 1)]['length']; |
|
375 | + } else if (($tokens[($closeTag - 1)]['code'] === T_COMMENT |
|
376 | + || isset(Tokens::$phpcsCommentTokens[$tokens[($closeTag - 1)]['code']]) === true) |
|
377 | + && substr($tokens[($closeTag - 1)]['content'], -1) === ' ' |
|
378 | + ) { |
|
379 | + $trailingSpace = (strlen($tokens[($closeTag - 1)]['content']) - strlen(rtrim($tokens[($closeTag - 1)]['content']))); |
|
380 | + } |
|
381 | + |
|
382 | + if ($trailingSpace !== 1) { |
|
383 | + $error = 'Expected 1 space before closing PHP tag; %s found'; |
|
384 | + $data = [$trailingSpace]; |
|
385 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingBeforeClose', $data); |
|
386 | + if ($fix === true) { |
|
387 | + if ($trailingSpace === 0) { |
|
388 | + $phpcsFile->fixer->addContentBefore($closeTag, ' '); |
|
389 | + } else if ($tokens[($closeTag - 1)]['code'] === T_COMMENT |
|
390 | + || isset(Tokens::$phpcsCommentTokens[$tokens[($closeTag - 1)]['code']]) === true |
|
391 | + ) { |
|
392 | + $phpcsFile->fixer->replaceToken(($closeTag - 1), rtrim($tokens[($closeTag - 1)]['content']).' '); |
|
393 | + } else { |
|
394 | + $phpcsFile->fixer->replaceToken(($closeTag - 1), ' '); |
|
395 | + } |
|
396 | + } |
|
397 | + } |
|
398 | + |
|
399 | + }//end validateInlineEmbeddedPhp() |
|
400 | 400 | |
401 | 401 | |
402 | 402 | }//end class |
@@ -16,33 +16,33 @@ |
||
16 | 16 | { |
17 | 17 | |
18 | 18 | |
19 | - /** |
|
20 | - * Returns an array of tokens this test wants to listen for. |
|
21 | - * |
|
22 | - * @return array |
|
23 | - */ |
|
24 | - public function register() |
|
25 | - { |
|
26 | - return [T_EVAL]; |
|
27 | - |
|
28 | - }//end register() |
|
29 | - |
|
30 | - |
|
31 | - /** |
|
32 | - * Processes this test, when one of its tokens is encountered. |
|
33 | - * |
|
34 | - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
35 | - * @param int $stackPtr The position of the current token in |
|
36 | - * the stack passed in $tokens. |
|
37 | - * |
|
38 | - * @return void |
|
39 | - */ |
|
40 | - public function process(File $phpcsFile, $stackPtr) |
|
41 | - { |
|
42 | - $error = 'Use of eval() is discouraged'; |
|
43 | - $phpcsFile->addWarning($error, $stackPtr, 'Discouraged'); |
|
44 | - |
|
45 | - }//end process() |
|
19 | + /** |
|
20 | + * Returns an array of tokens this test wants to listen for. |
|
21 | + * |
|
22 | + * @return array |
|
23 | + */ |
|
24 | + public function register() |
|
25 | + { |
|
26 | + return [T_EVAL]; |
|
27 | + |
|
28 | + }//end register() |
|
29 | + |
|
30 | + |
|
31 | + /** |
|
32 | + * Processes this test, when one of its tokens is encountered. |
|
33 | + * |
|
34 | + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
35 | + * @param int $stackPtr The position of the current token in |
|
36 | + * the stack passed in $tokens. |
|
37 | + * |
|
38 | + * @return void |
|
39 | + */ |
|
40 | + public function process(File $phpcsFile, $stackPtr) |
|
41 | + { |
|
42 | + $error = 'Use of eval() is discouraged'; |
|
43 | + $phpcsFile->addWarning($error, $stackPtr, 'Discouraged'); |
|
44 | + |
|
45 | + }//end process() |
|
46 | 46 | |
47 | 47 | |
48 | 48 | }//end class |
@@ -14,25 +14,25 @@ |
||
14 | 14 | class DiscouragedFunctionsSniff extends GenericForbiddenFunctionsSniff |
15 | 15 | { |
16 | 16 | |
17 | - /** |
|
18 | - * A list of forbidden functions with their alternatives. |
|
19 | - * |
|
20 | - * The value is NULL if no alternative exists. IE, the |
|
21 | - * function should just not be used. |
|
22 | - * |
|
23 | - * @var array<string, string|null> |
|
24 | - */ |
|
25 | - public $forbiddenFunctions = [ |
|
26 | - 'error_log' => null, |
|
27 | - 'print_r' => null, |
|
28 | - 'var_dump' => null, |
|
29 | - ]; |
|
17 | + /** |
|
18 | + * A list of forbidden functions with their alternatives. |
|
19 | + * |
|
20 | + * The value is NULL if no alternative exists. IE, the |
|
21 | + * function should just not be used. |
|
22 | + * |
|
23 | + * @var array<string, string|null> |
|
24 | + */ |
|
25 | + public $forbiddenFunctions = [ |
|
26 | + 'error_log' => null, |
|
27 | + 'print_r' => null, |
|
28 | + 'var_dump' => null, |
|
29 | + ]; |
|
30 | 30 | |
31 | - /** |
|
32 | - * If true, an error will be thrown; otherwise a warning. |
|
33 | - * |
|
34 | - * @var boolean |
|
35 | - */ |
|
36 | - public $error = false; |
|
31 | + /** |
|
32 | + * If true, an error will be thrown; otherwise a warning. |
|
33 | + * |
|
34 | + * @var boolean |
|
35 | + */ |
|
36 | + public $error = false; |
|
37 | 37 | |
38 | 38 | }//end class |
@@ -15,65 +15,65 @@ |
||
15 | 15 | class PropertyLabelSpacingSniff implements Sniff |
16 | 16 | { |
17 | 17 | |
18 | - /** |
|
19 | - * A list of tokenizers this sniff supports. |
|
20 | - * |
|
21 | - * @var array |
|
22 | - */ |
|
23 | - public $supportedTokenizers = ['JS']; |
|
18 | + /** |
|
19 | + * A list of tokenizers this sniff supports. |
|
20 | + * |
|
21 | + * @var array |
|
22 | + */ |
|
23 | + public $supportedTokenizers = ['JS']; |
|
24 | 24 | |
25 | 25 | |
26 | - /** |
|
27 | - * Returns an array of tokens this test wants to listen for. |
|
28 | - * |
|
29 | - * @return array |
|
30 | - */ |
|
31 | - public function register() |
|
32 | - { |
|
33 | - return [ |
|
34 | - T_PROPERTY, |
|
35 | - T_LABEL, |
|
36 | - ]; |
|
26 | + /** |
|
27 | + * Returns an array of tokens this test wants to listen for. |
|
28 | + * |
|
29 | + * @return array |
|
30 | + */ |
|
31 | + public function register() |
|
32 | + { |
|
33 | + return [ |
|
34 | + T_PROPERTY, |
|
35 | + T_LABEL, |
|
36 | + ]; |
|
37 | 37 | |
38 | - }//end register() |
|
38 | + }//end register() |
|
39 | 39 | |
40 | 40 | |
41 | - /** |
|
42 | - * Processes this test, when one of its tokens is encountered. |
|
43 | - * |
|
44 | - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
45 | - * @param int $stackPtr The position of the current token |
|
46 | - * in the stack passed in $tokens. |
|
47 | - * |
|
48 | - * @return void |
|
49 | - */ |
|
50 | - public function process(File $phpcsFile, $stackPtr) |
|
51 | - { |
|
52 | - $tokens = $phpcsFile->getTokens(); |
|
41 | + /** |
|
42 | + * Processes this test, when one of its tokens is encountered. |
|
43 | + * |
|
44 | + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
45 | + * @param int $stackPtr The position of the current token |
|
46 | + * in the stack passed in $tokens. |
|
47 | + * |
|
48 | + * @return void |
|
49 | + */ |
|
50 | + public function process(File $phpcsFile, $stackPtr) |
|
51 | + { |
|
52 | + $tokens = $phpcsFile->getTokens(); |
|
53 | 53 | |
54 | - $colon = $phpcsFile->findNext(T_COLON, ($stackPtr + 1)); |
|
54 | + $colon = $phpcsFile->findNext(T_COLON, ($stackPtr + 1)); |
|
55 | 55 | |
56 | - if ($colon !== ($stackPtr + 1)) { |
|
57 | - $error = 'There must be no space before the colon in a property/label declaration'; |
|
58 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Before'); |
|
59 | - if ($fix === true) { |
|
60 | - $phpcsFile->fixer->replaceToken(($stackPtr + 1), ''); |
|
61 | - } |
|
62 | - } |
|
56 | + if ($colon !== ($stackPtr + 1)) { |
|
57 | + $error = 'There must be no space before the colon in a property/label declaration'; |
|
58 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Before'); |
|
59 | + if ($fix === true) { |
|
60 | + $phpcsFile->fixer->replaceToken(($stackPtr + 1), ''); |
|
61 | + } |
|
62 | + } |
|
63 | 63 | |
64 | - if ($tokens[($colon + 1)]['code'] !== T_WHITESPACE || $tokens[($colon + 1)]['content'] !== ' ') { |
|
65 | - $error = 'There must be a single space after the colon in a property/label declaration'; |
|
66 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'After'); |
|
67 | - if ($fix === true) { |
|
68 | - if ($tokens[($colon + 1)]['code'] === T_WHITESPACE) { |
|
69 | - $phpcsFile->fixer->replaceToken(($colon + 1), ' '); |
|
70 | - } else { |
|
71 | - $phpcsFile->fixer->addContent($colon, ' '); |
|
72 | - } |
|
73 | - } |
|
74 | - } |
|
64 | + if ($tokens[($colon + 1)]['code'] !== T_WHITESPACE || $tokens[($colon + 1)]['content'] !== ' ') { |
|
65 | + $error = 'There must be a single space after the colon in a property/label declaration'; |
|
66 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'After'); |
|
67 | + if ($fix === true) { |
|
68 | + if ($tokens[($colon + 1)]['code'] === T_WHITESPACE) { |
|
69 | + $phpcsFile->fixer->replaceToken(($colon + 1), ' '); |
|
70 | + } else { |
|
71 | + $phpcsFile->fixer->addContent($colon, ' '); |
|
72 | + } |
|
73 | + } |
|
74 | + } |
|
75 | 75 | |
76 | - }//end process() |
|
76 | + }//end process() |
|
77 | 77 | |
78 | 78 | |
79 | 79 | }//end class |
@@ -17,49 +17,49 @@ |
||
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 Tokens::$castTokens; |
|
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 Tokens::$castTokens; |
|
28 | 28 | |
29 | - }//end register() |
|
29 | + }//end register() |
|
30 | 30 | |
31 | 31 | |
32 | - /** |
|
33 | - * Processes this test, 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 the |
|
37 | - * stack passed in $tokens. |
|
38 | - * |
|
39 | - * @return void |
|
40 | - */ |
|
41 | - public function process(File $phpcsFile, $stackPtr) |
|
42 | - { |
|
43 | - $tokens = $phpcsFile->getTokens(); |
|
32 | + /** |
|
33 | + * Processes this test, 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 the |
|
37 | + * stack passed in $tokens. |
|
38 | + * |
|
39 | + * @return void |
|
40 | + */ |
|
41 | + public function process(File $phpcsFile, $stackPtr) |
|
42 | + { |
|
43 | + $tokens = $phpcsFile->getTokens(); |
|
44 | 44 | |
45 | - $content = $tokens[$stackPtr]['content']; |
|
46 | - $expected = str_replace(' ', '', $content); |
|
47 | - $expected = str_replace("\t", '', $expected); |
|
45 | + $content = $tokens[$stackPtr]['content']; |
|
46 | + $expected = str_replace(' ', '', $content); |
|
47 | + $expected = str_replace("\t", '', $expected); |
|
48 | 48 | |
49 | - if ($content !== $expected) { |
|
50 | - $error = 'Cast statements must not contain whitespace; expected "%s" but found "%s"'; |
|
51 | - $data = [ |
|
52 | - $expected, |
|
53 | - $content, |
|
54 | - ]; |
|
49 | + if ($content !== $expected) { |
|
50 | + $error = 'Cast statements must not contain whitespace; expected "%s" but found "%s"'; |
|
51 | + $data = [ |
|
52 | + $expected, |
|
53 | + $content, |
|
54 | + ]; |
|
55 | 55 | |
56 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'ContainsWhiteSpace', $data); |
|
57 | - if ($fix === true) { |
|
58 | - $phpcsFile->fixer->replaceToken($stackPtr, $expected); |
|
59 | - } |
|
60 | - } |
|
56 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'ContainsWhiteSpace', $data); |
|
57 | + if ($fix === true) { |
|
58 | + $phpcsFile->fixer->replaceToken($stackPtr, $expected); |
|
59 | + } |
|
60 | + } |
|
61 | 61 | |
62 | - }//end process() |
|
62 | + }//end process() |
|
63 | 63 | |
64 | 64 | |
65 | 65 | }//end class |
@@ -78,7 +78,7 @@ |
||
78 | 78 | $tokens[$stackPtr]['content'].' '.$tokens[($stackPtr + 1)]['content'], |
79 | 79 | $tokens[$stackPtr]['content'].$tokens[($stackPtr + 1)]['content'], |
80 | 80 | ]; |
81 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Incorrect', $data); |
|
81 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Incorrect', $data); |
|
82 | 82 | if ($fix === true) { |
83 | 83 | $phpcsFile->fixer->addContent($stackPtr, ' '); |
84 | 84 | } |
@@ -17,73 +17,73 @@ |
||
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 [ |
|
28 | - T_ECHO, |
|
29 | - T_PRINT, |
|
30 | - T_RETURN, |
|
31 | - T_INCLUDE, |
|
32 | - T_INCLUDE_ONCE, |
|
33 | - T_REQUIRE, |
|
34 | - T_REQUIRE_ONCE, |
|
35 | - T_NEW, |
|
36 | - ]; |
|
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 [ |
|
28 | + T_ECHO, |
|
29 | + T_PRINT, |
|
30 | + T_RETURN, |
|
31 | + T_INCLUDE, |
|
32 | + T_INCLUDE_ONCE, |
|
33 | + T_REQUIRE, |
|
34 | + T_REQUIRE_ONCE, |
|
35 | + T_NEW, |
|
36 | + ]; |
|
37 | 37 | |
38 | - }//end register() |
|
38 | + }//end register() |
|
39 | 39 | |
40 | 40 | |
41 | - /** |
|
42 | - * Processes this test, when one of its tokens is encountered. |
|
43 | - * |
|
44 | - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
45 | - * @param int $stackPtr The position of the current token in |
|
46 | - * the stack passed in $tokens. |
|
47 | - * |
|
48 | - * @return void |
|
49 | - */ |
|
50 | - public function process(File $phpcsFile, $stackPtr) |
|
51 | - { |
|
52 | - $tokens = $phpcsFile->getTokens(); |
|
41 | + /** |
|
42 | + * Processes this test, when one of its tokens is encountered. |
|
43 | + * |
|
44 | + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
45 | + * @param int $stackPtr The position of the current token in |
|
46 | + * the stack passed in $tokens. |
|
47 | + * |
|
48 | + * @return void |
|
49 | + */ |
|
50 | + public function process(File $phpcsFile, $stackPtr) |
|
51 | + { |
|
52 | + $tokens = $phpcsFile->getTokens(); |
|
53 | 53 | |
54 | - if (isset($tokens[($stackPtr + 1)]) === false) { |
|
55 | - // Skip if there is no next token. |
|
56 | - return; |
|
57 | - } |
|
54 | + if (isset($tokens[($stackPtr + 1)]) === false) { |
|
55 | + // Skip if there is no next token. |
|
56 | + return; |
|
57 | + } |
|
58 | 58 | |
59 | - if ($tokens[($stackPtr + 1)]['code'] === T_SEMICOLON) { |
|
60 | - // No content for this language construct. |
|
61 | - return; |
|
62 | - } |
|
59 | + if ($tokens[($stackPtr + 1)]['code'] === T_SEMICOLON) { |
|
60 | + // No content for this language construct. |
|
61 | + return; |
|
62 | + } |
|
63 | 63 | |
64 | - if ($tokens[($stackPtr + 1)]['code'] === T_WHITESPACE) { |
|
65 | - $content = $tokens[($stackPtr + 1)]['content']; |
|
66 | - if ($content !== ' ') { |
|
67 | - $error = 'Language constructs must be followed by a single space; expected 1 space but found "%s"'; |
|
68 | - $data = [Util\Common::prepareForOutput($content)]; |
|
69 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'IncorrectSingle', $data); |
|
70 | - if ($fix === true) { |
|
71 | - $phpcsFile->fixer->replaceToken(($stackPtr + 1), ' '); |
|
72 | - } |
|
73 | - } |
|
74 | - } else if ($tokens[($stackPtr + 1)]['code'] !== T_OPEN_PARENTHESIS) { |
|
75 | - $error = 'Language constructs must be followed by a single space; expected "%s" but found "%s"'; |
|
76 | - $data = [ |
|
77 | - $tokens[$stackPtr]['content'].' '.$tokens[($stackPtr + 1)]['content'], |
|
78 | - $tokens[$stackPtr]['content'].$tokens[($stackPtr + 1)]['content'], |
|
79 | - ]; |
|
80 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Incorrect', $data); |
|
81 | - if ($fix === true) { |
|
82 | - $phpcsFile->fixer->addContent($stackPtr, ' '); |
|
83 | - } |
|
84 | - }//end if |
|
64 | + if ($tokens[($stackPtr + 1)]['code'] === T_WHITESPACE) { |
|
65 | + $content = $tokens[($stackPtr + 1)]['content']; |
|
66 | + if ($content !== ' ') { |
|
67 | + $error = 'Language constructs must be followed by a single space; expected 1 space but found "%s"'; |
|
68 | + $data = [Util\Common::prepareForOutput($content)]; |
|
69 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'IncorrectSingle', $data); |
|
70 | + if ($fix === true) { |
|
71 | + $phpcsFile->fixer->replaceToken(($stackPtr + 1), ' '); |
|
72 | + } |
|
73 | + } |
|
74 | + } else if ($tokens[($stackPtr + 1)]['code'] !== T_OPEN_PARENTHESIS) { |
|
75 | + $error = 'Language constructs must be followed by a single space; expected "%s" but found "%s"'; |
|
76 | + $data = [ |
|
77 | + $tokens[$stackPtr]['content'].' '.$tokens[($stackPtr + 1)]['content'], |
|
78 | + $tokens[$stackPtr]['content'].$tokens[($stackPtr + 1)]['content'], |
|
79 | + ]; |
|
80 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Incorrect', $data); |
|
81 | + if ($fix === true) { |
|
82 | + $phpcsFile->fixer->addContent($stackPtr, ' '); |
|
83 | + } |
|
84 | + }//end if |
|
85 | 85 | |
86 | - }//end process() |
|
86 | + }//end process() |
|
87 | 87 | |
88 | 88 | |
89 | 89 | }//end class |
@@ -17,80 +17,80 @@ |
||
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 [ |
|
28 | - T_OPEN_SQUARE_BRACKET, |
|
29 | - T_CLOSE_SQUARE_BRACKET, |
|
30 | - ]; |
|
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 [ |
|
28 | + T_OPEN_SQUARE_BRACKET, |
|
29 | + T_CLOSE_SQUARE_BRACKET, |
|
30 | + ]; |
|
31 | 31 | |
32 | - }//end register() |
|
32 | + }//end register() |
|
33 | 33 | |
34 | 34 | |
35 | - /** |
|
36 | - * Processes this sniff, when one of its tokens is encountered. |
|
37 | - * |
|
38 | - * @param \PHP_CodeSniffer\Files\File $phpcsFile The current file being checked. |
|
39 | - * @param int $stackPtr The position of the current token in the |
|
40 | - * stack passed in $tokens. |
|
41 | - * |
|
42 | - * @return void |
|
43 | - */ |
|
44 | - public function process(File $phpcsFile, $stackPtr) |
|
45 | - { |
|
46 | - $tokens = $phpcsFile->getTokens(); |
|
35 | + /** |
|
36 | + * Processes this sniff, when one of its tokens is encountered. |
|
37 | + * |
|
38 | + * @param \PHP_CodeSniffer\Files\File $phpcsFile The current file being checked. |
|
39 | + * @param int $stackPtr The position of the current token in the |
|
40 | + * stack passed in $tokens. |
|
41 | + * |
|
42 | + * @return void |
|
43 | + */ |
|
44 | + public function process(File $phpcsFile, $stackPtr) |
|
45 | + { |
|
46 | + $tokens = $phpcsFile->getTokens(); |
|
47 | 47 | |
48 | - if (($tokens[$stackPtr]['code'] === T_OPEN_SQUARE_BRACKET |
|
49 | - && isset($tokens[$stackPtr]['bracket_closer']) === false) |
|
50 | - || ($tokens[$stackPtr]['code'] === T_CLOSE_SQUARE_BRACKET |
|
51 | - && isset($tokens[$stackPtr]['bracket_opener']) === false) |
|
52 | - ) { |
|
53 | - // Bow out for parse error/during live coding. |
|
54 | - return; |
|
55 | - } |
|
48 | + if (($tokens[$stackPtr]['code'] === T_OPEN_SQUARE_BRACKET |
|
49 | + && isset($tokens[$stackPtr]['bracket_closer']) === false) |
|
50 | + || ($tokens[$stackPtr]['code'] === T_CLOSE_SQUARE_BRACKET |
|
51 | + && isset($tokens[$stackPtr]['bracket_opener']) === false) |
|
52 | + ) { |
|
53 | + // Bow out for parse error/during live coding. |
|
54 | + return; |
|
55 | + } |
|
56 | 56 | |
57 | - // Square brackets can not have a space before them. |
|
58 | - $prevType = $tokens[($stackPtr - 1)]['code']; |
|
59 | - if ($prevType === T_WHITESPACE) { |
|
60 | - $nonSpace = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 2), null, true); |
|
61 | - $expected = $tokens[$nonSpace]['content'].$tokens[$stackPtr]['content']; |
|
62 | - $found = $phpcsFile->getTokensAsString($nonSpace, ($stackPtr - $nonSpace)).$tokens[$stackPtr]['content']; |
|
63 | - $error = 'Space found before square bracket; expected "%s" but found "%s"'; |
|
64 | - $data = [ |
|
65 | - $expected, |
|
66 | - $found, |
|
67 | - ]; |
|
68 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceBeforeBracket', $data); |
|
69 | - if ($fix === true) { |
|
70 | - $phpcsFile->fixer->replaceToken(($stackPtr - 1), ''); |
|
71 | - } |
|
72 | - } |
|
57 | + // Square brackets can not have a space before them. |
|
58 | + $prevType = $tokens[($stackPtr - 1)]['code']; |
|
59 | + if ($prevType === T_WHITESPACE) { |
|
60 | + $nonSpace = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 2), null, true); |
|
61 | + $expected = $tokens[$nonSpace]['content'].$tokens[$stackPtr]['content']; |
|
62 | + $found = $phpcsFile->getTokensAsString($nonSpace, ($stackPtr - $nonSpace)).$tokens[$stackPtr]['content']; |
|
63 | + $error = 'Space found before square bracket; expected "%s" but found "%s"'; |
|
64 | + $data = [ |
|
65 | + $expected, |
|
66 | + $found, |
|
67 | + ]; |
|
68 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceBeforeBracket', $data); |
|
69 | + if ($fix === true) { |
|
70 | + $phpcsFile->fixer->replaceToken(($stackPtr - 1), ''); |
|
71 | + } |
|
72 | + } |
|
73 | 73 | |
74 | - // Open square brackets can't ever have spaces after them. |
|
75 | - if ($tokens[$stackPtr]['code'] === T_OPEN_SQUARE_BRACKET) { |
|
76 | - $nextType = $tokens[($stackPtr + 1)]['code']; |
|
77 | - if ($nextType === T_WHITESPACE) { |
|
78 | - $nonSpace = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 2), null, true); |
|
79 | - $expected = $tokens[$stackPtr]['content'].$tokens[$nonSpace]['content']; |
|
80 | - $found = $phpcsFile->getTokensAsString($stackPtr, ($nonSpace - $stackPtr + 1)); |
|
81 | - $error = 'Space found after square bracket; expected "%s" but found "%s"'; |
|
82 | - $data = [ |
|
83 | - $expected, |
|
84 | - $found, |
|
85 | - ]; |
|
86 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceAfterBracket', $data); |
|
87 | - if ($fix === true) { |
|
88 | - $phpcsFile->fixer->replaceToken(($stackPtr + 1), ''); |
|
89 | - } |
|
90 | - } |
|
91 | - } |
|
74 | + // Open square brackets can't ever have spaces after them. |
|
75 | + if ($tokens[$stackPtr]['code'] === T_OPEN_SQUARE_BRACKET) { |
|
76 | + $nextType = $tokens[($stackPtr + 1)]['code']; |
|
77 | + if ($nextType === T_WHITESPACE) { |
|
78 | + $nonSpace = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 2), null, true); |
|
79 | + $expected = $tokens[$stackPtr]['content'].$tokens[$nonSpace]['content']; |
|
80 | + $found = $phpcsFile->getTokensAsString($stackPtr, ($nonSpace - $stackPtr + 1)); |
|
81 | + $error = 'Space found after square bracket; expected "%s" but found "%s"'; |
|
82 | + $data = [ |
|
83 | + $expected, |
|
84 | + $found, |
|
85 | + ]; |
|
86 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceAfterBracket', $data); |
|
87 | + if ($fix === true) { |
|
88 | + $phpcsFile->fixer->replaceToken(($stackPtr + 1), ''); |
|
89 | + } |
|
90 | + } |
|
91 | + } |
|
92 | 92 | |
93 | - }//end process() |
|
93 | + }//end process() |
|
94 | 94 | |
95 | 95 | |
96 | 96 | }//end class |
@@ -65,7 +65,7 @@ discard block |
||
65 | 65 | $expected, |
66 | 66 | $found, |
67 | 67 | ]; |
68 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceBeforeBracket', $data); |
|
68 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceBeforeBracket', $data); |
|
69 | 69 | if ($fix === true) { |
70 | 70 | $phpcsFile->fixer->replaceToken(($stackPtr - 1), ''); |
71 | 71 | } |
@@ -83,7 +83,7 @@ discard block |
||
83 | 83 | $expected, |
84 | 84 | $found, |
85 | 85 | ]; |
86 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceAfterBracket', $data); |
|
86 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceAfterBracket', $data); |
|
87 | 87 | if ($fix === true) { |
88 | 88 | $phpcsFile->fixer->replaceToken(($stackPtr + 1), ''); |
89 | 89 | } |
@@ -16,129 +16,129 @@ |
||
16 | 16 | { |
17 | 17 | |
18 | 18 | |
19 | - /** |
|
20 | - * Returns an array of tokens this test wants to listen for. |
|
21 | - * |
|
22 | - * @return array |
|
23 | - */ |
|
24 | - public function register() |
|
25 | - { |
|
26 | - return [ |
|
27 | - T_CONSTANT_ENCAPSED_STRING, |
|
28 | - T_DOUBLE_QUOTED_STRING, |
|
29 | - ]; |
|
30 | - |
|
31 | - }//end register() |
|
32 | - |
|
33 | - |
|
34 | - /** |
|
35 | - * Processes this test, when one of its tokens is encountered. |
|
36 | - * |
|
37 | - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
38 | - * @param int $stackPtr The position of the current token |
|
39 | - * in the stack passed in $tokens. |
|
40 | - * |
|
41 | - * @return void |
|
42 | - */ |
|
43 | - public function process(File $phpcsFile, $stackPtr) |
|
44 | - { |
|
45 | - $tokens = $phpcsFile->getTokens(); |
|
46 | - |
|
47 | - // If tabs are being converted to spaces by the tokeniser, the |
|
48 | - // original content should be used instead of the converted content. |
|
49 | - if (isset($tokens[$stackPtr]['orig_content']) === true) { |
|
50 | - $workingString = $tokens[$stackPtr]['orig_content']; |
|
51 | - } else { |
|
52 | - $workingString = $tokens[$stackPtr]['content']; |
|
53 | - } |
|
54 | - |
|
55 | - $lastStringToken = $stackPtr; |
|
56 | - |
|
57 | - $i = ($stackPtr + 1); |
|
58 | - if (isset($tokens[$i]) === true) { |
|
59 | - while ($i < $phpcsFile->numTokens |
|
60 | - && $tokens[$i]['code'] === $tokens[$stackPtr]['code'] |
|
61 | - ) { |
|
62 | - if (isset($tokens[$i]['orig_content']) === true) { |
|
63 | - $workingString .= $tokens[$i]['orig_content']; |
|
64 | - } else { |
|
65 | - $workingString .= $tokens[$i]['content']; |
|
66 | - } |
|
67 | - |
|
68 | - $lastStringToken = $i; |
|
69 | - $i++; |
|
70 | - } |
|
71 | - } |
|
72 | - |
|
73 | - $skipTo = ($lastStringToken + 1); |
|
74 | - |
|
75 | - // Check if it's a double quoted string. |
|
76 | - if ($workingString[0] !== '"' || substr($workingString, -1) !== '"') { |
|
77 | - return $skipTo; |
|
78 | - } |
|
79 | - |
|
80 | - // The use of variables in double quoted strings is not allowed. |
|
81 | - if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING) { |
|
82 | - $stringTokens = token_get_all('<?php '.$workingString); |
|
83 | - foreach ($stringTokens as $token) { |
|
84 | - if (is_array($token) === true && $token[0] === T_VARIABLE) { |
|
85 | - $error = 'Variable "%s" not allowed in double quoted string; use concatenation instead'; |
|
86 | - $data = [$token[1]]; |
|
87 | - $phpcsFile->addError($error, $stackPtr, 'ContainsVar', $data); |
|
88 | - } |
|
89 | - } |
|
90 | - |
|
91 | - return $skipTo; |
|
92 | - }//end if |
|
93 | - |
|
94 | - $allowedChars = [ |
|
95 | - '\0', |
|
96 | - '\1', |
|
97 | - '\2', |
|
98 | - '\3', |
|
99 | - '\4', |
|
100 | - '\5', |
|
101 | - '\6', |
|
102 | - '\7', |
|
103 | - '\n', |
|
104 | - '\r', |
|
105 | - '\f', |
|
106 | - '\t', |
|
107 | - '\v', |
|
108 | - '\x', |
|
109 | - '\b', |
|
110 | - '\e', |
|
111 | - '\u', |
|
112 | - '\'', |
|
113 | - ]; |
|
114 | - |
|
115 | - foreach ($allowedChars as $testChar) { |
|
116 | - if (strpos($workingString, $testChar) !== false) { |
|
117 | - return $skipTo; |
|
118 | - } |
|
119 | - } |
|
120 | - |
|
121 | - $error = 'String %s does not require double quotes; use single quotes instead'; |
|
122 | - $data = [str_replace(["\r", "\n"], ['\r', '\n'], $workingString)]; |
|
123 | - $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NotRequired', $data); |
|
124 | - |
|
125 | - if ($fix === true) { |
|
126 | - $phpcsFile->fixer->beginChangeset(); |
|
127 | - $innerContent = substr($workingString, 1, -1); |
|
128 | - $innerContent = str_replace('\"', '"', $innerContent); |
|
129 | - $innerContent = str_replace('\\$', '$', $innerContent); |
|
130 | - $phpcsFile->fixer->replaceToken($stackPtr, "'$innerContent'"); |
|
131 | - while ($lastStringToken !== $stackPtr) { |
|
132 | - $phpcsFile->fixer->replaceToken($lastStringToken, ''); |
|
133 | - $lastStringToken--; |
|
134 | - } |
|
135 | - |
|
136 | - $phpcsFile->fixer->endChangeset(); |
|
137 | - } |
|
138 | - |
|
139 | - return $skipTo; |
|
140 | - |
|
141 | - }//end process() |
|
19 | + /** |
|
20 | + * Returns an array of tokens this test wants to listen for. |
|
21 | + * |
|
22 | + * @return array |
|
23 | + */ |
|
24 | + public function register() |
|
25 | + { |
|
26 | + return [ |
|
27 | + T_CONSTANT_ENCAPSED_STRING, |
|
28 | + T_DOUBLE_QUOTED_STRING, |
|
29 | + ]; |
|
30 | + |
|
31 | + }//end register() |
|
32 | + |
|
33 | + |
|
34 | + /** |
|
35 | + * Processes this test, when one of its tokens is encountered. |
|
36 | + * |
|
37 | + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. |
|
38 | + * @param int $stackPtr The position of the current token |
|
39 | + * in the stack passed in $tokens. |
|
40 | + * |
|
41 | + * @return void |
|
42 | + */ |
|
43 | + public function process(File $phpcsFile, $stackPtr) |
|
44 | + { |
|
45 | + $tokens = $phpcsFile->getTokens(); |
|
46 | + |
|
47 | + // If tabs are being converted to spaces by the tokeniser, the |
|
48 | + // original content should be used instead of the converted content. |
|
49 | + if (isset($tokens[$stackPtr]['orig_content']) === true) { |
|
50 | + $workingString = $tokens[$stackPtr]['orig_content']; |
|
51 | + } else { |
|
52 | + $workingString = $tokens[$stackPtr]['content']; |
|
53 | + } |
|
54 | + |
|
55 | + $lastStringToken = $stackPtr; |
|
56 | + |
|
57 | + $i = ($stackPtr + 1); |
|
58 | + if (isset($tokens[$i]) === true) { |
|
59 | + while ($i < $phpcsFile->numTokens |
|
60 | + && $tokens[$i]['code'] === $tokens[$stackPtr]['code'] |
|
61 | + ) { |
|
62 | + if (isset($tokens[$i]['orig_content']) === true) { |
|
63 | + $workingString .= $tokens[$i]['orig_content']; |
|
64 | + } else { |
|
65 | + $workingString .= $tokens[$i]['content']; |
|
66 | + } |
|
67 | + |
|
68 | + $lastStringToken = $i; |
|
69 | + $i++; |
|
70 | + } |
|
71 | + } |
|
72 | + |
|
73 | + $skipTo = ($lastStringToken + 1); |
|
74 | + |
|
75 | + // Check if it's a double quoted string. |
|
76 | + if ($workingString[0] !== '"' || substr($workingString, -1) !== '"') { |
|
77 | + return $skipTo; |
|
78 | + } |
|
79 | + |
|
80 | + // The use of variables in double quoted strings is not allowed. |
|
81 | + if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING) { |
|
82 | + $stringTokens = token_get_all('<?php '.$workingString); |
|
83 | + foreach ($stringTokens as $token) { |
|
84 | + if (is_array($token) === true && $token[0] === T_VARIABLE) { |
|
85 | + $error = 'Variable "%s" not allowed in double quoted string; use concatenation instead'; |
|
86 | + $data = [$token[1]]; |
|
87 | + $phpcsFile->addError($error, $stackPtr, 'ContainsVar', $data); |
|
88 | + } |
|
89 | + } |
|
90 | + |
|
91 | + return $skipTo; |
|
92 | + }//end if |
|
93 | + |
|
94 | + $allowedChars = [ |
|
95 | + '\0', |
|
96 | + '\1', |
|
97 | + '\2', |
|
98 | + '\3', |
|
99 | + '\4', |
|
100 | + '\5', |
|
101 | + '\6', |
|
102 | + '\7', |
|
103 | + '\n', |
|
104 | + '\r', |
|
105 | + '\f', |
|
106 | + '\t', |
|
107 | + '\v', |
|
108 | + '\x', |
|
109 | + '\b', |
|
110 | + '\e', |
|
111 | + '\u', |
|
112 | + '\'', |
|
113 | + ]; |
|
114 | + |
|
115 | + foreach ($allowedChars as $testChar) { |
|
116 | + if (strpos($workingString, $testChar) !== false) { |
|
117 | + return $skipTo; |
|
118 | + } |
|
119 | + } |
|
120 | + |
|
121 | + $error = 'String %s does not require double quotes; use single quotes instead'; |
|
122 | + $data = [str_replace(["\r", "\n"], ['\r', '\n'], $workingString)]; |
|
123 | + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NotRequired', $data); |
|
124 | + |
|
125 | + if ($fix === true) { |
|
126 | + $phpcsFile->fixer->beginChangeset(); |
|
127 | + $innerContent = substr($workingString, 1, -1); |
|
128 | + $innerContent = str_replace('\"', '"', $innerContent); |
|
129 | + $innerContent = str_replace('\\$', '$', $innerContent); |
|
130 | + $phpcsFile->fixer->replaceToken($stackPtr, "'$innerContent'"); |
|
131 | + while ($lastStringToken !== $stackPtr) { |
|
132 | + $phpcsFile->fixer->replaceToken($lastStringToken, ''); |
|
133 | + $lastStringToken--; |
|
134 | + } |
|
135 | + |
|
136 | + $phpcsFile->fixer->endChangeset(); |
|
137 | + } |
|
138 | + |
|
139 | + return $skipTo; |
|
140 | + |
|
141 | + }//end process() |
|
142 | 142 | |
143 | 143 | |
144 | 144 | }//end class |