comparison vendor/phpunit/php-token-stream/src/Token/Stream.php @ 14:1fec387a4317

Update Drupal core to 8.5.2 via Composer
author Chris Cannam
date Mon, 23 Apr 2018 09:46:53 +0100
parents 7a779792577d
children
comparison
equal deleted inserted replaced
13:5fb285c0d0e3 14:1fec387a4317
1 <?php 1 <?php
2 /* 2 /*
3 * This file is part of the PHP_TokenStream package. 3 * This file is part of php-token-stream.
4 * 4 *
5 * (c) Sebastian Bergmann <sebastian@phpunit.de> 5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6 * 6 *
7 * For the full copyright and license information, please view the LICENSE 7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code. 8 * file that was distributed with this source code.
9 */ 9 */
10 10
11 /** 11 /**
12 * A stream of PHP tokens. 12 * A stream of PHP tokens.
13 *
14 * @author Sebastian Bergmann <sebastian@phpunit.de>
15 * @copyright Sebastian Bergmann <sebastian@phpunit.de>
16 * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
17 * @link http://github.com/sebastianbergmann/php-token-stream/tree
18 * @since Class available since Release 1.0.0
19 */ 13 */
20 class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator 14 class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
21 { 15 {
22 /** 16 /**
23 * @var array 17 * @var array
24 */ 18 */
25 protected static $customTokens = array( 19 protected static $customTokens = [
26 '(' => 'PHP_Token_OPEN_BRACKET', 20 '(' => 'PHP_Token_OPEN_BRACKET',
27 ')' => 'PHP_Token_CLOSE_BRACKET', 21 ')' => 'PHP_Token_CLOSE_BRACKET',
28 '[' => 'PHP_Token_OPEN_SQUARE', 22 '[' => 'PHP_Token_OPEN_SQUARE',
29 ']' => 'PHP_Token_CLOSE_SQUARE', 23 ']' => 'PHP_Token_CLOSE_SQUARE',
30 '{' => 'PHP_Token_OPEN_CURLY', 24 '{' => 'PHP_Token_OPEN_CURLY',
49 '|' => 'PHP_Token_PIPE', 43 '|' => 'PHP_Token_PIPE',
50 '$' => 'PHP_Token_DOLLAR', 44 '$' => 'PHP_Token_DOLLAR',
51 '^' => 'PHP_Token_CARET', 45 '^' => 'PHP_Token_CARET',
52 '~' => 'PHP_Token_TILDE', 46 '~' => 'PHP_Token_TILDE',
53 '`' => 'PHP_Token_BACKTICK' 47 '`' => 'PHP_Token_BACKTICK'
54 ); 48 ];
55 49
56 /** 50 /**
57 * @var string 51 * @var string
58 */ 52 */
59 protected $filename; 53 protected $filename;
60 54
61 /** 55 /**
62 * @var array 56 * @var array
63 */ 57 */
64 protected $tokens = array(); 58 protected $tokens = [];
65 59
66 /** 60 /**
67 * @var integer 61 * @var int
68 */ 62 */
69 protected $position = 0; 63 protected $position = 0;
70 64
71 /** 65 /**
72 * @var array 66 * @var array
73 */ 67 */
74 protected $linesOfCode = array('loc' => 0, 'cloc' => 0, 'ncloc' => 0); 68 protected $linesOfCode = ['loc' => 0, 'cloc' => 0, 'ncloc' => 0];
75 69
76 /** 70 /**
77 * @var array 71 * @var array
78 */ 72 */
79 protected $classes; 73 protected $classes;
99 protected $traits; 93 protected $traits;
100 94
101 /** 95 /**
102 * @var array 96 * @var array
103 */ 97 */
104 protected $lineToFunctionMap = array(); 98 protected $lineToFunctionMap = [];
105 99
106 /** 100 /**
107 * Constructor. 101 * Constructor.
108 * 102 *
109 * @param string $sourceCode 103 * @param string $sourceCode
121 /** 115 /**
122 * Destructor. 116 * Destructor.
123 */ 117 */
124 public function __destruct() 118 public function __destruct()
125 { 119 {
126 $this->tokens = array(); 120 $this->tokens = [];
127 } 121 }
128 122
129 /** 123 /**
130 * @return string 124 * @return string
131 */ 125 */
140 return $buffer; 134 return $buffer;
141 } 135 }
142 136
143 /** 137 /**
144 * @return string 138 * @return string
145 * @since Method available since Release 1.1.0
146 */ 139 */
147 public function getFilename() 140 public function getFilename()
148 { 141 {
149 return $this->filename; 142 return $this->filename;
150 } 143 }
172 $name = substr(token_name($token[0]), 2); 165 $name = substr(token_name($token[0]), 2);
173 $text = $token[1]; 166 $text = $token[1];
174 167
175 if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') { 168 if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') {
176 $name = 'CLASS_NAME_CONSTANT'; 169 $name = 'CLASS_NAME_CONSTANT';
177 } elseif ($name == 'USE' && isset($tokens[$i+2][0]) && $tokens[$i+2][0] == T_FUNCTION) { 170 } elseif ($name == 'USE' && isset($tokens[$i + 2][0]) && $tokens[$i + 2][0] == T_FUNCTION) {
178 $name = 'USE_FUNCTION'; 171 $name = 'USE_FUNCTION';
179 $text .= $tokens[$i+1][1] . $tokens[$i+2][1]; 172 $text .= $tokens[$i + 1][1] . $tokens[$i + 2][1];
180 $skip = 2; 173 $skip = 2;
181 } 174 }
182 175
183 $tokenClass = 'PHP_Token_' . $name; 176 $tokenClass = 'PHP_Token_' . $name;
184 } else { 177 } else {
186 $tokenClass = self::$customTokens[$token]; 179 $tokenClass = self::$customTokens[$token];
187 } 180 }
188 181
189 $this->tokens[] = new $tokenClass($text, $line, $this, $id++); 182 $this->tokens[] = new $tokenClass($text, $line, $this, $id++);
190 $lines = substr_count($text, "\n"); 183 $lines = substr_count($text, "\n");
191 $line += $lines; 184 $line += $lines;
192 185
193 if ($tokenClass == 'PHP_Token_HALT_COMPILER') { 186 if ($tokenClass == 'PHP_Token_HALT_COMPILER') {
194 break; 187 break;
195 } elseif ($tokenClass == 'PHP_Token_COMMENT' || 188 } elseif ($tokenClass == 'PHP_Token_COMMENT' ||
196 $tokenClass == 'PHP_Token_DOC_COMMENT') { 189 $tokenClass == 'PHP_Token_DOC_COMMENT') {
210 $this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] - 203 $this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] -
211 $this->linesOfCode['cloc']; 204 $this->linesOfCode['cloc'];
212 } 205 }
213 206
214 /** 207 /**
215 * @return integer 208 * @return int
216 */ 209 */
217 public function count() 210 public function count()
218 { 211 {
219 return count($this->tokens); 212 return count($this->tokens);
220 } 213 }
269 return $this->interfaces; 262 return $this->interfaces;
270 } 263 }
271 264
272 /** 265 /**
273 * @return array 266 * @return array
274 * @since Method available since Release 1.1.0
275 */ 267 */
276 public function getTraits() 268 public function getTraits()
277 { 269 {
278 if ($this->traits !== null) { 270 if ($this->traits !== null) {
279 return $this->traits; 271 return $this->traits;
294 * 286 *
295 * Parameter $category allow to filter following specific inclusion type 287 * Parameter $category allow to filter following specific inclusion type
296 * 288 *
297 * @param bool $categorize OPTIONAL 289 * @param bool $categorize OPTIONAL
298 * @param string $category OPTIONAL Either 'require_once', 'require', 290 * @param string $category OPTIONAL Either 'require_once', 'require',
299 * 'include_once', 'include'. 291 * 'include_once', 'include'.
292 *
300 * @return array 293 * @return array
301 * @since Method available since Release 1.1.0
302 */ 294 */
303 public function getIncludes($categorize = false, $category = null) 295 public function getIncludes($categorize = false, $category = null)
304 { 296 {
305 if ($this->includes === null) { 297 if ($this->includes === null) {
306 $this->includes = array( 298 $this->includes = [
307 'require_once' => array(), 299 'require_once' => [],
308 'require' => array(), 300 'require' => [],
309 'include_once' => array(), 301 'include_once' => [],
310 'include' => array() 302 'include' => []
311 ); 303 ];
312 304
313 foreach ($this->tokens as $token) { 305 foreach ($this->tokens as $token) {
314 switch (get_class($token)) { 306 switch (get_class($token)) {
315 case 'PHP_Token_REQUIRE_ONCE': 307 case 'PHP_Token_REQUIRE_ONCE':
316 case 'PHP_Token_REQUIRE': 308 case 'PHP_Token_REQUIRE':
340 332
341 /** 333 /**
342 * Returns the name of the function or method a line belongs to. 334 * Returns the name of the function or method a line belongs to.
343 * 335 *
344 * @return string or null if the line is not in a function or method 336 * @return string or null if the line is not in a function or method
345 * @since Method available since Release 1.2.0
346 */ 337 */
347 public function getFunctionForLine($line) 338 public function getFunctionForLine($line)
348 { 339 {
349 $this->parse(); 340 $this->parse();
350 341
353 } 344 }
354 } 345 }
355 346
356 protected function parse() 347 protected function parse()
357 { 348 {
358 $this->interfaces = array(); 349 $this->interfaces = [];
359 $this->classes = array(); 350 $this->classes = [];
360 $this->traits = array(); 351 $this->traits = [];
361 $this->functions = array(); 352 $this->functions = [];
362 $class = array(); 353 $class = [];
363 $classEndLine = array(); 354 $classEndLine = [];
364 $trait = false; 355 $trait = false;
365 $traitEndLine = false; 356 $traitEndLine = false;
366 $interface = false; 357 $interface = false;
367 $interfaceEndLine = false; 358 $interfaceEndLine = false;
368 359
373 364
374 case 'PHP_Token_INTERFACE': 365 case 'PHP_Token_INTERFACE':
375 $interface = $token->getName(); 366 $interface = $token->getName();
376 $interfaceEndLine = $token->getEndLine(); 367 $interfaceEndLine = $token->getEndLine();
377 368
378 $this->interfaces[$interface] = array( 369 $this->interfaces[$interface] = [
379 'methods' => array(), 370 'methods' => [],
380 'parent' => $token->getParent(), 371 'parent' => $token->getParent(),
381 'keywords' => $token->getKeywords(), 372 'keywords' => $token->getKeywords(),
382 'docblock' => $token->getDocblock(), 373 'docblock' => $token->getDocblock(),
383 'startLine' => $token->getLine(), 374 'startLine' => $token->getLine(),
384 'endLine' => $interfaceEndLine, 375 'endLine' => $interfaceEndLine,
385 'package' => $token->getPackage(), 376 'package' => $token->getPackage(),
386 'file' => $this->filename 377 'file' => $this->filename
387 ); 378 ];
388 break; 379 break;
389 380
390 case 'PHP_Token_CLASS': 381 case 'PHP_Token_CLASS':
391 case 'PHP_Token_TRAIT': 382 case 'PHP_Token_TRAIT':
392 $tmp = array( 383 $tmp = [
393 'methods' => array(), 384 'methods' => [],
394 'parent' => $token->getParent(), 385 'parent' => $token->getParent(),
395 'interfaces'=> $token->getInterfaces(), 386 'interfaces'=> $token->getInterfaces(),
396 'keywords' => $token->getKeywords(), 387 'keywords' => $token->getKeywords(),
397 'docblock' => $token->getDocblock(), 388 'docblock' => $token->getDocblock(),
398 'startLine' => $token->getLine(), 389 'startLine' => $token->getLine(),
399 'endLine' => $token->getEndLine(), 390 'endLine' => $token->getEndLine(),
400 'package' => $token->getPackage(), 391 'package' => $token->getPackage(),
401 'file' => $this->filename 392 'file' => $this->filename
402 ); 393 ];
403 394
404 if ($token instanceof PHP_Token_CLASS) { 395 if ($token instanceof PHP_Token_CLASS) {
405 $class[] = $token->getName(); 396 $class[] = $token->getName();
406 $classEndLine[] = $token->getEndLine(); 397 $classEndLine[] = $token->getEndLine();
407 398
408 if ($class[count($class)-1] != 'anonymous class') { 399 $this->classes[$class[count($class) - 1]] = $tmp;
409 $this->classes[$class[count($class)-1]] = $tmp;
410 }
411 } else { 400 } else {
412 $trait = $token->getName(); 401 $trait = $token->getName();
413 $traitEndLine = $token->getEndLine(); 402 $traitEndLine = $token->getEndLine();
414 $this->traits[$trait] = $tmp; 403 $this->traits[$trait] = $tmp;
415 } 404 }
416 break; 405 break;
417 406
418 case 'PHP_Token_FUNCTION': 407 case 'PHP_Token_FUNCTION':
419 $name = $token->getName(); 408 $name = $token->getName();
420 $tmp = array( 409 $tmp = [
421 'docblock' => $token->getDocblock(), 410 'docblock' => $token->getDocblock(),
422 'keywords' => $token->getKeywords(), 411 'keywords' => $token->getKeywords(),
423 'visibility'=> $token->getVisibility(), 412 'visibility'=> $token->getVisibility(),
424 'signature' => $token->getSignature(), 413 'signature' => $token->getSignature(),
425 'startLine' => $token->getLine(), 414 'startLine' => $token->getLine(),
426 'endLine' => $token->getEndLine(), 415 'endLine' => $token->getEndLine(),
427 'ccn' => $token->getCCN(), 416 'ccn' => $token->getCCN(),
428 'file' => $this->filename 417 'file' => $this->filename
429 ); 418 ];
430 419
431 if (empty($class) && 420 if (empty($class) &&
432 $trait === false && 421 $trait === false &&
433 $interface === false) { 422 $interface === false) {
434 $this->functions[$name] = $tmp; 423 $this->functions[$name] = $tmp;
436 $this->addFunctionToMap( 425 $this->addFunctionToMap(
437 $name, 426 $name,
438 $tmp['startLine'], 427 $tmp['startLine'],
439 $tmp['endLine'] 428 $tmp['endLine']
440 ); 429 );
441 } elseif (!empty($class) && $class[count($class)-1] != 'anonymous class') { 430 } elseif (!empty($class)) {
442 $this->classes[$class[count($class)-1]]['methods'][$name] = $tmp; 431 $this->classes[$class[count($class) - 1]]['methods'][$name] = $tmp;
443 432
444 $this->addFunctionToMap( 433 $this->addFunctionToMap(
445 $class[count($class)-1] . '::' . $name, 434 $class[count($class) - 1] . '::' . $name,
446 $tmp['startLine'], 435 $tmp['startLine'],
447 $tmp['endLine'] 436 $tmp['endLine']
448 ); 437 );
449 } elseif ($trait !== false) { 438 } elseif ($trait !== false) {
450 $this->traits[$trait]['methods'][$name] = $tmp; 439 $this->traits[$trait]['methods'][$name] = $tmp;
459 } 448 }
460 break; 449 break;
461 450
462 case 'PHP_Token_CLOSE_CURLY': 451 case 'PHP_Token_CLOSE_CURLY':
463 if (!empty($classEndLine) && 452 if (!empty($classEndLine) &&
464 $classEndLine[count($classEndLine)-1] == $token->getLine()) { 453 $classEndLine[count($classEndLine) - 1] == $token->getLine()) {
465 array_pop($classEndLine); 454 array_pop($classEndLine);
466 array_pop($class); 455 array_pop($class);
467 } elseif ($traitEndLine !== false && 456 } elseif ($traitEndLine !== false &&
468 $traitEndLine == $token->getLine()) { 457 $traitEndLine == $token->getLine()) {
469 $trait = false; 458 $trait = false;
492 { 481 {
493 $this->position = 0; 482 $this->position = 0;
494 } 483 }
495 484
496 /** 485 /**
497 * @return boolean 486 * @return bool
498 */ 487 */
499 public function valid() 488 public function valid()
500 { 489 {
501 return isset($this->tokens[$this->position]); 490 return isset($this->tokens[$this->position]);
502 } 491 }
503 492
504 /** 493 /**
505 * @return integer 494 * @return int
506 */ 495 */
507 public function key() 496 public function key()
508 { 497 {
509 return $this->position; 498 return $this->position;
510 } 499 }
523 { 512 {
524 $this->position++; 513 $this->position++;
525 } 514 }
526 515
527 /** 516 /**
528 * @param integer $offset 517 * @param int $offset
529 * @return boolean 518 *
519 * @return bool
530 */ 520 */
531 public function offsetExists($offset) 521 public function offsetExists($offset)
532 { 522 {
533 return isset($this->tokens[$offset]); 523 return isset($this->tokens[$offset]);
534 } 524 }
535 525
536 /** 526 /**
537 * @param integer $offset 527 * @param int $offset
528 *
538 * @return mixed 529 * @return mixed
530 *
539 * @throws OutOfBoundsException 531 * @throws OutOfBoundsException
540 */ 532 */
541 public function offsetGet($offset) 533 public function offsetGet($offset)
542 { 534 {
543 if (!$this->offsetExists($offset)) { 535 if (!$this->offsetExists($offset)) {
551 543
552 return $this->tokens[$offset]; 544 return $this->tokens[$offset];
553 } 545 }
554 546
555 /** 547 /**
556 * @param integer $offset 548 * @param int $offset
557 * @param mixed $value 549 * @param mixed $value
558 */ 550 */
559 public function offsetSet($offset, $value) 551 public function offsetSet($offset, $value)
560 { 552 {
561 $this->tokens[$offset] = $value; 553 $this->tokens[$offset] = $value;
562 } 554 }
563 555
564 /** 556 /**
565 * @param integer $offset 557 * @param int $offset
558 *
566 * @throws OutOfBoundsException 559 * @throws OutOfBoundsException
567 */ 560 */
568 public function offsetUnset($offset) 561 public function offsetUnset($offset)
569 { 562 {
570 if (!$this->offsetExists($offset)) { 563 if (!$this->offsetExists($offset)) {
580 } 573 }
581 574
582 /** 575 /**
583 * Seek to an absolute position. 576 * Seek to an absolute position.
584 * 577 *
585 * @param integer $position 578 * @param int $position
579 *
586 * @throws OutOfBoundsException 580 * @throws OutOfBoundsException
587 */ 581 */
588 public function seek($position) 582 public function seek($position)
589 { 583 {
590 $this->position = $position; 584 $this->position = $position;
598 ); 592 );
599 } 593 }
600 } 594 }
601 595
602 /** 596 /**
603 * @param string $name 597 * @param string $name
604 * @param integer $startLine 598 * @param int $startLine
605 * @param integer $endLine 599 * @param int $endLine
606 */ 600 */
607 private function addFunctionToMap($name, $startLine, $endLine) 601 private function addFunctionToMap($name, $startLine, $endLine)
608 { 602 {
609 for ($line = $startLine; $line <= $endLine; $line++) { 603 for ($line = $startLine; $line <= $endLine; $line++) {
610 $this->lineToFunctionMap[$line] = $name; 604 $this->lineToFunctionMap[$line] = $name;