7b8c8e2324809952669e5c7fc4f1b55768d17abc
[yaffs-website] / vendor / nikic / php-parser / lib / PhpParser / Node / Name.php
1 <?php
2
3 namespace PhpParser\Node;
4
5 use PhpParser\NodeAbstract;
6
7 class Name extends NodeAbstract
8 {
9     /**
10      * @var string[] Parts of the name
11      */
12     public $parts;
13
14     /**
15      * Constructs a name node.
16      *
17      * @param string|array|self $name       Name as string, part array or Name instance (copy ctor)
18      * @param array             $attributes Additional attributes
19      */
20     public function __construct($name, array $attributes = array()) {
21         parent::__construct($attributes);
22         $this->parts = self::prepareName($name);
23     }
24
25     public function getSubNodeNames() {
26         return array('parts');
27     }
28
29     /**
30      * Gets the first part of the name, i.e. everything before the first namespace separator.
31      *
32      * @return string First part of the name
33      */
34     public function getFirst() {
35         return $this->parts[0];
36     }
37
38     /**
39      * Gets the last part of the name, i.e. everything after the last namespace separator.
40      *
41      * @return string Last part of the name
42      */
43     public function getLast() {
44         return $this->parts[count($this->parts) - 1];
45     }
46
47     /**
48      * Checks whether the name is unqualified. (E.g. Name)
49      *
50      * @return bool Whether the name is unqualified
51      */
52     public function isUnqualified() {
53         return 1 == count($this->parts);
54     }
55
56     /**
57      * Checks whether the name is qualified. (E.g. Name\Name)
58      *
59      * @return bool Whether the name is qualified
60      */
61     public function isQualified() {
62         return 1 < count($this->parts);
63     }
64
65     /**
66      * Checks whether the name is fully qualified. (E.g. \Name)
67      *
68      * @return bool Whether the name is fully qualified
69      */
70     public function isFullyQualified() {
71         return false;
72     }
73
74     /**
75      * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name)
76      *
77      * @return bool Whether the name is relative
78      */
79     public function isRelative() {
80         return false;
81     }
82
83     /**
84      * Returns a string representation of the name by imploding the namespace parts with the
85      * namespace separator.
86      *
87      * @return string String representation
88      */
89     public function toString() {
90         return implode('\\', $this->parts);
91     }
92
93     /**
94      * Returns a string representation of the name by imploding the namespace parts with the
95      * namespace separator.
96      *
97      * @return string String representation
98      */
99     public function __toString() {
100         return implode('\\', $this->parts);
101     }
102
103     /**
104      * Gets a slice of a name (similar to array_slice).
105      *
106      * This method returns a new instance of the same type as the original and with the same
107      * attributes.
108      *
109      * If the slice is empty, null is returned. The null value will be correctly handled in
110      * concatenations using concat().
111      *
112      * Offset and length have the same meaning as in array_slice().
113      *
114      * @param int      $offset Offset to start the slice at (may be negative)
115      * @param int|null $length Length of the slice (may be negative)
116      *
117      * @return static|null Sliced name
118      */
119     public function slice($offset, $length = null) {
120         $numParts = count($this->parts);
121
122         $realOffset = $offset < 0 ? $offset + $numParts : $offset;
123         if ($realOffset < 0 || $realOffset > $numParts) {
124             throw new \OutOfBoundsException(sprintf('Offset %d is out of bounds', $offset));
125         }
126
127         if (null === $length) {
128             $realLength = $numParts - $realOffset;
129         } else {
130             $realLength = $length < 0 ? $length + $numParts - $realOffset : $length;
131             if ($realLength < 0 || $realLength > $numParts) {
132                 throw new \OutOfBoundsException(sprintf('Length %d is out of bounds', $length));
133             }
134         }
135
136         if ($realLength === 0) {
137             // Empty slice is represented as null
138             return null;
139         }
140
141         return new static(array_slice($this->parts, $realOffset, $realLength), $this->attributes);
142     }
143
144     /**
145      * Concatenate two names, yielding a new Name instance.
146      *
147      * The type of the generated instance depends on which class this method is called on, for
148      * example Name\FullyQualified::concat() will yield a Name\FullyQualified instance.
149      *
150      * If one of the arguments is null, a new instance of the other name will be returned. If both
151      * arguments are null, null will be returned. As such, writing
152      *     Name::concat($namespace, $shortName)
153      * where $namespace is a Name node or null will work as expected.
154      *
155      * @param string|array|self|null $name1      The first name
156      * @param string|array|self|null $name2      The second name
157      * @param array                  $attributes Attributes to assign to concatenated name
158      *
159      * @return static|null Concatenated name
160      */
161     public static function concat($name1, $name2, array $attributes = []) {
162         if (null === $name1 && null === $name2) {
163             return null;
164         } elseif (null === $name1) {
165             return new static(self::prepareName($name2), $attributes);
166         } else if (null === $name2) {
167             return new static(self::prepareName($name1), $attributes);
168         } else {
169             return new static(
170                 array_merge(self::prepareName($name1), self::prepareName($name2)), $attributes
171             );
172         }
173     }
174
175     /**
176      * Prepares a (string, array or Name node) name for use in name changing methods by converting
177      * it to an array.
178      *
179      * @param string|array|self $name Name to prepare
180      *
181      * @return array Prepared name
182      */
183     private static function prepareName($name) {
184         if (\is_string($name)) {
185             return explode('\\', $name);
186         } elseif (\is_array($name)) {
187             return $name;
188         } elseif ($name instanceof self) {
189             return $name->parts;
190         }
191
192         throw new \InvalidArgumentException(
193             'Expected string, array of parts or Name instance'
194         );
195     }
196 }