Mercurial > hg > isophonics-drupal-site
comparison vendor/squizlabs/php_codesniffer/src/Reports/Code.php @ 17:129ea1e6d783
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:21:36 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
16:c2387f117808 | 17:129ea1e6d783 |
---|---|
1 <?php | |
2 /** | |
3 * Full report for PHP_CodeSniffer. | |
4 * | |
5 * @author Greg Sherwood <gsherwood@squiz.net> | |
6 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600) | |
7 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence | |
8 */ | |
9 | |
10 namespace PHP_CodeSniffer\Reports; | |
11 | |
12 use PHP_CodeSniffer\Files\File; | |
13 use PHP_CodeSniffer\Util; | |
14 | |
15 class Code implements Report | |
16 { | |
17 | |
18 | |
19 /** | |
20 * Generate a partial report for a single processed file. | |
21 * | |
22 * Function should return TRUE if it printed or stored data about the file | |
23 * and FALSE if it ignored the file. Returning TRUE indicates that the file and | |
24 * its data should be counted in the grand totals. | |
25 * | |
26 * @param array $report Prepared report data. | |
27 * @param \PHP_CodeSniffer\File $phpcsFile The file being reported on. | |
28 * @param bool $showSources Show sources? | |
29 * @param int $width Maximum allowed line width. | |
30 * | |
31 * @return bool | |
32 */ | |
33 public function generateFileReport($report, File $phpcsFile, $showSources=false, $width=80) | |
34 { | |
35 if ($report['errors'] === 0 && $report['warnings'] === 0) { | |
36 // Nothing to print. | |
37 return false; | |
38 } | |
39 | |
40 // How many lines to show about and below the error line. | |
41 $surroundingLines = 2; | |
42 | |
43 $file = $report['filename']; | |
44 $tokens = $phpcsFile->getTokens(); | |
45 if (empty($tokens) === true) { | |
46 if (PHP_CODESNIFFER_VERBOSITY === 1) { | |
47 $startTime = microtime(true); | |
48 echo 'CODE report is parsing '.basename($file).' '; | |
49 } else if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
50 echo "CODE report is forcing parse of $file".PHP_EOL; | |
51 } | |
52 | |
53 try { | |
54 $phpcsFile->parse(); | |
55 } catch (\Exception $e) { | |
56 // This is a second parse, so ignore exceptions. | |
57 // They would have been added to the file's error list already. | |
58 } | |
59 | |
60 if (PHP_CODESNIFFER_VERBOSITY === 1) { | |
61 $timeTaken = ((microtime(true) - $startTime) * 1000); | |
62 if ($timeTaken < 1000) { | |
63 $timeTaken = round($timeTaken); | |
64 echo "DONE in {$timeTaken}ms"; | |
65 } else { | |
66 $timeTaken = round(($timeTaken / 1000), 2); | |
67 echo "DONE in $timeTaken secs"; | |
68 } | |
69 | |
70 echo PHP_EOL; | |
71 } | |
72 | |
73 $tokens = $phpcsFile->getTokens(); | |
74 }//end if | |
75 | |
76 // Create an array that maps lines to the first token on the line. | |
77 $lineTokens = []; | |
78 $lastLine = 0; | |
79 $stackPtr = 0; | |
80 foreach ($tokens as $stackPtr => $token) { | |
81 if ($token['line'] !== $lastLine) { | |
82 if ($lastLine > 0) { | |
83 $lineTokens[$lastLine]['end'] = ($stackPtr - 1); | |
84 } | |
85 | |
86 $lastLine++; | |
87 $lineTokens[$lastLine] = [ | |
88 'start' => $stackPtr, | |
89 'end' => null, | |
90 ]; | |
91 } | |
92 } | |
93 | |
94 // Make sure the last token in the file sits on an imaginary | |
95 // last line so it is easier to generate code snippets at the | |
96 // end of the file. | |
97 $lineTokens[$lastLine]['end'] = $stackPtr; | |
98 | |
99 // Determine the longest code line we will be showing. | |
100 $maxSnippetLength = 0; | |
101 $eolLen = strlen($phpcsFile->eolChar); | |
102 foreach ($report['messages'] as $line => $lineErrors) { | |
103 $startLine = max(($line - $surroundingLines), 1); | |
104 $endLine = min(($line + $surroundingLines), $lastLine); | |
105 | |
106 $maxLineNumLength = strlen($endLine); | |
107 | |
108 for ($i = $startLine; $i <= $endLine; $i++) { | |
109 if ($i === 1) { | |
110 continue; | |
111 } | |
112 | |
113 $lineLength = ($tokens[($lineTokens[$i]['start'] - 1)]['column'] + $tokens[($lineTokens[$i]['start'] - 1)]['length'] - $eolLen); | |
114 $maxSnippetLength = max($lineLength, $maxSnippetLength); | |
115 } | |
116 } | |
117 | |
118 $maxSnippetLength += ($maxLineNumLength + 8); | |
119 | |
120 // Determine the longest error message we will be showing. | |
121 $maxErrorLength = 0; | |
122 foreach ($report['messages'] as $line => $lineErrors) { | |
123 foreach ($lineErrors as $column => $colErrors) { | |
124 foreach ($colErrors as $error) { | |
125 $length = strlen($error['message']); | |
126 if ($showSources === true) { | |
127 $length += (strlen($error['source']) + 3); | |
128 } | |
129 | |
130 $maxErrorLength = max($maxErrorLength, ($length + 1)); | |
131 } | |
132 } | |
133 } | |
134 | |
135 // The padding that all lines will require that are printing an error message overflow. | |
136 if ($report['warnings'] > 0) { | |
137 $typeLength = 7; | |
138 } else { | |
139 $typeLength = 5; | |
140 } | |
141 | |
142 $errorPadding = str_repeat(' ', ($maxLineNumLength + 7)); | |
143 $errorPadding .= str_repeat(' ', $typeLength); | |
144 $errorPadding .= ' '; | |
145 if ($report['fixable'] > 0) { | |
146 $errorPadding .= ' '; | |
147 } | |
148 | |
149 $errorPaddingLength = strlen($errorPadding); | |
150 | |
151 // The maximum amount of space an error message can use. | |
152 $maxErrorSpace = ($width - $errorPaddingLength); | |
153 if ($showSources === true) { | |
154 // Account for the chars used to print colors. | |
155 $maxErrorSpace += 8; | |
156 } | |
157 | |
158 // Figure out the max report width we need and can use. | |
159 $fileLength = strlen($file); | |
160 $maxWidth = max(($fileLength + 6), ($maxErrorLength + $errorPaddingLength)); | |
161 $width = max(min($width, $maxWidth), $maxSnippetLength); | |
162 if ($width < 70) { | |
163 $width = 70; | |
164 } | |
165 | |
166 // Print the file header. | |
167 echo PHP_EOL."\033[1mFILE: "; | |
168 if ($fileLength <= ($width - 6)) { | |
169 echo $file; | |
170 } else { | |
171 echo '...'.substr($file, ($fileLength - ($width - 6))); | |
172 } | |
173 | |
174 echo "\033[0m".PHP_EOL; | |
175 echo str_repeat('-', $width).PHP_EOL; | |
176 | |
177 echo "\033[1m".'FOUND '.$report['errors'].' ERROR'; | |
178 if ($report['errors'] !== 1) { | |
179 echo 'S'; | |
180 } | |
181 | |
182 if ($report['warnings'] > 0) { | |
183 echo ' AND '.$report['warnings'].' WARNING'; | |
184 if ($report['warnings'] !== 1) { | |
185 echo 'S'; | |
186 } | |
187 } | |
188 | |
189 echo ' AFFECTING '.count($report['messages']).' LINE'; | |
190 if (count($report['messages']) !== 1) { | |
191 echo 'S'; | |
192 } | |
193 | |
194 echo "\033[0m".PHP_EOL; | |
195 | |
196 foreach ($report['messages'] as $line => $lineErrors) { | |
197 $startLine = max(($line - $surroundingLines), 1); | |
198 $endLine = min(($line + $surroundingLines), $lastLine); | |
199 | |
200 $snippet = ''; | |
201 if (isset($lineTokens[$startLine]) === true) { | |
202 for ($i = $lineTokens[$startLine]['start']; $i <= $lineTokens[$endLine]['end']; $i++) { | |
203 $snippetLine = $tokens[$i]['line']; | |
204 if ($lineTokens[$snippetLine]['start'] === $i) { | |
205 // Starting a new line. | |
206 if ($snippetLine === $line) { | |
207 $snippet .= "\033[1m".'>> '; | |
208 } else { | |
209 $snippet .= ' '; | |
210 } | |
211 | |
212 $snippet .= str_repeat(' ', ($maxLineNumLength - strlen($snippetLine))); | |
213 $snippet .= $snippetLine.': '; | |
214 if ($snippetLine === $line) { | |
215 $snippet .= "\033[0m"; | |
216 } | |
217 } | |
218 | |
219 if (isset($tokens[$i]['orig_content']) === true) { | |
220 $tokenContent = $tokens[$i]['orig_content']; | |
221 } else { | |
222 $tokenContent = $tokens[$i]['content']; | |
223 } | |
224 | |
225 if (strpos($tokenContent, "\t") !== false) { | |
226 $token = $tokens[$i]; | |
227 $token['content'] = $tokenContent; | |
228 if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { | |
229 $tab = "\000"; | |
230 } else { | |
231 $tab = "\033[30;1m»\033[0m"; | |
232 } | |
233 | |
234 $phpcsFile->tokenizer->replaceTabsInToken($token, $tab, "\000"); | |
235 $tokenContent = $token['content']; | |
236 } | |
237 | |
238 $tokenContent = Util\Common::prepareForOutput($tokenContent, ["\r", "\n", "\t"]); | |
239 $tokenContent = str_replace("\000", ' ', $tokenContent); | |
240 | |
241 $underline = false; | |
242 if ($snippetLine === $line && isset($lineErrors[$tokens[$i]['column']]) === true) { | |
243 $underline = true; | |
244 } | |
245 | |
246 // Underline invisible characters as well. | |
247 if ($underline === true && trim($tokenContent) === '') { | |
248 $snippet .= "\033[4m".' '."\033[0m".$tokenContent; | |
249 } else { | |
250 if ($underline === true) { | |
251 $snippet .= "\033[4m"; | |
252 } | |
253 | |
254 $snippet .= $tokenContent; | |
255 | |
256 if ($underline === true) { | |
257 $snippet .= "\033[0m"; | |
258 } | |
259 } | |
260 }//end for | |
261 }//end if | |
262 | |
263 echo str_repeat('-', $width).PHP_EOL; | |
264 | |
265 foreach ($lineErrors as $column => $colErrors) { | |
266 foreach ($colErrors as $error) { | |
267 $padding = ($maxLineNumLength - strlen($line)); | |
268 echo 'LINE '.str_repeat(' ', $padding).$line.': '; | |
269 | |
270 if ($error['type'] === 'ERROR') { | |
271 echo "\033[31mERROR\033[0m"; | |
272 if ($report['warnings'] > 0) { | |
273 echo ' '; | |
274 } | |
275 } else { | |
276 echo "\033[33mWARNING\033[0m"; | |
277 } | |
278 | |
279 echo ' '; | |
280 if ($report['fixable'] > 0) { | |
281 echo '['; | |
282 if ($error['fixable'] === true) { | |
283 echo 'x'; | |
284 } else { | |
285 echo ' '; | |
286 } | |
287 | |
288 echo '] '; | |
289 } | |
290 | |
291 $message = $error['message']; | |
292 $message = str_replace("\n", "\n".$errorPadding, $message); | |
293 if ($showSources === true) { | |
294 $message = "\033[1m".$message."\033[0m".' ('.$error['source'].')'; | |
295 } | |
296 | |
297 $errorMsg = wordwrap( | |
298 $message, | |
299 $maxErrorSpace, | |
300 PHP_EOL.$errorPadding | |
301 ); | |
302 | |
303 echo $errorMsg.PHP_EOL; | |
304 }//end foreach | |
305 }//end foreach | |
306 | |
307 echo str_repeat('-', $width).PHP_EOL; | |
308 echo rtrim($snippet).PHP_EOL; | |
309 }//end foreach | |
310 | |
311 echo str_repeat('-', $width).PHP_EOL; | |
312 if ($report['fixable'] > 0) { | |
313 echo "\033[1m".'PHPCBF CAN FIX THE '.$report['fixable'].' MARKED SNIFF VIOLATIONS AUTOMATICALLY'."\033[0m".PHP_EOL; | |
314 echo str_repeat('-', $width).PHP_EOL; | |
315 } | |
316 | |
317 return true; | |
318 | |
319 }//end generateFileReport() | |
320 | |
321 | |
322 /** | |
323 * Prints all errors and warnings for each file processed. | |
324 * | |
325 * @param string $cachedData Any partial report data that was returned from | |
326 * generateFileReport during the run. | |
327 * @param int $totalFiles Total number of files processed during the run. | |
328 * @param int $totalErrors Total number of errors found during the run. | |
329 * @param int $totalWarnings Total number of warnings found during the run. | |
330 * @param int $totalFixable Total number of problems that can be fixed. | |
331 * @param bool $showSources Show sources? | |
332 * @param int $width Maximum allowed line width. | |
333 * @param bool $interactive Are we running in interactive mode? | |
334 * @param bool $toScreen Is the report being printed to screen? | |
335 * | |
336 * @return void | |
337 */ | |
338 public function generate( | |
339 $cachedData, | |
340 $totalFiles, | |
341 $totalErrors, | |
342 $totalWarnings, | |
343 $totalFixable, | |
344 $showSources=false, | |
345 $width=80, | |
346 $interactive=false, | |
347 $toScreen=true | |
348 ) { | |
349 if ($cachedData === '') { | |
350 return; | |
351 } | |
352 | |
353 echo $cachedData; | |
354 | |
355 if ($toScreen === true && $interactive === false) { | |
356 Util\Timing::printRunTime(); | |
357 } | |
358 | |
359 }//end generate() | |
360 | |
361 | |
362 }//end class |