PluginProbe
Code Engine – PHP Snippets, AI Functions & Automation for WordPress / 0.5.1
Code Engine – PHP Snippets, AI Functions & Automation for WordPress v0.5.1
0.5.7 0.5.6 0.5.5 0.5.4 0.5.3 0.5.2 0.5.1 0.5.0 0.4.9 0.4.8 0.4.7 0.4.6 trunk 0.0.1 0.0.2 0.2.8 0.2.9 0.3.0 0.3.1 0.3.2 0.3.3 0.3.4 0.3.5 0.3.6 0.3.7 All 33 releases
code-engine / vendor / nikic / php-parser / lib / PhpParser / Node / Name.php

Name.php in Code Engine – PHP Snippets, AI Functions & Automation for WordPress 0.5.1, at vendor/nikic/php-parser/lib/PhpParser/Node/Name.php

270 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php declare(strict_types=1);
2
3 namespace PhpParser\Node;
4
5 use PhpParser\NodeAbstract;
6
7 class Name extends NodeAbstract {
8 /** @var string Name as string */
9 public string $name;
10
11 /** @var array<string, bool> */
12 private static array $specialClassNames = [
13 'self' => true,
14 'parent' => true,
15 'static' => true,
16 ];
17
18 /**
19 * Constructs a name node.
20 *
21 * @param string|string[]|self $name Name as string, part array or Name instance (copy ctor)
22 * @param array<string, mixed> $attributes Additional attributes
23 */
24 final public function __construct($name, array $attributes = []) {
25 $this->attributes = $attributes;
26 $this->name = self::prepareName($name);
27 }
28
29 public function getSubNodeNames(): array {
30 return ['name'];
31 }
32
33 /**
34 * Get parts of name (split by the namespace separator).
35 *
36 * @return string[] Parts of name
37 */
38 public function getParts(): array {
39 return \explode('\\', $this->name);
40 }
41
42 /**
43 * Gets the first part of the name, i.e. everything before the first namespace separator.
44 *
45 * @return string First part of the name
46 */
47 public function getFirst(): string {
48 if (false !== $pos = \strpos($this->name, '\\')) {
49 return \substr($this->name, 0, $pos);
50 }
51 return $this->name;
52 }
53
54 /**
55 * Gets the last part of the name, i.e. everything after the last namespace separator.
56 *
57 * @return string Last part of the name
58 */
59 public function getLast(): string {
60 if (false !== $pos = \strrpos($this->name, '\\')) {
61 return \substr($this->name, $pos + 1);
62 }
63 return $this->name;
64 }
65
66 /**
67 * Checks whether the name is unqualified. (E.g. Name)
68 *
69 * @return bool Whether the name is unqualified
70 */
71 public function isUnqualified(): bool {
72 return false === \strpos($this->name, '\\');
73 }
74
75 /**
76 * Checks whether the name is qualified. (E.g. Name\Name)
77 *
78 * @return bool Whether the name is qualified
79 */
80 public function isQualified(): bool {
81 return false !== \strpos($this->name, '\\');
82 }
83
84 /**
85 * Checks whether the name is fully qualified. (E.g. \Name)
86 *
87 * @return bool Whether the name is fully qualified
88 */
89 public function isFullyQualified(): bool {
90 return false;
91 }
92
93 /**
94 * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name)
95 *
96 * @return bool Whether the name is relative
97 */
98 public function isRelative(): bool {
99 return false;
100 }
101
102 /**
103 * Returns a string representation of the name itself, without taking the name type into
104 * account (e.g., not including a leading backslash for fully qualified names).
105 *
106 * @return string String representation
107 */
108 public function toString(): string {
109 return $this->name;
110 }
111
112 /**
113 * Returns a string representation of the name as it would occur in code (e.g., including
114 * leading backslash for fully qualified names.
115 *
116 * @return string String representation
117 */
118 public function toCodeString(): string {
119 return $this->toString();
120 }
121
122 /**
123 * Returns lowercased string representation of the name, without taking the name type into
124 * account (e.g., no leading backslash for fully qualified names).
125 *
126 * @return string Lowercased string representation
127 */
128 public function toLowerString(): string {
129 return strtolower($this->name);
130 }
131
132 /**
133 * Checks whether the identifier is a special class name (self, parent or static).
134 *
135 * @return bool Whether identifier is a special class name
136 */
137 public function isSpecialClassName(): bool {
138 return isset(self::$specialClassNames[strtolower($this->name)]);
139 }
140
141 /**
142 * Returns a string representation of the name by imploding the namespace parts with the
143 * namespace separator.
144 *
145 * @return string String representation
146 */
147 public function __toString(): string {
148 return $this->name;
149 }
150
151 /**
152 * Gets a slice of a name (similar to array_slice).
153 *
154 * This method returns a new instance of the same type as the original and with the same
155 * attributes.
156 *
157 * If the slice is empty, null is returned. The null value will be correctly handled in
158 * concatenations using concat().
159 *
160 * Offset and length have the same meaning as in array_slice().
161 *
162 * @param int $offset Offset to start the slice at (may be negative)
163 * @param int|null $length Length of the slice (may be negative)
164 *
165 * @return static|null Sliced name
166 */
167 public function slice(int $offset, ?int $length = null) {
168 if ($offset === 1 && $length === null) {
169 // Short-circuit the common case.
170 if (false !== $pos = \strpos($this->name, '\\')) {
171 return new static(\substr($this->name, $pos + 1));
172 }
173 return null;
174 }
175
176 $parts = \explode('\\', $this->name);
177 $numParts = \count($parts);
178
179 $realOffset = $offset < 0 ? $offset + $numParts : $offset;
180 if ($realOffset < 0 || $realOffset > $numParts) {
181 throw new \OutOfBoundsException(sprintf('Offset %d is out of bounds', $offset));
182 }
183
184 if (null === $length) {
185 $realLength = $numParts - $realOffset;
186 } else {
187 $realLength = $length < 0 ? $length + $numParts - $realOffset : $length;
188 if ($realLength < 0 || $realLength > $numParts - $realOffset) {
189 throw new \OutOfBoundsException(sprintf('Length %d is out of bounds', $length));
190 }
191 }
192
193 if ($realLength === 0) {
194 // Empty slice is represented as null
195 return null;
196 }
197
198 return new static(array_slice($parts, $realOffset, $realLength), $this->attributes);
199 }
200
201 /**
202 * Concatenate two names, yielding a new Name instance.
203 *
204 * The type of the generated instance depends on which class this method is called on, for
205 * example Name\FullyQualified::concat() will yield a Name\FullyQualified instance.
206 *
207 * If one of the arguments is null, a new instance of the other name will be returned. If both
208 * arguments are null, null will be returned. As such, writing
209 * Name::concat($namespace, $shortName)
210 * where $namespace is a Name node or null will work as expected.
211 *
212 * @param string|string[]|self|null $name1 The first name
213 * @param string|string[]|self|null $name2 The second name
214 * @param array<string, mixed> $attributes Attributes to assign to concatenated name
215 *
216 * @return static|null Concatenated name
217 */
218 public static function concat($name1, $name2, array $attributes = []) {
219 if (null === $name1 && null === $name2) {
220 return null;
221 }
222 if (null === $name1) {
223 return new static($name2, $attributes);
224 }
225 if (null === $name2) {
226 return new static($name1, $attributes);
227 } else {
228 return new static(
229 self::prepareName($name1) . '\\' . self::prepareName($name2), $attributes
230 );
231 }
232 }
233
234 /**
235 * Prepares a (string, array or Name node) name for use in name changing methods by converting
236 * it to a string.
237 *
238 * @param string|string[]|self $name Name to prepare
239 *
240 * @return string Prepared name
241 */
242 private static function prepareName($name): string {
243 if (\is_string($name)) {
244 if ('' === $name) {
245 throw new \InvalidArgumentException('Name cannot be empty');
246 }
247
248 return $name;
249 }
250 if (\is_array($name)) {
251 if (empty($name)) {
252 throw new \InvalidArgumentException('Name cannot be empty');
253 }
254
255 return implode('\\', $name);
256 }
257 if ($name instanceof self) {
258 return $name->name;
259 }
260
261 throw new \InvalidArgumentException(
262 'Expected string, array of parts or Name instance'
263 );
264 }
265
266 public function getType(): string {
267 return 'Name';
268 }
269 }
270