PATH:
home
/
centosnipponia
/
public_html
/
apptt
/
vendor
/
phpunit
/
php-token-stream
/
src
<?php declare(strict_types=1); /* * This file is part of phpunit/php-token-stream. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator { /** * @var array<string, class-string<PHP_Token>> */ protected static $customTokens = [ '(' => PHP_Token_OPEN_BRACKET::class, ')' => PHP_Token_CLOSE_BRACKET::class, '[' => PHP_Token_OPEN_SQUARE::class, ']' => PHP_Token_CLOSE_SQUARE::class, '{' => PHP_Token_OPEN_CURLY::class, '}' => PHP_Token_CLOSE_CURLY::class, ';' => PHP_Token_SEMICOLON::class, '.' => PHP_Token_DOT::class, ',' => PHP_Token_COMMA::class, '=' => PHP_Token_EQUAL::class, '<' => PHP_Token_LT::class, '>' => PHP_Token_GT::class, '+' => PHP_Token_PLUS::class, '-' => PHP_Token_MINUS::class, '*' => PHP_Token_MULT::class, '/' => PHP_Token_DIV::class, '?' => PHP_Token_QUESTION_MARK::class, '!' => PHP_Token_EXCLAMATION_MARK::class, ':' => PHP_Token_COLON::class, '"' => PHP_Token_DOUBLE_QUOTES::class, '@' => PHP_Token_AT::class, '&' => PHP_Token_AMPERSAND::class, '%' => PHP_Token_PERCENT::class, '|' => PHP_Token_PIPE::class, '$' => PHP_Token_DOLLAR::class, '^' => PHP_Token_CARET::class, '~' => PHP_Token_TILDE::class, '`' => PHP_Token_BACKTICK::class, ]; /** * @var string */ protected $filename; /** * @var array */ protected $tokens = []; /** * @var array */ protected $tokensByLine = []; /** * @var int */ protected $position = 0; /** * @var array */ protected $linesOfCode = ['loc' => 0, 'cloc' => 0, 'ncloc' => 0]; /** * @var array */ protected $classes; /** * @var array */ protected $functions; /** * @var array */ protected $includes; /** * @var array */ protected $interfaces; /** * @var array */ protected $traits; /** * @var array */ protected $lineToFunctionMap = []; /** * Constructor. * * @param string $sourceCode */ public function __construct($sourceCode) { if (\is_file($sourceCode)) { $this->filename = $sourceCode; $sourceCode = \file_get_contents($sourceCode); } $this->scan($sourceCode); } /** * Destructor. */ public function __destruct() { $this->tokens = []; $this->tokensByLine = []; } /** * @return string */ public function __toString() { $buffer = ''; foreach ($this as $token) { $buffer .= $token; } return $buffer; } /** * @return string */ public function getFilename() { return $this->filename; } /** * @return int */ public function count() { return \count($this->tokens); } /** * @return PHP_Token[] */ public function tokens() { return $this->tokens; } /** * @return array */ public function getClasses() { if ($this->classes !== null) { return $this->classes; } $this->parse(); return $this->classes; } /** * @return array */ public function getFunctions() { if ($this->functions !== null) { return $this->functions; } $this->parse(); return $this->functions; } /** * @return array */ public function getInterfaces() { if ($this->interfaces !== null) { return $this->interfaces; } $this->parse(); return $this->interfaces; } /** * @return array */ public function getTraits() { if ($this->traits !== null) { return $this->traits; } $this->parse(); return $this->traits; } /** * Gets the names of all files that have been included * using include(), include_once(), require() or require_once(). * * Parameter $categorize set to TRUE causing this function to return a * multi-dimensional array with categories in the keys of the first dimension * and constants and their values in the second dimension. * * Parameter $category allow to filter following specific inclusion type * * @param bool $categorize OPTIONAL * @param string $category OPTIONAL Either 'require_once', 'require', * 'include_once', 'include' * * @return array */ public function getIncludes($categorize = false, $category = null) { if ($this->includes === null) { $this->includes = [ 'require_once' => [], 'require' => [], 'include_once' => [], 'include' => [], ]; foreach ($this->tokens as $token) { switch (\get_class($token)) { case PHP_Token_REQUIRE_ONCE::class: case PHP_Token_REQUIRE::class: case PHP_Token_INCLUDE_ONCE::class: case PHP_Token_INCLUDE::class: $this->includes[$token->getType()][] = $token->getName(); break; } } } if (isset($this->includes[$category])) { $includes = $this->includes[$category]; } elseif ($categorize === false) { $includes = \array_merge( $this->includes['require_once'], $this->includes['require'], $this->includes['include_once'], $this->includes['include'] ); } else { $includes = $this->includes; } return $includes; } /** * Returns the name of the function or method a line belongs to. * * @return string or null if the line is not in a function or method */ public function getFunctionForLine($line) { $this->parse(); if (isset($this->lineToFunctionMap[$line])) { return $this->lineToFunctionMap[$line]; } } /** * @return array */ public function getLinesOfCode() { return $this->linesOfCode; } public function rewind()/*: void*/ { $this->position = 0; } /** * @return bool */ public function valid() { return isset($this->tokens[$this->position]); } /** * @return int */ public function key() { return $this->position; } /** * @return PHP_Token */ public function current() { return $this->tokens[$this->position]; } public function next()/*: void*/ { $this->position++; } /** * @param int $offset * * @return bool */ public function offsetExists($offset) { return isset($this->tokens[$offset]); } /** * @param int $offset * * @throws OutOfBoundsException */ public function offsetGet($offset) { if (!$this->offsetExists($offset)) { throw new OutOfBoundsException( \sprintf( 'No token at position "%s"', $offset ) ); } return $this->tokens[$offset]; } /** * @param int $offset */ public function offsetSet($offset, $value)/*: void*/ { $this->tokens[$offset] = $value; } /** * @param int $offset * * @throws OutOfBoundsException */ public function offsetUnset($offset)/*: void*/ { if (!$this->offsetExists($offset)) { throw new OutOfBoundsException( \sprintf( 'No token at position "%s"', $offset ) ); } unset($this->tokens[$offset]); } /** * Seek to an absolute position. * * @param int $position * * @throws OutOfBoundsException */ public function seek($position)/*: void*/ { $this->position = $position; if (!$this->valid()) { throw new OutOfBoundsException( \sprintf( 'No token at position "%s"', $this->position ) ); } } /** * Scans the source for sequences of characters and converts them into a * stream of tokens. * * @param string $sourceCode */ protected function scan($sourceCode)/*: void*/ { $id = 0; $line = 1; $tokens = \token_get_all($sourceCode); $numTokens = \count($tokens); $lastNonWhitespaceTokenWasDoubleColon = false; $name = null; for ($i = 0; $i < $numTokens; ++$i) { $token = $tokens[$i]; $skip = 0; if (\is_array($token)) { $name = \substr(\token_name($token[0]), 2); $text = $token[1]; if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') { $name = 'CLASS_NAME_CONSTANT'; } elseif ($name == 'USE' && isset($tokens[$i + 2][0]) && $tokens[$i + 2][0] == \T_FUNCTION) { $name = 'USE_FUNCTION'; $text .= $tokens[$i + 1][1] . $tokens[$i + 2][1]; $skip = 2; } /** @var class-string<PHP_Token> $tokenClass */ $tokenClass = 'PHP_Token_' . $name; } else { $text = $token; $tokenClass = self::$customTokens[$token]; } /* * @see https://github.com/sebastianbergmann/php-token-stream/issues/95 */ if (PHP_MAJOR_VERSION >= 8 && $name === 'WHITESPACE' && // Current token is T_WHITESPACE isset($this->tokens[$id - 1]) && // Current token is not the first token $this->tokens[$id - 1] instanceof PHP_Token_COMMENT && // Previous token is T_COMMENT strpos((string) $this->tokens[$id - 1], '/*') === false && // Previous token is comment that starts with '#' or '//' strpos($text, "\n") === 0 // Text of current token begins with newline ) { $this->tokens[$id - 1] = new PHP_Token_COMMENT( $this->tokens[$id - 1] . "\n", $this->tokens[$id - 1]->getLine(), $this, $id - 1 ); $text = substr($text, 1); $line++; if (empty($text)) { continue; } } if (!isset($this->tokensByLine[$line])) { $this->tokensByLine[$line] = []; } $token = new $tokenClass($text, $line, $this, $id++); $this->tokens[] = $token; $this->tokensByLine[$line][] = $token; $line += \substr_count($text, "\n"); if ($tokenClass == PHP_Token_HALT_COMPILER::class) { break; } if ($name == 'DOUBLE_COLON') { $lastNonWhitespaceTokenWasDoubleColon = true; } elseif ($name != 'WHITESPACE') { $lastNonWhitespaceTokenWasDoubleColon = false; } $i += $skip; } foreach ($this->tokens as $token) { if (!$token instanceof PHP_Token_COMMENT && !$token instanceof PHP_Token_DOC_COMMENT) { continue; } foreach ($this->tokensByLine[$token->getLine()] as $_token) { if (!$_token instanceof PHP_Token_COMMENT && !$_token instanceof PHP_Token_DOC_COMMENT && !$_token instanceof PHP_Token_WHITESPACE) { continue 2; } } $this->linesOfCode['cloc'] += max(1, \substr_count((string) $token, "\n")); } $this->linesOfCode['loc'] = \substr_count($sourceCode, "\n"); $this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] - $this->linesOfCode['cloc']; } protected function parse()/*: void*/ { $this->interfaces = []; $this->classes = []; $this->traits = []; $this->functions = []; $class = []; $classEndLine = []; $trait = false; $traitEndLine = false; $interface = false; $interfaceEndLine = false; foreach ($this->tokens as $token) { switch (\get_class($token)) { case PHP_Token_HALT_COMPILER::class: return; case PHP_Token_INTERFACE::class: $interface = $token->getName(); $interfaceEndLine = $token->getEndLine(); $this->interfaces[$interface] = [ 'methods' => [], 'parent' => $token->getParent(), 'keywords' => $token->getKeywords(), 'docblock' => $token->getDocblock(), 'startLine' => $token->getLine(), 'endLine' => $interfaceEndLine, 'package' => $token->getPackage(), 'file' => $this->filename, ]; break; case PHP_Token_CLASS::class: case PHP_Token_TRAIT::class: $tmp = [ 'methods' => [], 'parent' => $token->getParent(), 'interfaces'=> $token->getInterfaces(), 'keywords' => $token->getKeywords(), 'docblock' => $token->getDocblock(), 'startLine' => $token->getLine(), 'endLine' => $token->getEndLine(), 'package' => $token->getPackage(), 'file' => $this->filename, ]; if ($token instanceof PHP_Token_CLASS) { $class[] = $token->getName(); $classEndLine[] = $token->getEndLine(); if ($token->getName() !== null) { $this->classes[$class[\count($class) - 1]] = $tmp; } } else { $trait = $token->getName(); $traitEndLine = $token->getEndLine(); $this->traits[$trait] = $tmp; } break; case PHP_Token_FUNCTION::class: $name = $token->getName(); $tmp = [ 'docblock' => $token->getDocblock(), 'keywords' => $token->getKeywords(), 'visibility'=> $token->getVisibility(), 'signature' => $token->getSignature(), 'startLine' => $token->getLine(), 'endLine' => $token->getEndLine(), 'ccn' => $token->getCCN(), 'file' => $this->filename, ]; if (empty($class) && $trait === false && $interface === false) { $this->functions[$name] = $tmp; $this->addFunctionToMap( $name, $tmp['startLine'], $tmp['endLine'] ); } elseif (!empty($class)) { if ($class[\count($class) - 1] !== null) { $this->classes[$class[\count($class) - 1]]['methods'][$name] = $tmp; $this->addFunctionToMap( $class[\count($class) - 1] . '::' . $name, $tmp['startLine'], $tmp['endLine'] ); } } elseif ($trait !== false) { $this->traits[$trait]['methods'][$name] = $tmp; $this->addFunctionToMap( $trait . '::' . $name, $tmp['startLine'], $tmp['endLine'] ); } else { $this->interfaces[$interface]['methods'][$name] = $tmp; } break; case PHP_Token_CLOSE_CURLY::class: if (!empty($classEndLine) && $classEndLine[\count($classEndLine) - 1] == $token->getLine()) { \array_pop($classEndLine); \array_pop($class); } elseif ($traitEndLine !== false && $traitEndLine == $token->getLine()) { $trait = false; $traitEndLine = false; } elseif ($interfaceEndLine !== false && $interfaceEndLine == $token->getLine()) { $interface = false; $interfaceEndLine = false; } break; } } } /** * @param string $name * @param int $startLine * @param int $endLine */ private function addFunctionToMap($name, $startLine, $endLine): void { for ($line = $startLine; $line <= $endLine; $line++) { $this->lineToFunctionMap[$line] = $name; } } }
[+]
..
[-] Abstract.php
[edit]
[-] Ampersand.php
[edit]
[-] AndEqual.php
[edit]
[-] Array.php
[edit]
[-] ArrayCast.php
[edit]
[-] As.php
[edit]
[-] At.php
[edit]
[-] Backtick.php
[edit]
[-] BadCharacter.php
[edit]
[-] BoolCast.php
[edit]
[-] BooleanAnd.php
[edit]
[-] BooleanOr.php
[edit]
[-] CachingFactory.php
[edit]
[-] Callable.php
[edit]
[-] Caret.php
[edit]
[-] Case.php
[edit]
[-] Catch.php
[edit]
[-] Character.php
[edit]
[-] Class.php
[edit]
[-] ClassC.php
[edit]
[-] ClassNameConstant.php
[edit]
[-] Clone.php
[edit]
[-] CloseBracket.php
[edit]
[-] CloseCurly.php
[edit]
[-] CloseSquare.php
[edit]
[-] CloseTag.php
[edit]
[-] Coalesce.php
[edit]
[-] CoalesceEqual.php
[edit]
[-] Colon.php
[edit]
[-] Comma.php
[edit]
[-] Comment.php
[edit]
[-] ConcatEqual.php
[edit]
[-] Const.php
[edit]
[-] ConstantEncapsedString.php
[edit]
[-] Continue.php
[edit]
[-] CurlyOpen.php
[edit]
[-] DNumber.php
[edit]
[-] Dec.php
[edit]
[-] Declare.php
[edit]
[-] Default.php
[edit]
[-] Dir.php
[edit]
[-] Div.php
[edit]
[-] DivEqual.php
[edit]
[-] Do.php
[edit]
[-] DocComment.php
[edit]
[-] Dollar.php
[edit]
[-] DollarOpenCurlyBraces.php
[edit]
[-] Dot.php
[edit]
[-] DoubleArrow.php
[edit]
[-] DoubleCast.php
[edit]
[-] DoubleColon.php
[edit]
[-] DoubleQuotes.php
[edit]
[-] Echo.php
[edit]
[-] Ellipsis.php
[edit]
[-] Else.php
[edit]
[-] Elseif.php
[edit]
[-] Empty.php
[edit]
[-] EncapsedAndWhitespace.php
[edit]
[-] EndHeredoc.php
[edit]
[-] Enddeclare.php
[edit]
[-] Endfor.php
[edit]
[-] Endforeach.php
[edit]
[-] Endif.php
[edit]
[-] Endswitch.php
[edit]
[-] Endwhile.php
[edit]
[-] Equal.php
[edit]
[-] Eval.php
[edit]
[-] ExclamationMark.php
[edit]
[-] Exit.php
[edit]
[-] Extends.php
[edit]
[-] File.php
[edit]
[-] Final.php
[edit]
[-] Finally.php
[edit]
[-] Fn.php
[edit]
[-] For.php
[edit]
[-] Foreach.php
[edit]
[-] FuncC.php
[edit]
[-] Function.php
[edit]
[-] Global.php
[edit]
[-] Goto.php
[edit]
[-] Gt.php
[edit]
[-] HaltCompiler.php
[edit]
[-] If.php
[edit]
[-] Implements.php
[edit]
[-] Inc.php
[edit]
[-] Include.php
[edit]
[-] IncludeOnce.php
[edit]
[-] Includes.php
[edit]
[-] InlineHtml.php
[edit]
[-] Instanceof.php
[edit]
[-] Insteadof.php
[edit]
[-] IntCast.php
[edit]
[-] Interface.php
[edit]
[-] IsEqual.php
[edit]
[-] IsGreaterOrEqual.php
[edit]
[-] IsIdentical.php
[edit]
[-] IsNotEqual.php
[edit]
[-] IsNotIdentical.php
[edit]
[-] IsSmallerOrEqual.php
[edit]
[-] Isset.php
[edit]
[-] Line.php
[edit]
[-] List.php
[edit]
[-] Lnumber.php
[edit]
[-] LogicalAnd.php
[edit]
[-] LogicalOr.php
[edit]
[-] LogicalXor.php
[edit]
[-] Lt.php
[edit]
[-] MethodC.php
[edit]
[-] Minus.php
[edit]
[-] MinusEqual.php
[edit]
[-] ModEqual.php
[edit]
[-] MulEqual.php
[edit]
[-] Mult.php
[edit]
[-] NameFullyQualified.php
[edit]
[-] NameQualified.php
[edit]
[-] NameRelative.php
[edit]
[-] Namespace.php
[edit]
[-] New.php
[edit]
[-] NsC.php
[edit]
[-] NsSeparator.php
[edit]
[-] NumString.php
[edit]
[-] ObjectCast.php
[edit]
[-] ObjectOperator.php
[edit]
[-] OpenBracket.php
[edit]
[-] OpenCurly.php
[edit]
[-] OpenSquare.php
[edit]
[-] OpenTag.php
[edit]
[-] OpenTagWithEcho.php
[edit]
[-] OrEqual.php
[edit]
[-] PaamayimNekudotayim.php
[edit]
[-] Percent.php
[edit]
[-] Pipe.php
[edit]
[-] Plus.php
[edit]
[-] PlusEqual.php
[edit]
[-] Pow.php
[edit]
[-] PowEqual.php
[edit]
[-] Print.php
[edit]
[-] Private.php
[edit]
[-] Protected.php
[edit]
[-] Public.php
[edit]
[-] QuestionMark.php
[edit]
[-] Require.php
[edit]
[-] RequireOnce.php
[edit]
[-] Return.php
[edit]
[-] Semicolon.php
[edit]
[-] Sl.php
[edit]
[-] SlEqual.php
[edit]
[-] Spaceship.php
[edit]
[-] Sr.php
[edit]
[-] SrEqual.php
[edit]
[-] StartHeredoc.php
[edit]
[-] Static.php
[edit]
[-] Stream.php
[edit]
[-] String.php
[edit]
[-] StringCast.php
[edit]
[-] StringVarname.php
[edit]
[-] Switch.php
[edit]
[-] Throw.php
[edit]
[-] Tilde.php
[edit]
[-] Token.php
[edit]
[-] TokenWithScope.php
[edit]
[-] TokenWithScopeAndVisibility.php
[edit]
[-] Trait.php
[edit]
[-] TraitC.php
[edit]
[-] Try.php
[edit]
[-] Unset.php
[edit]
[-] UnsetCast.php
[edit]
[-] Use.php
[edit]
[-] UseFunction.php
[edit]
[-] Util.php
[edit]
[-] Var.php
[edit]
[-] Variable.php
[edit]
[-] While.php
[edit]
[-] Whitespace.php
[edit]
[-] XorEqual.php
[edit]
[-] Yield.php
[edit]
[-] YieldFrom.php
[edit]
[-] break.php
[edit]
[-] .htaccess.disabled
[edit]