Chris@14
|
1 <?php
|
Chris@14
|
2 /*
|
Chris@14
|
3 * This file is part of the php-code-coverage package.
|
Chris@14
|
4 *
|
Chris@14
|
5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
|
Chris@14
|
6 *
|
Chris@14
|
7 * For the full copyright and license information, please view the LICENSE
|
Chris@14
|
8 * file that was distributed with this source code.
|
Chris@14
|
9 */
|
Chris@14
|
10
|
Chris@14
|
11 namespace SebastianBergmann\CodeCoverage\Report\Html;
|
Chris@14
|
12
|
Chris@14
|
13 use SebastianBergmann\CodeCoverage\Node\File as FileNode;
|
Chris@14
|
14 use SebastianBergmann\CodeCoverage\Util;
|
Chris@14
|
15
|
Chris@14
|
16 /**
|
Chris@14
|
17 * Renders a file node.
|
Chris@14
|
18 */
|
Chris@14
|
19 class File extends Renderer
|
Chris@14
|
20 {
|
Chris@14
|
21 /**
|
Chris@14
|
22 * @var int
|
Chris@14
|
23 */
|
Chris@14
|
24 private $htmlspecialcharsFlags;
|
Chris@14
|
25
|
Chris@14
|
26 /**
|
Chris@14
|
27 * Constructor.
|
Chris@14
|
28 *
|
Chris@14
|
29 * @param string $templatePath
|
Chris@14
|
30 * @param string $generator
|
Chris@14
|
31 * @param string $date
|
Chris@14
|
32 * @param int $lowUpperBound
|
Chris@14
|
33 * @param int $highLowerBound
|
Chris@14
|
34 */
|
Chris@14
|
35 public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
|
Chris@14
|
36 {
|
Chris@14
|
37 parent::__construct(
|
Chris@14
|
38 $templatePath,
|
Chris@14
|
39 $generator,
|
Chris@14
|
40 $date,
|
Chris@14
|
41 $lowUpperBound,
|
Chris@14
|
42 $highLowerBound
|
Chris@14
|
43 );
|
Chris@14
|
44
|
Chris@14
|
45 $this->htmlspecialcharsFlags = ENT_COMPAT;
|
Chris@14
|
46
|
Chris@14
|
47 $this->htmlspecialcharsFlags = $this->htmlspecialcharsFlags | ENT_HTML401 | ENT_SUBSTITUTE;
|
Chris@14
|
48 }
|
Chris@14
|
49
|
Chris@14
|
50 /**
|
Chris@14
|
51 * @param FileNode $node
|
Chris@14
|
52 * @param string $file
|
Chris@14
|
53 */
|
Chris@14
|
54 public function render(FileNode $node, $file)
|
Chris@14
|
55 {
|
Chris@14
|
56 $template = new \Text_Template($this->templatePath . 'file.html', '{{', '}}');
|
Chris@14
|
57
|
Chris@14
|
58 $template->setVar(
|
Chris@14
|
59 [
|
Chris@14
|
60 'items' => $this->renderItems($node),
|
Chris@14
|
61 'lines' => $this->renderSource($node)
|
Chris@14
|
62 ]
|
Chris@14
|
63 );
|
Chris@14
|
64
|
Chris@14
|
65 $this->setCommonTemplateVariables($template, $node);
|
Chris@14
|
66
|
Chris@14
|
67 $template->renderTo($file);
|
Chris@14
|
68 }
|
Chris@14
|
69
|
Chris@14
|
70 /**
|
Chris@14
|
71 * @param FileNode $node
|
Chris@14
|
72 *
|
Chris@14
|
73 * @return string
|
Chris@14
|
74 */
|
Chris@14
|
75 protected function renderItems(FileNode $node)
|
Chris@14
|
76 {
|
Chris@14
|
77 $template = new \Text_Template($this->templatePath . 'file_item.html', '{{', '}}');
|
Chris@14
|
78
|
Chris@14
|
79 $methodItemTemplate = new \Text_Template(
|
Chris@14
|
80 $this->templatePath . 'method_item.html',
|
Chris@14
|
81 '{{',
|
Chris@14
|
82 '}}'
|
Chris@14
|
83 );
|
Chris@14
|
84
|
Chris@14
|
85 $items = $this->renderItemTemplate(
|
Chris@14
|
86 $template,
|
Chris@14
|
87 [
|
Chris@14
|
88 'name' => 'Total',
|
Chris@14
|
89 'numClasses' => $node->getNumClassesAndTraits(),
|
Chris@14
|
90 'numTestedClasses' => $node->getNumTestedClassesAndTraits(),
|
Chris@14
|
91 'numMethods' => $node->getNumFunctionsAndMethods(),
|
Chris@14
|
92 'numTestedMethods' => $node->getNumTestedFunctionsAndMethods(),
|
Chris@14
|
93 'linesExecutedPercent' => $node->getLineExecutedPercent(false),
|
Chris@14
|
94 'linesExecutedPercentAsString' => $node->getLineExecutedPercent(),
|
Chris@14
|
95 'numExecutedLines' => $node->getNumExecutedLines(),
|
Chris@14
|
96 'numExecutableLines' => $node->getNumExecutableLines(),
|
Chris@14
|
97 'testedMethodsPercent' => $node->getTestedFunctionsAndMethodsPercent(false),
|
Chris@14
|
98 'testedMethodsPercentAsString' => $node->getTestedFunctionsAndMethodsPercent(),
|
Chris@14
|
99 'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false),
|
Chris@14
|
100 'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent(),
|
Chris@14
|
101 'crap' => '<abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr>'
|
Chris@14
|
102 ]
|
Chris@14
|
103 );
|
Chris@14
|
104
|
Chris@14
|
105 $items .= $this->renderFunctionItems(
|
Chris@14
|
106 $node->getFunctions(),
|
Chris@14
|
107 $methodItemTemplate
|
Chris@14
|
108 );
|
Chris@14
|
109
|
Chris@14
|
110 $items .= $this->renderTraitOrClassItems(
|
Chris@14
|
111 $node->getTraits(),
|
Chris@14
|
112 $template,
|
Chris@14
|
113 $methodItemTemplate
|
Chris@14
|
114 );
|
Chris@14
|
115
|
Chris@14
|
116 $items .= $this->renderTraitOrClassItems(
|
Chris@14
|
117 $node->getClasses(),
|
Chris@14
|
118 $template,
|
Chris@14
|
119 $methodItemTemplate
|
Chris@14
|
120 );
|
Chris@14
|
121
|
Chris@14
|
122 return $items;
|
Chris@14
|
123 }
|
Chris@14
|
124
|
Chris@14
|
125 /**
|
Chris@14
|
126 * @param array $items
|
Chris@14
|
127 * @param \Text_Template $template
|
Chris@14
|
128 * @param \Text_Template $methodItemTemplate
|
Chris@14
|
129 *
|
Chris@14
|
130 * @return string
|
Chris@14
|
131 */
|
Chris@14
|
132 protected function renderTraitOrClassItems(array $items, \Text_Template $template, \Text_Template $methodItemTemplate)
|
Chris@14
|
133 {
|
Chris@14
|
134 $buffer = '';
|
Chris@14
|
135
|
Chris@14
|
136 if (empty($items)) {
|
Chris@14
|
137 return $buffer;
|
Chris@14
|
138 }
|
Chris@14
|
139
|
Chris@14
|
140 foreach ($items as $name => $item) {
|
Chris@14
|
141 $numMethods = 0;
|
Chris@14
|
142 $numTestedMethods = 0;
|
Chris@14
|
143
|
Chris@14
|
144 foreach ($item['methods'] as $method) {
|
Chris@14
|
145 if ($method['executableLines'] > 0) {
|
Chris@14
|
146 $numMethods++;
|
Chris@14
|
147
|
Chris@14
|
148 if ($method['executedLines'] === $method['executableLines']) {
|
Chris@14
|
149 $numTestedMethods++;
|
Chris@14
|
150 }
|
Chris@14
|
151 }
|
Chris@14
|
152 }
|
Chris@14
|
153
|
Chris@14
|
154 if ($item['executableLines'] > 0) {
|
Chris@14
|
155 $numClasses = 1;
|
Chris@14
|
156 $numTestedClasses = $numTestedMethods == $numMethods ? 1 : 0;
|
Chris@14
|
157 $linesExecutedPercentAsString = Util::percent(
|
Chris@14
|
158 $item['executedLines'],
|
Chris@14
|
159 $item['executableLines'],
|
Chris@14
|
160 true
|
Chris@14
|
161 );
|
Chris@14
|
162 } else {
|
Chris@14
|
163 $numClasses = 'n/a';
|
Chris@14
|
164 $numTestedClasses = 'n/a';
|
Chris@14
|
165 $linesExecutedPercentAsString = 'n/a';
|
Chris@14
|
166 }
|
Chris@14
|
167
|
Chris@14
|
168 $buffer .= $this->renderItemTemplate(
|
Chris@14
|
169 $template,
|
Chris@14
|
170 [
|
Chris@14
|
171 'name' => $name,
|
Chris@14
|
172 'numClasses' => $numClasses,
|
Chris@14
|
173 'numTestedClasses' => $numTestedClasses,
|
Chris@14
|
174 'numMethods' => $numMethods,
|
Chris@14
|
175 'numTestedMethods' => $numTestedMethods,
|
Chris@14
|
176 'linesExecutedPercent' => Util::percent(
|
Chris@14
|
177 $item['executedLines'],
|
Chris@14
|
178 $item['executableLines'],
|
Chris@14
|
179 false
|
Chris@14
|
180 ),
|
Chris@14
|
181 'linesExecutedPercentAsString' => $linesExecutedPercentAsString,
|
Chris@14
|
182 'numExecutedLines' => $item['executedLines'],
|
Chris@14
|
183 'numExecutableLines' => $item['executableLines'],
|
Chris@14
|
184 'testedMethodsPercent' => Util::percent(
|
Chris@14
|
185 $numTestedMethods,
|
Chris@14
|
186 $numMethods,
|
Chris@14
|
187 false
|
Chris@14
|
188 ),
|
Chris@14
|
189 'testedMethodsPercentAsString' => Util::percent(
|
Chris@14
|
190 $numTestedMethods,
|
Chris@14
|
191 $numMethods,
|
Chris@14
|
192 true
|
Chris@14
|
193 ),
|
Chris@14
|
194 'testedClassesPercent' => Util::percent(
|
Chris@14
|
195 $numTestedMethods == $numMethods ? 1 : 0,
|
Chris@14
|
196 1,
|
Chris@14
|
197 false
|
Chris@14
|
198 ),
|
Chris@14
|
199 'testedClassesPercentAsString' => Util::percent(
|
Chris@14
|
200 $numTestedMethods == $numMethods ? 1 : 0,
|
Chris@14
|
201 1,
|
Chris@14
|
202 true
|
Chris@14
|
203 ),
|
Chris@14
|
204 'crap' => $item['crap']
|
Chris@14
|
205 ]
|
Chris@14
|
206 );
|
Chris@14
|
207
|
Chris@14
|
208 foreach ($item['methods'] as $method) {
|
Chris@14
|
209 $buffer .= $this->renderFunctionOrMethodItem(
|
Chris@14
|
210 $methodItemTemplate,
|
Chris@14
|
211 $method,
|
Chris@14
|
212 ' '
|
Chris@14
|
213 );
|
Chris@14
|
214 }
|
Chris@14
|
215 }
|
Chris@14
|
216
|
Chris@14
|
217 return $buffer;
|
Chris@14
|
218 }
|
Chris@14
|
219
|
Chris@14
|
220 /**
|
Chris@14
|
221 * @param array $functions
|
Chris@14
|
222 * @param \Text_Template $template
|
Chris@14
|
223 *
|
Chris@14
|
224 * @return string
|
Chris@14
|
225 */
|
Chris@14
|
226 protected function renderFunctionItems(array $functions, \Text_Template $template)
|
Chris@14
|
227 {
|
Chris@14
|
228 if (empty($functions)) {
|
Chris@14
|
229 return '';
|
Chris@14
|
230 }
|
Chris@14
|
231
|
Chris@14
|
232 $buffer = '';
|
Chris@14
|
233
|
Chris@14
|
234 foreach ($functions as $function) {
|
Chris@14
|
235 $buffer .= $this->renderFunctionOrMethodItem(
|
Chris@14
|
236 $template,
|
Chris@14
|
237 $function
|
Chris@14
|
238 );
|
Chris@14
|
239 }
|
Chris@14
|
240
|
Chris@14
|
241 return $buffer;
|
Chris@14
|
242 }
|
Chris@14
|
243
|
Chris@14
|
244 /**
|
Chris@14
|
245 * @param \Text_Template $template
|
Chris@14
|
246 *
|
Chris@14
|
247 * @return string
|
Chris@14
|
248 */
|
Chris@14
|
249 protected function renderFunctionOrMethodItem(\Text_Template $template, array $item, $indent = '')
|
Chris@14
|
250 {
|
Chris@14
|
251 $numMethods = 0;
|
Chris@14
|
252 $numTestedMethods = 0;
|
Chris@14
|
253
|
Chris@14
|
254 if ($item['executableLines'] > 0) {
|
Chris@14
|
255 $numMethods = 1;
|
Chris@14
|
256
|
Chris@14
|
257 if ($item['executedLines'] === $item['executableLines']) {
|
Chris@14
|
258 $numTestedMethods = 1;
|
Chris@14
|
259 }
|
Chris@14
|
260 }
|
Chris@14
|
261
|
Chris@14
|
262 return $this->renderItemTemplate(
|
Chris@14
|
263 $template,
|
Chris@14
|
264 [
|
Chris@14
|
265 'name' => \sprintf(
|
Chris@14
|
266 '%s<a href="#%d"><abbr title="%s">%s</abbr></a>',
|
Chris@14
|
267 $indent,
|
Chris@14
|
268 $item['startLine'],
|
Chris@14
|
269 \htmlspecialchars($item['signature']),
|
Chris@14
|
270 isset($item['functionName']) ? $item['functionName'] : $item['methodName']
|
Chris@14
|
271 ),
|
Chris@14
|
272 'numMethods' => $numMethods,
|
Chris@14
|
273 'numTestedMethods' => $numTestedMethods,
|
Chris@14
|
274 'linesExecutedPercent' => Util::percent(
|
Chris@14
|
275 $item['executedLines'],
|
Chris@14
|
276 $item['executableLines'],
|
Chris@14
|
277 false
|
Chris@14
|
278 ),
|
Chris@14
|
279 'linesExecutedPercentAsString' => Util::percent(
|
Chris@14
|
280 $item['executedLines'],
|
Chris@14
|
281 $item['executableLines'],
|
Chris@14
|
282 true
|
Chris@14
|
283 ),
|
Chris@14
|
284 'numExecutedLines' => $item['executedLines'],
|
Chris@14
|
285 'numExecutableLines' => $item['executableLines'],
|
Chris@14
|
286 'testedMethodsPercent' => Util::percent(
|
Chris@14
|
287 $numTestedMethods,
|
Chris@14
|
288 1,
|
Chris@14
|
289 false
|
Chris@14
|
290 ),
|
Chris@14
|
291 'testedMethodsPercentAsString' => Util::percent(
|
Chris@14
|
292 $numTestedMethods,
|
Chris@14
|
293 1,
|
Chris@14
|
294 true
|
Chris@14
|
295 ),
|
Chris@14
|
296 'crap' => $item['crap']
|
Chris@14
|
297 ]
|
Chris@14
|
298 );
|
Chris@14
|
299 }
|
Chris@14
|
300
|
Chris@14
|
301 /**
|
Chris@14
|
302 * @param FileNode $node
|
Chris@14
|
303 *
|
Chris@14
|
304 * @return string
|
Chris@14
|
305 */
|
Chris@14
|
306 protected function renderSource(FileNode $node)
|
Chris@14
|
307 {
|
Chris@14
|
308 $coverageData = $node->getCoverageData();
|
Chris@14
|
309 $testData = $node->getTestData();
|
Chris@14
|
310 $codeLines = $this->loadFile($node->getPath());
|
Chris@14
|
311 $lines = '';
|
Chris@14
|
312 $i = 1;
|
Chris@14
|
313
|
Chris@14
|
314 foreach ($codeLines as $line) {
|
Chris@14
|
315 $trClass = '';
|
Chris@14
|
316 $popoverContent = '';
|
Chris@14
|
317 $popoverTitle = '';
|
Chris@14
|
318
|
Chris@14
|
319 if (\array_key_exists($i, $coverageData)) {
|
Chris@14
|
320 $numTests = ($coverageData[$i] ? \count($coverageData[$i]) : 0);
|
Chris@14
|
321
|
Chris@14
|
322 if ($coverageData[$i] === null) {
|
Chris@14
|
323 $trClass = ' class="warning"';
|
Chris@14
|
324 } elseif ($numTests == 0) {
|
Chris@14
|
325 $trClass = ' class="danger"';
|
Chris@14
|
326 } else {
|
Chris@14
|
327 $lineCss = 'covered-by-large-tests';
|
Chris@14
|
328 $popoverContent = '<ul>';
|
Chris@14
|
329
|
Chris@14
|
330 if ($numTests > 1) {
|
Chris@14
|
331 $popoverTitle = $numTests . ' tests cover line ' . $i;
|
Chris@14
|
332 } else {
|
Chris@14
|
333 $popoverTitle = '1 test covers line ' . $i;
|
Chris@14
|
334 }
|
Chris@14
|
335
|
Chris@14
|
336 foreach ($coverageData[$i] as $test) {
|
Chris@14
|
337 if ($lineCss == 'covered-by-large-tests' && $testData[$test]['size'] == 'medium') {
|
Chris@14
|
338 $lineCss = 'covered-by-medium-tests';
|
Chris@14
|
339 } elseif ($testData[$test]['size'] == 'small') {
|
Chris@14
|
340 $lineCss = 'covered-by-small-tests';
|
Chris@14
|
341 }
|
Chris@14
|
342
|
Chris@14
|
343 switch ($testData[$test]['status']) {
|
Chris@14
|
344 case 0:
|
Chris@14
|
345 switch ($testData[$test]['size']) {
|
Chris@14
|
346 case 'small':
|
Chris@14
|
347 $testCSS = ' class="covered-by-small-tests"';
|
Chris@14
|
348
|
Chris@14
|
349 break;
|
Chris@14
|
350
|
Chris@14
|
351 case 'medium':
|
Chris@14
|
352 $testCSS = ' class="covered-by-medium-tests"';
|
Chris@14
|
353
|
Chris@14
|
354 break;
|
Chris@14
|
355
|
Chris@14
|
356 default:
|
Chris@14
|
357 $testCSS = ' class="covered-by-large-tests"';
|
Chris@14
|
358
|
Chris@14
|
359 break;
|
Chris@14
|
360 }
|
Chris@14
|
361
|
Chris@14
|
362 break;
|
Chris@14
|
363
|
Chris@14
|
364 case 1:
|
Chris@14
|
365 case 2:
|
Chris@14
|
366 $testCSS = ' class="warning"';
|
Chris@14
|
367
|
Chris@14
|
368 break;
|
Chris@14
|
369
|
Chris@14
|
370 case 3:
|
Chris@14
|
371 $testCSS = ' class="danger"';
|
Chris@14
|
372
|
Chris@14
|
373 break;
|
Chris@14
|
374
|
Chris@14
|
375 case 4:
|
Chris@14
|
376 $testCSS = ' class="danger"';
|
Chris@14
|
377
|
Chris@14
|
378 break;
|
Chris@14
|
379
|
Chris@14
|
380 default:
|
Chris@14
|
381 $testCSS = '';
|
Chris@14
|
382 }
|
Chris@14
|
383
|
Chris@14
|
384 $popoverContent .= \sprintf(
|
Chris@14
|
385 '<li%s>%s</li>',
|
Chris@14
|
386 $testCSS,
|
Chris@14
|
387 \htmlspecialchars($test)
|
Chris@14
|
388 );
|
Chris@14
|
389 }
|
Chris@14
|
390
|
Chris@14
|
391 $popoverContent .= '</ul>';
|
Chris@14
|
392 $trClass = ' class="' . $lineCss . ' popin"';
|
Chris@14
|
393 }
|
Chris@14
|
394 }
|
Chris@14
|
395
|
Chris@14
|
396 if (!empty($popoverTitle)) {
|
Chris@14
|
397 $popover = \sprintf(
|
Chris@14
|
398 ' data-title="%s" data-content="%s" data-placement="bottom" data-html="true"',
|
Chris@14
|
399 $popoverTitle,
|
Chris@14
|
400 \htmlspecialchars($popoverContent)
|
Chris@14
|
401 );
|
Chris@14
|
402 } else {
|
Chris@14
|
403 $popover = '';
|
Chris@14
|
404 }
|
Chris@14
|
405
|
Chris@14
|
406 $lines .= \sprintf(
|
Chris@14
|
407 ' <tr%s%s><td><div align="right"><a name="%d"></a><a href="#%d">%d</a></div></td><td class="codeLine">%s</td></tr>' . "\n",
|
Chris@14
|
408 $trClass,
|
Chris@14
|
409 $popover,
|
Chris@14
|
410 $i,
|
Chris@14
|
411 $i,
|
Chris@14
|
412 $i,
|
Chris@14
|
413 $line
|
Chris@14
|
414 );
|
Chris@14
|
415
|
Chris@14
|
416 $i++;
|
Chris@14
|
417 }
|
Chris@14
|
418
|
Chris@14
|
419 return $lines;
|
Chris@14
|
420 }
|
Chris@14
|
421
|
Chris@14
|
422 /**
|
Chris@14
|
423 * @param string $file
|
Chris@14
|
424 *
|
Chris@14
|
425 * @return array
|
Chris@14
|
426 */
|
Chris@14
|
427 protected function loadFile($file)
|
Chris@14
|
428 {
|
Chris@14
|
429 $buffer = \file_get_contents($file);
|
Chris@14
|
430 $tokens = \token_get_all($buffer);
|
Chris@14
|
431 $result = [''];
|
Chris@14
|
432 $i = 0;
|
Chris@14
|
433 $stringFlag = false;
|
Chris@14
|
434 $fileEndsWithNewLine = \substr($buffer, -1) == "\n";
|
Chris@14
|
435
|
Chris@14
|
436 unset($buffer);
|
Chris@14
|
437
|
Chris@14
|
438 foreach ($tokens as $j => $token) {
|
Chris@14
|
439 if (\is_string($token)) {
|
Chris@14
|
440 if ($token === '"' && $tokens[$j - 1] !== '\\') {
|
Chris@14
|
441 $result[$i] .= \sprintf(
|
Chris@14
|
442 '<span class="string">%s</span>',
|
Chris@14
|
443 \htmlspecialchars($token)
|
Chris@14
|
444 );
|
Chris@14
|
445
|
Chris@14
|
446 $stringFlag = !$stringFlag;
|
Chris@14
|
447 } else {
|
Chris@14
|
448 $result[$i] .= \sprintf(
|
Chris@14
|
449 '<span class="keyword">%s</span>',
|
Chris@14
|
450 \htmlspecialchars($token)
|
Chris@14
|
451 );
|
Chris@14
|
452 }
|
Chris@14
|
453
|
Chris@14
|
454 continue;
|
Chris@14
|
455 }
|
Chris@14
|
456
|
Chris@14
|
457 list($token, $value) = $token;
|
Chris@14
|
458
|
Chris@14
|
459 $value = \str_replace(
|
Chris@14
|
460 ["\t", ' '],
|
Chris@14
|
461 [' ', ' '],
|
Chris@14
|
462 \htmlspecialchars($value, $this->htmlspecialcharsFlags)
|
Chris@14
|
463 );
|
Chris@14
|
464
|
Chris@14
|
465 if ($value === "\n") {
|
Chris@14
|
466 $result[++$i] = '';
|
Chris@14
|
467 } else {
|
Chris@14
|
468 $lines = \explode("\n", $value);
|
Chris@14
|
469
|
Chris@14
|
470 foreach ($lines as $jj => $line) {
|
Chris@14
|
471 $line = \trim($line);
|
Chris@14
|
472
|
Chris@14
|
473 if ($line !== '') {
|
Chris@14
|
474 if ($stringFlag) {
|
Chris@14
|
475 $colour = 'string';
|
Chris@14
|
476 } else {
|
Chris@14
|
477 switch ($token) {
|
Chris@14
|
478 case T_INLINE_HTML:
|
Chris@14
|
479 $colour = 'html';
|
Chris@14
|
480
|
Chris@14
|
481 break;
|
Chris@14
|
482
|
Chris@14
|
483 case T_COMMENT:
|
Chris@14
|
484 case T_DOC_COMMENT:
|
Chris@14
|
485 $colour = 'comment';
|
Chris@14
|
486
|
Chris@14
|
487 break;
|
Chris@14
|
488
|
Chris@14
|
489 case T_ABSTRACT:
|
Chris@14
|
490 case T_ARRAY:
|
Chris@14
|
491 case T_AS:
|
Chris@14
|
492 case T_BREAK:
|
Chris@14
|
493 case T_CALLABLE:
|
Chris@14
|
494 case T_CASE:
|
Chris@14
|
495 case T_CATCH:
|
Chris@14
|
496 case T_CLASS:
|
Chris@14
|
497 case T_CLONE:
|
Chris@14
|
498 case T_CONTINUE:
|
Chris@14
|
499 case T_DEFAULT:
|
Chris@14
|
500 case T_ECHO:
|
Chris@14
|
501 case T_ELSE:
|
Chris@14
|
502 case T_ELSEIF:
|
Chris@14
|
503 case T_EMPTY:
|
Chris@14
|
504 case T_ENDDECLARE:
|
Chris@14
|
505 case T_ENDFOR:
|
Chris@14
|
506 case T_ENDFOREACH:
|
Chris@14
|
507 case T_ENDIF:
|
Chris@14
|
508 case T_ENDSWITCH:
|
Chris@14
|
509 case T_ENDWHILE:
|
Chris@14
|
510 case T_EXIT:
|
Chris@14
|
511 case T_EXTENDS:
|
Chris@14
|
512 case T_FINAL:
|
Chris@14
|
513 case T_FINALLY:
|
Chris@14
|
514 case T_FOREACH:
|
Chris@14
|
515 case T_FUNCTION:
|
Chris@14
|
516 case T_GLOBAL:
|
Chris@14
|
517 case T_IF:
|
Chris@14
|
518 case T_IMPLEMENTS:
|
Chris@14
|
519 case T_INCLUDE:
|
Chris@14
|
520 case T_INCLUDE_ONCE:
|
Chris@14
|
521 case T_INSTANCEOF:
|
Chris@14
|
522 case T_INSTEADOF:
|
Chris@14
|
523 case T_INTERFACE:
|
Chris@14
|
524 case T_ISSET:
|
Chris@14
|
525 case T_LOGICAL_AND:
|
Chris@14
|
526 case T_LOGICAL_OR:
|
Chris@14
|
527 case T_LOGICAL_XOR:
|
Chris@14
|
528 case T_NAMESPACE:
|
Chris@14
|
529 case T_NEW:
|
Chris@14
|
530 case T_PRIVATE:
|
Chris@14
|
531 case T_PROTECTED:
|
Chris@14
|
532 case T_PUBLIC:
|
Chris@14
|
533 case T_REQUIRE:
|
Chris@14
|
534 case T_REQUIRE_ONCE:
|
Chris@14
|
535 case T_RETURN:
|
Chris@14
|
536 case T_STATIC:
|
Chris@14
|
537 case T_THROW:
|
Chris@14
|
538 case T_TRAIT:
|
Chris@14
|
539 case T_TRY:
|
Chris@14
|
540 case T_UNSET:
|
Chris@14
|
541 case T_USE:
|
Chris@14
|
542 case T_VAR:
|
Chris@14
|
543 case T_WHILE:
|
Chris@14
|
544 case T_YIELD:
|
Chris@14
|
545 $colour = 'keyword';
|
Chris@14
|
546
|
Chris@14
|
547 break;
|
Chris@14
|
548
|
Chris@14
|
549 default:
|
Chris@14
|
550 $colour = 'default';
|
Chris@14
|
551 }
|
Chris@14
|
552 }
|
Chris@14
|
553
|
Chris@14
|
554 $result[$i] .= \sprintf(
|
Chris@14
|
555 '<span class="%s">%s</span>',
|
Chris@14
|
556 $colour,
|
Chris@14
|
557 $line
|
Chris@14
|
558 );
|
Chris@14
|
559 }
|
Chris@14
|
560
|
Chris@14
|
561 if (isset($lines[$jj + 1])) {
|
Chris@14
|
562 $result[++$i] = '';
|
Chris@14
|
563 }
|
Chris@14
|
564 }
|
Chris@14
|
565 }
|
Chris@14
|
566 }
|
Chris@14
|
567
|
Chris@14
|
568 if ($fileEndsWithNewLine) {
|
Chris@14
|
569 unset($result[\count($result) - 1]);
|
Chris@14
|
570 }
|
Chris@14
|
571
|
Chris@14
|
572 return $result;
|
Chris@14
|
573 }
|
Chris@14
|
574 }
|