Skip to content

Commit 49b7338

Browse files
committed
WIP introduced CodeCoverage_Token PoPo to avoid fcall costs
1 parent d10990d commit 49b7338

File tree

1 file changed

+71
-61
lines changed

1 file changed

+71
-61
lines changed

src/CodeCoverage/Util/Tokenizer.php

Lines changed: 71 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ class PHP_CodeCoverage_Util_Tokenizer {
55
private $functions = [];
66
private $classes = [];
77
private $traits = [];
8-
private $tlines = [];
98
private $linesOfCode = array('loc' => 0, 'cloc' => 0, 'ncloc' => 0);
109

1110
/**
@@ -46,6 +45,7 @@ public function __construct($filename) {
4645
$this->filename = $filename;
4746
}
4847

48+
4949
private function tconst($token) {
5050
if (is_array($token)) {
5151
return $token[0];
@@ -148,7 +148,7 @@ private function getKeywords(array $tokens, $idx) {
148148

149149
for ($i = $idx - 2; $i > $idx - 7; $i -= 2) {
150150
if (isset($tokens[$i])) {
151-
$tconst = $this->tconst($tokens[$i]);
151+
$tconst = $tokens[$i]->tconst;
152152

153153
if ($tconst === T_PRIVATE || $tconst === T_PROTECTED || $tconst === T_PUBLIC) {
154154
continue;
@@ -169,12 +169,12 @@ private function getKeywords(array $tokens, $idx) {
169169

170170
private function getParent(array $tokens, $i) {
171171
$parent = false;
172-
if ($this->tconst($tokens[$i+4]) === T_EXTENDS) {
172+
if ($tokens[$i+4]->tconst === T_EXTENDS) {
173173
$ci = $i + 6;
174-
$className = $this->tstring($tokens[$ci]);
174+
$className = $tokens[$ci]->tstring;
175175

176-
while (isset($tokens[$ci+1]) && !($this->tconst($tokens[$ci+1]) === T_WHITESPACE)) {
177-
$className .= $this->tstring($tokens[++$ci]);
176+
while (isset($tokens[$ci+1]) && !($tokens[$ci+1]->tconst === T_WHITESPACE)) {
177+
$className .= $tokens[++$ci]->tstring;
178178
}
179179

180180
$parent = $className;
@@ -184,19 +184,19 @@ private function getParent(array $tokens, $i) {
184184

185185
private function getInterfaces(array $tokens, $i) {
186186
$interfaces = false;
187-
if (isset($tokens[$i + 4]) && $this->tconst($tokens[$i + 4]) === T_IMPLEMENTS ||
188-
isset($tokens[$i + 8]) && $this->tconst($tokens[$i + 8]) === T_IMPLEMENTS) {
189-
if ($this->tconst($tokens[$i + 4]) === T_IMPLEMENTS) {
187+
if (isset($tokens[$i + 4]) && $tokens[$i + 4]->tconst === T_IMPLEMENTS ||
188+
isset($tokens[$i + 8]) && $tokens[$i + 8]->tconst === T_IMPLEMENTS) {
189+
if ($tokens[$i + 4]->tconst === T_IMPLEMENTS) {
190190
$ii = $i + 3;
191191
} else {
192192
$ii = $i + 7;
193193
}
194194

195-
while (!$this->tclass($tokens[$ii+1]) === 'PHP_Token_OPEN_CURLY') {
195+
while ($tokens[$ii+1]->tclass !== 'PHP_Token_OPEN_CURLY') {
196196
$ii++;
197197

198-
if ($this->tconst($tokens[$ii]) === T_STRING) {
199-
$interfaces[] = $this->tstring($tokens[$ii]);
198+
if ($tokens[$ii]->tconst === T_STRING) {
199+
$interfaces[] = $tokens[$ii]->tstring;
200200
}
201201
}
202202
}
@@ -211,7 +211,7 @@ private function getVisibility(array $tokens, $idx)
211211
{
212212
for ($i = $idx - 2; $i > $idx - 7; $i -= 2) {
213213
if (isset($tokens[$i])) {
214-
$tconst = $this->tconst($tokens[$i]);
214+
$tconst = $tokens[$i]->tconst;
215215

216216
if ($tconst === T_PRIVATE) {
217217
return "private";
@@ -239,7 +239,7 @@ private function getVisibility(array $tokens, $idx)
239239
* @return string|null Returns the docblock as a string if found
240240
*/
241241
private function getDocblock(array $tokens, $idx) {
242-
$currentLineNumber = $this->tline($idx);
242+
$currentLineNumber = $tokens[$idx]->tline;
243243
$prevLineNumber = $currentLineNumber - 1;
244244

245245
for ($i = $idx - 1; $i; $i--) {
@@ -248,15 +248,15 @@ private function getDocblock(array $tokens, $idx) {
248248
}
249249

250250
$token = $tokens[$i];
251-
$tconst = $this->tconst($token);
251+
$tconst = $token->tconst;
252252

253253
if ($tconst === T_FUNCTION || $tconst === T_CLASS || $tconst === T_TRAIT) {
254254
// Some other trait, class or function, no docblock can be
255255
// used for the current token
256256
break;
257257
}
258258

259-
$line = $this->tline($i);
259+
$line = $tokens[$i]->tline;
260260

261261
if ($line == $currentLineNumber || ($line == $prevLineNumber && $tconst === T_WHITESPACE)) {
262262
continue;
@@ -266,7 +266,7 @@ private function getDocblock(array $tokens, $idx) {
266266
break;
267267
}
268268

269-
return $this->tstring($token);
269+
return $token->tstring;
270270
}
271271
}
272272

@@ -281,8 +281,8 @@ private function getEndTokenId(array $tokens, $idx)
281281

282282
while ($endTokenId === null && isset($tokens[$i])) {
283283
$token = $tokens[$i];
284-
$tclass = $this->tclass($token);
285-
$tconst = $this->tconst($token);
284+
$tclass = $token->tclass;
285+
$tconst = $token->tconst;
286286
if ($tclass === 'PHP_Token_OPEN_CURLY' || $tclass === 'PHP_Token_CURLY_OPEN') {
287287
$block++;
288288
} elseif ($tclass === 'PHP_Token_CLOSE_CURLY') {
@@ -312,7 +312,7 @@ private function getEndTokenId(array $tokens, $idx)
312312
*/
313313
private function getEndLine(array $tokens, $idx)
314314
{
315-
return $this->tline($this->getEndTokenId($tokens, $idx));
315+
return $tokens[$this->getEndTokenId($tokens, $idx)]->tline;
316316
}
317317

318318
/**
@@ -321,7 +321,7 @@ private function getEndLine(array $tokens, $idx)
321321
private function getPackage(array $tokens, $idx)
322322
{
323323
$token = $tokens[$idx];
324-
$className = $this->tname($tokens, $idx);
324+
$className = $tokens[$idx]->tname;
325325
$docComment = $this->getDocblock($tokens, $idx);
326326

327327
$result = array(
@@ -333,9 +333,9 @@ private function getPackage(array $tokens, $idx)
333333
);
334334

335335
for ($i = $idx; $i; --$i) {
336-
$tconst = $this->tconst($tokens[$i]);
336+
$tconst = $tokens[$i]->tconst;
337337
if ($tconst === T_NAMESPACE) {
338-
$result['namespace'] = $this->tname($tokens, $i);
338+
$result['namespace'] = $tokens[$i]->tname;
339339
break;
340340
}
341341
}
@@ -382,18 +382,18 @@ private function arrayToName(array $parts, $join = '\\')
382382
*/
383383
private function getSignature(array $tokens, $idx)
384384
{
385-
if ($this->tname($tokens, $idx) == 'anonymous function') {
385+
if ($tokens[$idx]->tname == 'anonymous function') {
386386
$signature = 'anonymous function';
387387
$i = $idx + 1;
388388
} else {
389389
$signature = '';
390390
$i = $idx + 2;
391391
}
392392

393-
while (isset($tokens[$i]) && ($tclass = $this->tclass($tokens[$i])) &&
394-
$tclass !== 'PHP_Token_OPEN_CURLY' &&
395-
$tclass !== 'PHP_Token_SEMICOLON') {
396-
$signature .= $this->tstring($tokens[$i++]);
393+
while (isset($tokens[$i]) &&
394+
$tokens[$i]->tclass !== 'PHP_Token_OPEN_CURLY' &&
395+
$tokens[$i]->tclass !== 'PHP_Token_SEMICOLON') {
396+
$signature .= $tokens[$i++]->tstring;
397397
}
398398

399399
$signature = trim($signature);
@@ -423,11 +423,11 @@ private function getCCN($tokens, $idx)
423423
T_LOGICAL_OR
424424
);
425425
for ($i = $idx; $i <= $end; $i++) {
426-
$tconst = $this->tconst($tokens[$i]);
426+
$tconst = $tokens[$i]->tconst;
427427
if (in_array($tconst, $ccnTokens)) {
428428
$ccn++;
429429
}
430-
$tclass = $this->tclass($tokens[$i]);
430+
$tclass = $tokens[$i]->tclass;
431431
if ($tclass === 'PHP_Token_QUESTION_MARK') {
432432
$ccn++;
433433
}
@@ -443,21 +443,23 @@ public function tokenize() {
443443

444444
// precalculate in which line the tokens reside, for later lookaheads
445445
$line = 1;
446+
$ccTokens = array();
446447
for ($i = 0; $i < $numTokens; ++$i) {
447-
$token = $tokens[$i];
448-
449-
if (is_array($token)) {
450-
$name = substr(token_name($token[0]), 2);
451-
$text = $token[1];
452-
} else {
453-
$text = $token;
454-
}
455-
456-
$this->tlines[$i] = $line;
448+
$preToken = $tokens[$i];
449+
$text = $this->tstring($preToken);
450+
451+
$ccTokens[] = new CodeCoverage_Token(
452+
$this->tname($tokens, $i),
453+
$this->tconst($preToken),
454+
$this->tclass($preToken),
455+
$text,
456+
$line
457+
);
457458

458459
$lines = substr_count($text, "\n");
459460
$line += $lines;
460461
}
462+
$tokens = $ccTokens;
461463

462464
$class = false;
463465
$classEndLine = false;
@@ -468,16 +470,8 @@ public function tokenize() {
468470
$line = 1;
469471
for ($i = 0; $i < $numTokens; ++$i) {
470472
$token = $tokens[$i];
471-
472-
if (is_array($token)) {
473-
$name = substr(token_name($token[0]), 2);
474-
$text = $token[1];
475-
476-
$tokenClass = 'PHP_Token_' . $name;
477-
} else {
478-
$text = $token;
479-
$tokenClass = self::$customTokens[$token];
480-
}
473+
$text = $token->tstring;
474+
$tokenClass = $token->tclass;
481475

482476
$lines = substr_count($text, "\n");
483477
$line += $lines;
@@ -487,15 +481,15 @@ public function tokenize() {
487481
break 2;
488482

489483
case 'PHP_Token_INTERFACE':
490-
$interface = $this->tname($tokens, $i);
484+
$interface = $tokens[$i]->tname;
491485
$interfaceEndLine = $this->getEndLine($tokens, $i);
492486

493487
$this->interfaces[$interface] = array(
494488
'methods' => array(),
495489
'parent' => $this->getParent($tokens, $i),
496490
'keywords' => $this->getKeywords($tokens, $i),
497491
'docblock' => $this->getDocblock($tokens, $i),
498-
'startLine' => $this->tline($i),
492+
'startLine' => $token->tline,
499493
'endLine' => $interfaceEndLine,
500494
'package' => $this->getPackage($tokens, $i),
501495
'file' => $this->filename
@@ -512,32 +506,32 @@ public function tokenize() {
512506
'interfaces'=> $this->getInterfaces($tokens, $i),
513507
'keywords' => $this->getKeywords($tokens, $i),
514508
'docblock' => $this->getDocblock($tokens, $i),
515-
'startLine' => $this->tline($i),
509+
'startLine' => $token->tline,
516510
'endLine' => $endLine,
517511
'package' => $this->getPackage($tokens, $i),
518512
'file' => $this->filename
519513
);
520514

521-
$tclass = $this->tclass($token);
515+
$tclass = $token->tclass;
522516
if ($tclass === 'PHP_Token_CLASS') {
523-
$class = $this->tname($tokens, $i);
517+
$class = $tokens[$i]->tname;
524518
$classEndLine = $endLine;
525519
$this->classes[$class] = $tmp;
526520
} else {
527-
$trait = $this->tname($tokens, $i);
521+
$trait = $tokens[$i]->tname;
528522
$traitEndLine = $endLine;
529523
$this->traits[$trait] = $tmp;
530524
}
531525
break;
532526

533527
case 'PHP_Token_FUNCTION':
534-
$tname = $this->tname($tokens, $i);
528+
$tname = $tokens[$i]->tname;
535529
$tmp = array(
536530
'docblock' => $this->getDocblock($tokens, $i),
537531
'keywords' => $this->getKeywords($tokens, $i),
538532
'visibility'=> $this->getVisibility($tokens, $i),
539533
'signature' => $this->getSignature($tokens, $i),
540-
'startLine' => $this->tline($i),
534+
'startLine' => $token->tline,
541535
'endLine' => $this->getEndLine($tokens, $i),
542536
'ccn' => $this->getCCN($tokens, $i),
543537
'file' => $this->filename
@@ -555,13 +549,13 @@ public function tokenize() {
555549
break;
556550

557551
case 'PHP_Token_CLOSE_CURLY':
558-
if ($classEndLine !== false && $classEndLine == $this->tline($i)) {
552+
if ($classEndLine !== false && $classEndLine == $token->tline) {
559553
$class = false;
560554
$classEndLine = false;
561-
} elseif ($traitEndLine !== false && $traitEndLine == $this->tline($i)) {
555+
} elseif ($traitEndLine !== false && $traitEndLine == $token->tline) {
562556
$trait = false;
563557
$traitEndLine = false;
564-
} elseif ($interfaceEndLine !== false && $interfaceEndLine == $this->tline($i)) {
558+
} elseif ($interfaceEndLine !== false && $interfaceEndLine == $token->tline) {
565559
$interface = false;
566560
$interfaceEndLine = false;
567561
}
@@ -594,4 +588,20 @@ public function getTraits() {
594588
public function getFunctions() {
595589
return $this->functions;
596590
}
591+
}
592+
593+
class CodeCoverage_Token {
594+
public $tname;
595+
public $tconst;
596+
public $tclass;
597+
public $tstring;
598+
public $tline;
599+
600+
public function __construct($tname, $tconst, $tclass, $tstring, $tline) {
601+
$this->tname = $tname;
602+
$this->tconst = $tconst;
603+
$this->tclass = $tclass;
604+
$this->tstring = $tstring;
605+
$this->tline = $tline;
606+
}
597607
}

0 commit comments

Comments
 (0)