*/ private array $tokens; private int $numTokens; private int $pointer = 0; public function __construct(string $content) { $this->tokens = PhpToken::tokenize($content); $this->numTokens = count($this->tokens); } public function getNamespace(): string { $currentNamespace = ''; while ($token = $this->next()) { if ($token->is(T_NAMESPACE)) { $currentNamespace = $this->parseNamespace(); } } return $currentNamespace; } /** * @return array */ public function parseUseStatements(string $namespaceName): array { $this->pointer = 0; $currentNamespace = ''; $statements = []; while ($token = $this->next()) { if ($currentNamespace === $namespaceName && $token->is(T_USE)) { $statements = [...$statements, ...$this->parseUseStatement()]; continue; } if (! $token->is(T_NAMESPACE)) { continue; } $currentNamespace = $this->parseNamespace(); // Get fresh array for new namespace. This is to prevent the parser // to collect the use statements for a previous namespace with the // same name (this is the case if a namespace is defined twice). $statements = []; } return $statements; } /** * @return array */ private function parseUseStatement(): array { $groupRoot = ''; $class = ''; $alias = ''; $statements = []; $explicitAlias = false; while ($token = $this->next()) { $name = (string)$token; if (! $explicitAlias && $token->is(T_STRING)) { $class = $alias = $name; } elseif ($explicitAlias && $token->is(T_STRING)) { $alias = $name; } elseif ($token->is([T_NAME_QUALIFIED, T_NAME_FULLY_QUALIFIED])) { $class = $name; $classSplit = explode('\\', $name); $alias = $classSplit[count($classSplit) - 1]; } elseif ($token->is(T_NS_SEPARATOR)) { $class .= '\\'; $alias = ''; } elseif ($token->is(T_AS)) { $explicitAlias = true; $alias = ''; } elseif ($name === ',') { $statements[strtolower($alias)] = $groupRoot . $class; $class = $alias = ''; $explicitAlias = false; } elseif ($name === ';') { if ($alias !== '') { $statements[strtolower($alias)] = $groupRoot . $class; } break; } elseif ($name === '{') { $groupRoot = $class; $class = ''; } } return $statements; } private function next(): ?PhpToken { for ($i = $this->pointer; $i < $this->numTokens; $i++) { $this->pointer++; if (! $this->tokens[$i]->isIgnorable()) { return $this->tokens[$i]; } } return null; } private function parseNamespace(): string { while ($token = $this->next()) { if ($token->is([T_NAME_QUALIFIED, T_NAME_FULLY_QUALIFIED, T_STRING])) { return (string)$token; } elseif ($token->is('{')) { return ""; } } /** @infection-ignore-all */ // @codeCoverageIgnoreStart throw new LogicException('Namespace not found.'); // @codeCoverageIgnoreEnd } }