Passed
Push — master ( 7cc72b...baad32 )
by Vladimir
10:39
created

Type::getStandardType()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 5.667

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 13
ccs 3
cts 9
cp 0.3333
rs 10
c 0
b 0
f 0
cc 3
nc 4
nop 1
crap 5.667
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Type\Definition;
6
7
use GraphQL\Error\InvariantViolation;
8
use GraphQL\Language\AST\TypeDefinitionNode;
9
use GraphQL\Language\AST\TypeExtensionNode;
10
use GraphQL\Type\Introspection;
11
use GraphQL\Utils\Utils;
12
use JsonSerializable;
13
use ReflectionClass;
14
use function array_keys;
15
use function array_merge;
16
use function implode;
17
use function in_array;
18
use function preg_replace;
19
use function trigger_error;
20
use const E_USER_DEPRECATED;
21
22
/**
23
 * Registry of standard GraphQL types
24
 * and a base class for all other types.
25
 */
26
abstract class Type implements JsonSerializable
27
{
28
    public const STRING  = 'String';
29
    public const INT     = 'Int';
30
    public const BOOLEAN = 'Boolean';
31
    public const FLOAT   = 'Float';
32
    public const ID      = 'ID';
33
34
    /** @var array<string, ScalarType>> */
35
    protected static $standardTypes;
36
37
    /** @var Type[] */
38
    private static $builtInTypes;
39
40
    /** @var string */
41
    public $name;
42
43
    /** @var string|null */
44
    public $description;
45
46
    /** @var TypeDefinitionNode|null */
47
    public $astNode;
48
49
    /** @var mixed[] */
50
    public $config;
51
52
    /** @var TypeExtensionNode[] */
53
    public $extensionASTNodes;
54
55
    /**
56
     * @api
57
     */
58 909
    public static function id() : ScalarType
59
    {
60 909
        if ((static::$standardTypes[self::ID] ?? null) === null) {
61
            static::$standardTypes[self::ID] = new IDType();
62
        }
63
64 909
        return static::$standardTypes[self::ID];
65
    }
66
67
    /**
68
     * @api
69
     */
70 939
    public static function string() : ScalarType
71
    {
72 939
        if ((static::$standardTypes[self::STRING] ?? null) === null) {
73
            static::$standardTypes[self::STRING] = new StringType();
74
        }
75
76 939
        return static::$standardTypes[self::STRING];
77
    }
78
79
    /**
80
     * @api
81
     */
82 959
    public static function boolean() : ScalarType
83
    {
84 959
        if ((static::$standardTypes[self::BOOLEAN] ?? null) === null) {
85
            static::$standardTypes[self::BOOLEAN] = new BooleanType();
86
        }
87
88 959
        return static::$standardTypes[self::BOOLEAN];
89
    }
90
91
    /**
92
     * @api
93
     */
94 979
    public static function int() : ScalarType
95
    {
96 979
        if ((static::$standardTypes[self::INT] ?? null) === null) {
97
            static::$standardTypes[self::INT] = new IntType();
98
        }
99
100 979
        return static::$standardTypes[self::INT];
101
    }
102
103
    /**
104
     * @api
105
     */
106 916
    public static function float() : ScalarType
107
    {
108 916
        if ((static::$standardTypes[self::FLOAT] ?? null) === null) {
109
            static::$standardTypes[self::FLOAT] = new FloatType();
110
        }
111
112 916
        return static::$standardTypes[self::FLOAT];
113
    }
114
115
    /**
116
     * @api
117
     */
118 632
    public static function listOf(Type $wrappedType) : ListOfType
119
    {
120 632
        return new ListOfType($wrappedType);
121
    }
122
123
    /**
124
     * @api
125
     */
126 698
    public static function nonNull(NullableType $wrappedType) : NonNull
127
    {
128 698
        return new NonNull($wrappedType);
129
    }
130
131
    /**
132
     * Checks if the type is a builtin type
133
     */
134 107
    public static function isBuiltInType(Type $type) : bool
135
    {
136 107
        return in_array($type->name, array_keys(self::getAllBuiltInTypes()), true);
137
    }
138
139
    /**
140
     * Returns all builtin in types including base scalar and
141
     * introspection types
142
     *
143
     * @return Type[]
144
     */
145 198
    public static function getAllBuiltInTypes()
146
    {
147 198
        if (self::$builtInTypes === null) {
0 ignored issues
show
introduced by
The condition self::builtInTypes === null is always false.
Loading history...
148 1
            self::$builtInTypes = array_merge(
149 1
                Introspection::getTypes(),
150 1
                self::getStandardTypes()
151
            );
152
        }
153
154 198
        return self::$builtInTypes;
155
    }
156
157
    /**
158
     * Returns all builtin scalar types
159
     *
160
     * @return ScalarType[]
161
     */
162 893
    public static function getStandardTypes()
163
    {
164
        return [
165 893
            self::ID => static::id(),
166 893
            self::STRING => static::string(),
167 893
            self::FLOAT => static::float(),
168 893
            self::INT => static::int(),
169 893
            self::BOOLEAN => static::boolean(),
170
        ];
171
    }
172
173
    /**
174
     * @deprecated Use method getStandardTypes() instead
175
     *
176
     * @return Type[]
177
     *
178
     * @codeCoverageIgnore
179
     */
180
    public static function getInternalTypes()
181
    {
182
        trigger_error(__METHOD__ . ' is deprecated. Use Type::getStandardTypes() instead', E_USER_DEPRECATED);
183
184
        return self::getStandardTypes();
185
    }
186
187
    /**
188
     * @param array<string, ScalarType> $types
189
     */
190 8
    public static function overrideStandardTypes(array $types)
191
    {
192 8
        $standardTypes = self::getStandardTypes();
193 8
        foreach ($types as $type) {
194 8
            Utils::invariant(
195 8
                $type instanceof Type,
196 8
                'Expecting instance of %s, got %s',
197 8
                self::class,
198 8
                Utils::printSafe($type)
199
            );
200 8
            Utils::invariant(
201 8
                isset($type->name, $standardTypes[$type->name]),
202 8
                'Expecting one of the following names for a standard type: %s, got %s',
203 8
                implode(', ', array_keys($standardTypes)),
204 8
                Utils::printSafe($type->name ?? null)
205
            );
206 8
            static::$standardTypes[$type->name] = $type;
207
        }
208 8
    }
209
210
    /**
211
     * @param Type $type
212
     *
213
     * @api
214
     */
215 412
    public static function isInputType($type) : bool
216
    {
217 412
        return self::getNamedType($type) instanceof InputType;
218
    }
219
220
    /**
221
     * @param Type $type
222
     *
223
     * @api
224
     */
225 668
    public static function getNamedType($type) : ?Type
226
    {
227 668
        if ($type === null) {
228 187
            return null;
229
        }
230 653
        while ($type instanceof WrappingType) {
231 325
            $type = $type->getWrappedType();
232
        }
233
234 653
        return $type;
235
    }
236
237
    /**
238
     * @param Type $type
239
     *
240
     * @api
241
     */
242 622
    public static function isOutputType($type) : bool
243
    {
244 622
        return self::getNamedType($type) instanceof OutputType;
245
    }
246
247
    /**
248
     * @param Type $type
249
     *
250
     * @return bool
251
     *
252
     * @api
253
     */
254 138
    public static function isLeafType($type)
255
    {
256 138
        return $type instanceof LeafType;
257
    }
258
259
    /**
260
     * @param Type $type
261
     *
262
     * @return bool
263
     *
264
     * @api
265
     */
266 534
    public static function isCompositeType($type)
267
    {
268 534
        return $type instanceof CompositeType;
269
    }
270
271
    /**
272
     * @param Type $type
273
     *
274
     * @api
275
     */
276 28
    public static function isAbstractType($type) : bool
277
    {
278 28
        return $type instanceof AbstractType;
279
    }
280
281
    /**
282
     * @param mixed $type
283
     *
284
     * @return mixed
285
     */
286
    public static function assertType($type)
287
    {
288
        Utils::invariant(
289
            self::isType($type),
290
            'Expected ' . Utils::printSafe($type) . ' to be a GraphQL type.'
291
        );
292
293
        return $type;
294
    }
295
296
    /**
297
     * @param Type $type
298
     *
299
     * @api
300
     */
301
    public static function isType($type) : bool
302
    {
303
        return $type instanceof Type;
304
    }
305
306
    /**
307
     * @api
308
     */
309 10
    public static function getNullableType(Type $type) : Type
310
    {
311 10
        return $type instanceof NonNull
312
            ? $type->getWrappedType()
313 10
            : $type;
314
    }
315
316
    /**
317
     * @throws InvariantViolation
318
     */
319 23
    public function assertValid()
320
    {
321 23
        Utils::assertValidName($this->name);
322 23
    }
323
324
    /**
325
     * @return string
326
     */
327 1
    public function jsonSerialize()
328
    {
329 1
        return $this->toString();
330
    }
331
332
    /**
333
     * @return string
334
     */
335 871
    public function toString()
336
    {
337 871
        return $this->name;
338
    }
339
340
    /**
341
     * @return string
342
     */
343 856
    public function __toString()
344
    {
345 856
        return $this->toString();
346
    }
347
348
    /**
349
     * @return string|null
350
     */
351 39
    protected function tryInferName()
352
    {
353 39
        if ($this->name) {
354 37
            return $this->name;
355
        }
356
357
        // If class is extended - infer name from className
358
        // QueryType -> Type
359
        // SomeOtherType -> SomeOther
360 2
        $tmp  = new ReflectionClass($this);
361 2
        $name = $tmp->getShortName();
362
363 2
        if ($tmp->getNamespaceName() !== __NAMESPACE__) {
364 1
            return preg_replace('~Type$~', '', $name);
365
        }
366
367 1
        return null;
368
    }
369
}
370