Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php declare(strict_types=1);
2
 
3
namespace PhpParser;
4
 
5
use PhpParser\Node\ComplexType;
6
use PhpParser\Node\Expr;
7
use PhpParser\Node\Identifier;
8
use PhpParser\Node\Name;
9
use PhpParser\Node\NullableType;
10
use PhpParser\Node\Scalar;
11
use PhpParser\Node\Stmt;
12
 
13
/**
14
 * This class defines helpers used in the implementation of builders. Don't use it directly.
15
 *
16
 * @internal
17
 */
18
final class BuilderHelpers
19
{
20
    /**
21
     * Normalizes a node: Converts builder objects to nodes.
22
     *
23
     * @param Node|Builder $node The node to normalize
24
     *
25
     * @return Node The normalized node
26
     */
27
    public static function normalizeNode($node) : Node {
28
        if ($node instanceof Builder) {
29
            return $node->getNode();
30
        }
31
 
32
        if ($node instanceof Node) {
33
            return $node;
34
        }
35
 
36
        throw new \LogicException('Expected node or builder object');
37
    }
38
 
39
    /**
40
     * Normalizes a node to a statement.
41
     *
42
     * Expressions are wrapped in a Stmt\Expression node.
43
     *
44
     * @param Node|Builder $node The node to normalize
45
     *
46
     * @return Stmt The normalized statement node
47
     */
48
    public static function normalizeStmt($node) : Stmt {
49
        $node = self::normalizeNode($node);
50
        if ($node instanceof Stmt) {
51
            return $node;
52
        }
53
 
54
        if ($node instanceof Expr) {
55
            return new Stmt\Expression($node);
56
        }
57
 
58
        throw new \LogicException('Expected statement or expression node');
59
    }
60
 
61
    /**
62
     * Normalizes strings to Identifier.
63
     *
64
     * @param string|Identifier $name The identifier to normalize
65
     *
66
     * @return Identifier The normalized identifier
67
     */
68
    public static function normalizeIdentifier($name) : Identifier {
69
        if ($name instanceof Identifier) {
70
            return $name;
71
        }
72
 
73
        if (\is_string($name)) {
74
            return new Identifier($name);
75
        }
76
 
77
        throw new \LogicException('Expected string or instance of Node\Identifier');
78
    }
79
 
80
    /**
81
     * Normalizes strings to Identifier, also allowing expressions.
82
     *
83
     * @param string|Identifier|Expr $name The identifier to normalize
84
     *
85
     * @return Identifier|Expr The normalized identifier or expression
86
     */
87
    public static function normalizeIdentifierOrExpr($name) {
88
        if ($name instanceof Identifier || $name instanceof Expr) {
89
            return $name;
90
        }
91
 
92
        if (\is_string($name)) {
93
            return new Identifier($name);
94
        }
95
 
96
        throw new \LogicException('Expected string or instance of Node\Identifier or Node\Expr');
97
    }
98
 
99
    /**
100
     * Normalizes a name: Converts string names to Name nodes.
101
     *
102
     * @param Name|string $name The name to normalize
103
     *
104
     * @return Name The normalized name
105
     */
106
    public static function normalizeName($name) : Name {
107
        if ($name instanceof Name) {
108
            return $name;
109
        }
110
 
111
        if (is_string($name)) {
112
            if (!$name) {
113
                throw new \LogicException('Name cannot be empty');
114
            }
115
 
116
            if ($name[0] === '\\') {
117
                return new Name\FullyQualified(substr($name, 1));
118
            }
119
 
120
            if (0 === strpos($name, 'namespace\\')) {
121
                return new Name\Relative(substr($name, strlen('namespace\\')));
122
            }
123
 
124
            return new Name($name);
125
        }
126
 
127
        throw new \LogicException('Name must be a string or an instance of Node\Name');
128
    }
129
 
130
    /**
131
     * Normalizes a name: Converts string names to Name nodes, while also allowing expressions.
132
     *
133
     * @param Expr|Name|string $name The name to normalize
134
     *
135
     * @return Name|Expr The normalized name or expression
136
     */
137
    public static function normalizeNameOrExpr($name) {
138
        if ($name instanceof Expr) {
139
            return $name;
140
        }
141
 
142
        if (!is_string($name) && !($name instanceof Name)) {
143
            throw new \LogicException(
144
                'Name must be a string or an instance of Node\Name or Node\Expr'
145
            );
146
        }
147
 
148
        return self::normalizeName($name);
149
    }
150
 
151
    /**
152
     * Normalizes a type: Converts plain-text type names into proper AST representation.
153
     *
154
     * In particular, builtin types become Identifiers, custom types become Names and nullables
155
     * are wrapped in NullableType nodes.
156
     *
157
     * @param string|Name|Identifier|ComplexType $type The type to normalize
158
     *
159
     * @return Name|Identifier|ComplexType The normalized type
160
     */
161
    public static function normalizeType($type) {
162
        if (!is_string($type)) {
163
            if (
164
                !$type instanceof Name && !$type instanceof Identifier &&
165
                !$type instanceof ComplexType
166
            ) {
167
                throw new \LogicException(
168
                    'Type must be a string, or an instance of Name, Identifier or ComplexType'
169
                );
170
            }
171
            return $type;
172
        }
173
 
174
        $nullable = false;
175
        if (strlen($type) > 0 && $type[0] === '?') {
176
            $nullable = true;
177
            $type = substr($type, 1);
178
        }
179
 
180
        $builtinTypes = [
181
            'array',
182
            'callable',
183
            'bool',
184
            'int',
185
            'float',
186
            'string',
187
            'iterable',
188
            'void',
189
            'object',
190
            'null',
191
            'false',
192
            'mixed',
193
            'never',
194
            'true',
195
        ];
196
 
197
        $lowerType = strtolower($type);
198
        if (in_array($lowerType, $builtinTypes)) {
199
            $type = new Identifier($lowerType);
200
        } else {
201
            $type = self::normalizeName($type);
202
        }
203
 
204
        $notNullableTypes = [
205
            'void', 'mixed', 'never',
206
        ];
207
        if ($nullable && in_array((string) $type, $notNullableTypes)) {
208
            throw new \LogicException(sprintf('%s type cannot be nullable', $type));
209
        }
210
 
211
        return $nullable ? new NullableType($type) : $type;
212
    }
213
 
214
    /**
215
     * Normalizes a value: Converts nulls, booleans, integers,
216
     * floats, strings and arrays into their respective nodes
217
     *
218
     * @param Node\Expr|bool|null|int|float|string|array $value The value to normalize
219
     *
220
     * @return Expr The normalized value
221
     */
222
    public static function normalizeValue($value) : Expr {
223
        if ($value instanceof Node\Expr) {
224
            return $value;
225
        }
226
 
227
        if (is_null($value)) {
228
            return new Expr\ConstFetch(
229
                new Name('null')
230
            );
231
        }
232
 
233
        if (is_bool($value)) {
234
            return new Expr\ConstFetch(
235
                new Name($value ? 'true' : 'false')
236
            );
237
        }
238
 
239
        if (is_int($value)) {
240
            return new Scalar\LNumber($value);
241
        }
242
 
243
        if (is_float($value)) {
244
            return new Scalar\DNumber($value);
245
        }
246
 
247
        if (is_string($value)) {
248
            return new Scalar\String_($value);
249
        }
250
 
251
        if (is_array($value)) {
252
            $items = [];
253
            $lastKey = -1;
254
            foreach ($value as $itemKey => $itemValue) {
255
                // for consecutive, numeric keys don't generate keys
256
                if (null !== $lastKey && ++$lastKey === $itemKey) {
257
                    $items[] = new Expr\ArrayItem(
258
                        self::normalizeValue($itemValue)
259
                    );
260
                } else {
261
                    $lastKey = null;
262
                    $items[] = new Expr\ArrayItem(
263
                        self::normalizeValue($itemValue),
264
                        self::normalizeValue($itemKey)
265
                    );
266
                }
267
            }
268
 
269
            return new Expr\Array_($items);
270
        }
271
 
272
        throw new \LogicException('Invalid value');
273
    }
274
 
275
    /**
276
     * Normalizes a doc comment: Converts plain strings to PhpParser\Comment\Doc.
277
     *
278
     * @param Comment\Doc|string $docComment The doc comment to normalize
279
     *
280
     * @return Comment\Doc The normalized doc comment
281
     */
282
    public static function normalizeDocComment($docComment) : Comment\Doc {
283
        if ($docComment instanceof Comment\Doc) {
284
            return $docComment;
285
        }
286
 
287
        if (is_string($docComment)) {
288
            return new Comment\Doc($docComment);
289
        }
290
 
291
        throw new \LogicException('Doc comment must be a string or an instance of PhpParser\Comment\Doc');
292
    }
293
 
294
    /**
295
     * Normalizes a attribute: Converts attribute to the Attribute Group if needed.
296
     *
297
     * @param Node\Attribute|Node\AttributeGroup $attribute
298
     *
299
     * @return Node\AttributeGroup The Attribute Group
300
     */
301
    public static function normalizeAttribute($attribute) : Node\AttributeGroup
302
    {
303
        if ($attribute instanceof Node\AttributeGroup) {
304
            return $attribute;
305
        }
306
 
307
        if (!($attribute instanceof Node\Attribute)) {
308
            throw new \LogicException('Attribute must be an instance of PhpParser\Node\Attribute or PhpParser\Node\AttributeGroup');
309
        }
310
 
311
        return new Node\AttributeGroup([$attribute]);
312
    }
313
 
314
    /**
315
     * Adds a modifier and returns new modifier bitmask.
316
     *
317
     * @param int $modifiers Existing modifiers
318
     * @param int $modifier  Modifier to set
319
     *
320
     * @return int New modifiers
321
     */
322
    public static function addModifier(int $modifiers, int $modifier) : int {
323
        Stmt\Class_::verifyModifier($modifiers, $modifier);
324
        return $modifiers | $modifier;
325
    }
326
 
327
    /**
328
     * Adds a modifier and returns new modifier bitmask.
329
     * @return int New modifiers
330
     */
331
    public static function addClassModifier(int $existingModifiers, int $modifierToSet) : int {
332
        Stmt\Class_::verifyClassModifier($existingModifiers, $modifierToSet);
333
        return $existingModifiers | $modifierToSet;
334
    }
335
}