PluginProbe ʕ •ᴥ•ʔ
Cookiebot by Usercentrics – Automatic Cookie Banner for GDPR/CCPA & Google Consent Mode / 3.4.2
Cookiebot by Usercentrics – Automatic Cookie Banner for GDPR/CCPA & Google Consent Mode v3.4.2
4.7.2 4.7.1 trunk 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 3.0.0 3.0.1 3.1.0 3.10.0 3.10.1 3.11.1 3.11.2 3.11.3 3.2.0 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.5 3.6.6 3.7.0 3.7.1 3.8.0 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.2.0 4.2.1 4.2.10 4.2.11 4.2.12 4.2.13 4.2.14 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.3.10 4.3.11 4.3.12 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.3.7.1 4.3.8 4.3.9 4.3.9.1 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.10 4.5.11 4.5.2 4.5.3 4.5.4 4.5.5 4.5.6 4.5.7 4.5.8 4.5.9 4.6.0 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.6.6 4.6.7 4.7.0
cookiebot / addons / lib / ioc / php-di / phpdoc-reader / src / PhpDocReader / PhpParser / TokenParser.php
cookiebot / addons / lib / ioc / php-di / phpdoc-reader / src / PhpDocReader / PhpParser Last commit date
TokenParser.php 7 years ago UseStatementParser.php 7 years ago
TokenParser.php
160 lines
1 <?php
2
3 namespace PhpDocReader\PhpParser;
4
5 /**
6 * Parses a file for namespaces/use/class declarations.
7 *
8 * Class taken and adapted from doctrine/annotations to avoid pulling the whole package.
9 *
10 * @author Fabien Potencier <fabien@symfony.com>
11 * @author Christian Kaps <christian.kaps@mohiva.com>
12 */
13 class TokenParser
14 {
15 /**
16 * The token list.
17 *
18 * @var array
19 */
20 private $tokens;
21
22 /**
23 * The number of tokens.
24 *
25 * @var int
26 */
27 private $numTokens;
28
29 /**
30 * The current array pointer.
31 *
32 * @var int
33 */
34 private $pointer = 0;
35
36 /**
37 * @param string $contents
38 */
39 public function __construct($contents)
40 {
41 $this->tokens = token_get_all($contents);
42
43 // The PHP parser sets internal compiler globals for certain things. Annoyingly, the last docblock comment it
44 // saw gets stored in doc_comment. When it comes to compile the next thing to be include()d this stored
45 // doc_comment becomes owned by the first thing the compiler sees in the file that it considers might have a
46 // docblock. If the first thing in the file is a class without a doc block this would cause calls to
47 // getDocBlock() on said class to return our long lost doc_comment. Argh.
48 // To workaround, cause the parser to parse an empty docblock. Sure getDocBlock() will return this, but at least
49 // it's harmless to us.
50 token_get_all("<?php\n/**\n *\n */");
51
52 $this->numTokens = count($this->tokens);
53 }
54
55 /**
56 * Gets all use statements.
57 *
58 * @param string $namespaceName The namespace name of the reflected class.
59 *
60 * @return array A list with all found use statements.
61 */
62 public function parseUseStatements($namespaceName)
63 {
64 $statements = array();
65 while (($token = $this->next())) {
66 if ($token[0] === T_USE) {
67 $statements = array_merge($statements, $this->parseUseStatement());
68 continue;
69 }
70 if ($token[0] !== T_NAMESPACE || $this->parseNamespace() != $namespaceName) {
71 continue;
72 }
73
74 // Get fresh array for new namespace. This is to prevent the parser to collect the use statements
75 // for a previous namespace with the same name. This is the case if a namespace is defined twice
76 // or if a namespace with the same name is commented out.
77 $statements = array();
78 }
79
80 return $statements;
81 }
82
83 /**
84 * Gets the next non whitespace and non comment token.
85 *
86 * @param boolean $docCommentIsComment If TRUE then a doc comment is considered a comment and skipped.
87 * If FALSE then only whitespace and normal comments are skipped.
88 *
89 * @return array|null The token if exists, null otherwise.
90 */
91 private function next($docCommentIsComment = true)
92 {
93 for ($i = $this->pointer; $i < $this->numTokens; $i++) {
94 $this->pointer++;
95 if ($this->tokens[$i][0] === T_WHITESPACE ||
96 $this->tokens[$i][0] === T_COMMENT ||
97 ($docCommentIsComment && $this->tokens[$i][0] === T_DOC_COMMENT)) {
98
99 continue;
100 }
101
102 return $this->tokens[$i];
103 }
104
105 return null;
106 }
107
108 /**
109 * Parses a single use statement.
110 *
111 * @return array A list with all found class names for a use statement.
112 */
113 private function parseUseStatement()
114 {
115 $class = '';
116 $alias = '';
117 $statements = array();
118 $explicitAlias = false;
119 while (($token = $this->next())) {
120 $isNameToken = $token[0] === T_STRING || $token[0] === T_NS_SEPARATOR;
121 if (!$explicitAlias && $isNameToken) {
122 $class .= $token[1];
123 $alias = $token[1];
124 } elseif ($explicitAlias && $isNameToken) {
125 $alias .= $token[1];
126 } elseif ($token[0] === T_AS) {
127 $explicitAlias = true;
128 $alias = '';
129 } elseif ($token === ',') {
130 $statements[strtolower($alias)] = $class;
131 $class = '';
132 $alias = '';
133 $explicitAlias = false;
134 } elseif ($token === ';') {
135 $statements[strtolower($alias)] = $class;
136 break;
137 } else {
138 break;
139 }
140 }
141
142 return $statements;
143 }
144
145 /**
146 * Gets the namespace.
147 *
148 * @return string The found namespace.
149 */
150 private function parseNamespace()
151 {
152 $name = '';
153 while (($token = $this->next()) && ($token[0] === T_STRING || $token[0] === T_NS_SEPARATOR)) {
154 $name .= $token[1];
155 }
156
157 return $name;
158 }
159 }
160