Passed
Push — master ( a27dd3...975c9f )
by Vladimir
11:24
created

Introspection   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 756
Duplicated Lines 0 %

Test Coverage

Coverage 49.83%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 50
eloc 431
dl 0
loc 756
ccs 149
cts 299
cp 0.4983
rs 8.4
c 1
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A isIntrospectionType() 0 3 1
A getIntrospectionQuery() 0 70 4
A _schema() 0 54 2
A getTypes() 0 11 1
A _enumValue() 0 40 2
A _field() 0 53 3
A _typeKind() 0 45 2
D _type() 0 149 20
A _inputValue() 0 54 4
A typeNameMetaFieldDef() 0 20 2
A typeMetaFieldDef() 0 17 2
A schemaMetaFieldDef() 0 20 2
A _directive() 0 44 3
B _directiveLocation() 0 88 2

How to fix   Complexity   

Complex Class

Complex classes like Introspection often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Introspection, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Type;
6
7
use Exception;
8
use GraphQL\Language\DirectiveLocation;
9
use GraphQL\Language\Printer;
10
use GraphQL\Type\Definition\Directive;
11
use GraphQL\Type\Definition\EnumType;
12
use GraphQL\Type\Definition\FieldArgument;
13
use GraphQL\Type\Definition\FieldDefinition;
14
use GraphQL\Type\Definition\InputObjectField;
15
use GraphQL\Type\Definition\InputObjectType;
16
use GraphQL\Type\Definition\InterfaceType;
17
use GraphQL\Type\Definition\ListOfType;
18
use GraphQL\Type\Definition\NonNull;
19
use GraphQL\Type\Definition\ObjectType;
20
use GraphQL\Type\Definition\ResolveInfo;
21
use GraphQL\Type\Definition\ScalarType;
22
use GraphQL\Type\Definition\Type;
23
use GraphQL\Type\Definition\UnionType;
24
use GraphQL\Type\Definition\WrappingType;
25
use GraphQL\Utils\AST;
26
use GraphQL\Utils\Utils;
27
use function array_filter;
28
use function array_key_exists;
29
use function array_values;
30
use function in_array;
31
use function is_bool;
32
use function method_exists;
33
use function trigger_error;
34
use const E_USER_DEPRECATED;
35
36
class Introspection
37
{
38
    const SCHEMA_FIELD_NAME    = '__schema';
39
    const TYPE_FIELD_NAME      = '__type';
40
    const TYPE_NAME_FIELD_NAME = '__typename';
41
42
    /** @var Type[] */
43
    private static $map = [];
44
45
    /**
46
     * Options:
47
     *   - descriptions
48
     *     Whether to include descriptions in the introspection result.
49
     *     Default: true
50
     *
51
     * @param bool[]|bool $options
52
     *
53
     * @return string
54
     */
55 5
    public static function getIntrospectionQuery($options = [])
56
    {
57 5
        if (is_bool($options)) {
58
            trigger_error(
59
                'Calling Introspection::getIntrospectionQuery(boolean) is deprecated. ' .
60
                'Please use Introspection::getIntrospectionQuery(["descriptions" => boolean]).',
61
                E_USER_DEPRECATED
62
            );
63
            $descriptions = $options;
64
        } else {
65 5
            $descriptions = ! array_key_exists('descriptions', $options) || $options['descriptions'] === true;
66
        }
67 5
        $descriptionField = $descriptions ? 'description' : '';
68
69
        return <<<EOD
70
  query IntrospectionQuery {
71
    __schema {
72
      queryType { name }
73
      mutationType { name }
74
      subscriptionType { name }
75
      types {
76
        ...FullType
77
      }
78
      directives {
79
        name
80 5
        {$descriptionField}
81
        locations
82
        args {
83
          ...InputValue
84
        }
85
      }
86
    }
87
  }
88
89
  fragment FullType on __Type {
90
    kind
91
    name
92 5
    {$descriptionField}
93
    fields(includeDeprecated: true) {
94
      name
95 5
      {$descriptionField}
96
      args {
97
        ...InputValue
98
      }
99
      type {
100
        ...TypeRef
101
      }
102
      isDeprecated
103
      deprecationReason
104
    }
105
    inputFields {
106
      ...InputValue
107
    }
108
    interfaces {
109
      ...TypeRef
110
    }
111
    enumValues(includeDeprecated: true) {
112
      name
113 5
      {$descriptionField}
114
      isDeprecated
115
      deprecationReason
116
    }
117
    possibleTypes {
118
      ...TypeRef
119
    }
120
  }
121
122
  fragment InputValue on __InputValue {
123
    name
124 5
    {$descriptionField}
125
    type { ...TypeRef }
126
    defaultValue
127
  }
128
129
  fragment TypeRef on __Type {
130
    kind
131
    name
132
    ofType {
133
      kind
134
      name
135
      ofType {
136
        kind
137
        name
138
        ofType {
139
          kind
140
          name
141
          ofType {
142
            kind
143
            name
144
            ofType {
145
              kind
146
              name
147
              ofType {
148
                kind
149
                name
150
                ofType {
151
                  kind
152
                  name
153
                }
154
              }
155
            }
156
          }
157
        }
158
      }
159
    }
160
  }
161
EOD;
162
    }
163
164
    /**
165
     * @param Type $type
166
     *
167
     * @return bool
168
     */
169 137
    public static function isIntrospectionType($type)
170
    {
171 137
        return array_key_exists($type->name, self::getTypes());
172
    }
173
174 871
    public static function getTypes()
175
    {
176
        return [
177 871
            '__Schema'            => self::_schema(),
178 871
            '__Type'              => self::_type(),
179 871
            '__Directive'         => self::_directive(),
180 871
            '__Field'             => self::_field(),
181 871
            '__InputValue'        => self::_inputValue(),
182 871
            '__EnumValue'         => self::_enumValue(),
183 871
            '__TypeKind'          => self::_typeKind(),
184 871
            '__DirectiveLocation' => self::_directiveLocation(),
185
        ];
186
    }
187
188 871
    public static function _schema()
189
    {
190 871
        if (! isset(self::$map['__Schema'])) {
191
            self::$map['__Schema'] = new ObjectType([
192
                'name'            => '__Schema',
193
                'isIntrospection' => true,
194
                'description'     =>
195
                    'A GraphQL Schema defines the capabilities of a GraphQL ' .
196
                    'server. It exposes all available types and directives on ' .
197
                    'the server, as well as the entry points for query, mutation, and ' .
198
                    'subscription operations.',
199
                'fields'          => [
200
                    'types'            => [
201
                        'description' => 'A list of all types supported by this server.',
202
                        'type'        => new NonNull(new ListOfType(new NonNull(self::_type()))),
0 ignored issues
show
Bug introduced by
self::_type() of type GraphQL\Type\Definition\Type is incompatible with the type GraphQL\Type\Definition\NullableType expected by parameter $type of GraphQL\Type\Definition\NonNull::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

202
                        'type'        => new NonNull(new ListOfType(new NonNull(/** @scrutinizer ignore-type */ self::_type()))),
Loading history...
203
                        'resolve'     => static function (Schema $schema) {
204 4
                            return array_values($schema->getTypeMap());
205
                        },
206
                    ],
207
                    'queryType'        => [
208
                        'description' => 'The type that query operations will be rooted at.',
209
                        'type'        => new NonNull(self::_type()),
210
                        'resolve'     => static function (Schema $schema) {
211 5
                            return $schema->getQueryType();
212
                        },
213
                    ],
214
                    'mutationType'     => [
215
                        'description' =>
216
                            'If this server supports mutation, the type that ' .
217
                            'mutation operations will be rooted at.',
218
                        'type'        => self::_type(),
219
                        'resolve'     => static function (Schema $schema) {
220 3
                            return $schema->getMutationType();
221
                        },
222
                    ],
223
                    'subscriptionType' => [
224
                        'description' => 'If this server support subscription, the type that subscription operations will be rooted at.',
225
                        'type'        => self::_type(),
226
                        'resolve'     => static function (Schema $schema) {
227 3
                            return $schema->getSubscriptionType();
228
                        },
229
                    ],
230
                    'directives'       => [
231
                        'description' => 'A list of all directives supported by this server.',
232
                        'type'        => Type::nonNull(Type::listOf(Type::nonNull(self::_directive()))),
0 ignored issues
show
Bug introduced by
self::_directive() of type GraphQL\Type\Definition\Type is incompatible with the type GraphQL\Type\Definition\NullableType expected by parameter $wrappedType of GraphQL\Type\Definition\Type::nonNull(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

232
                        'type'        => Type::nonNull(Type::listOf(Type::nonNull(/** @scrutinizer ignore-type */ self::_directive()))),
Loading history...
233
                        'resolve'     => static function (Schema $schema) {
234 3
                            return $schema->getDirectives();
235
                        },
236
                    ],
237
                ],
238
            ]);
239
        }
240
241 871
        return self::$map['__Schema'];
242
    }
243
244 871
    public static function _type()
245
    {
246 871
        if (! isset(self::$map['__Type'])) {
247
            self::$map['__Type'] = new ObjectType([
248
                'name'            => '__Type',
249
                'isIntrospection' => true,
250
                'description'     =>
251
                    'The fundamental unit of any GraphQL Schema is the type. There are ' .
252
                    'many kinds of types in GraphQL as represented by the `__TypeKind` enum.' .
253
                    "\n\n" .
254
                    'Depending on the kind of a type, certain fields describe ' .
255
                    'information about that type. Scalar types provide no information ' .
256
                    'beyond a name and description, while Enum types provide their values. ' .
257
                    'Object and Interface types provide the fields they describe. Abstract ' .
258
                    'types, Union and Interface, provide the Object types possible ' .
259
                    'at runtime. List and NonNull types compose other types.',
260
                'fields'          => static function () {
261
                    return [
262
                        'kind'          => [
263
                            'type'    => Type::nonNull(self::_typeKind()),
0 ignored issues
show
Bug introduced by
self::_typeKind() of type GraphQL\Type\Definition\Type is incompatible with the type GraphQL\Type\Definition\NullableType expected by parameter $wrappedType of GraphQL\Type\Definition\Type::nonNull(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

263
                            'type'    => Type::nonNull(/** @scrutinizer ignore-type */ self::_typeKind()),
Loading history...
264
                            'resolve' => static function (Type $type) {
265
                                switch (true) {
266 10
                                    case $type instanceof ListOfType:
267 6
                                        return TypeKind::LIST_KIND;
268 10
                                    case $type instanceof NonNull:
269 6
                                        return TypeKind::NON_NULL;
270 10
                                    case $type instanceof ScalarType:
271 7
                                        return TypeKind::SCALAR;
272 9
                                    case $type instanceof ObjectType:
273 4
                                        return TypeKind::OBJECT;
274 8
                                    case $type instanceof EnumType:
275 5
                                        return TypeKind::ENUM;
276 4
                                    case $type instanceof InputObjectType:
277 1
                                        return TypeKind::INPUT_OBJECT;
278 3
                                    case $type instanceof InterfaceType:
279 3
                                        return TypeKind::INTERFACE_KIND;
280 1
                                    case $type instanceof UnionType:
281 1
                                        return TypeKind::UNION;
282
                                    default:
283
                                        throw new Exception('Unknown kind of type: ' . Utils::printSafe($type));
284
                                }
285
                            },
286
                        ],
287
                        'name'          => [
288
                            'type' => Type::string(),
289
                            'resolve' => static function ($obj) {
290 21
                                return $obj->name;
291
                            },
292
                        ],
293
                        'description'   => [
294
                            'type' => Type::string(),
295
                            'resolve' => static function ($obj) {
296 5
                                return $obj->description;
297
                            },
298
                        ],
299
                        'fields'        => [
300
                            'type'    => Type::listOf(Type::nonNull(self::_field())),
301
                            'args'    => [
302
                                'includeDeprecated' => ['type' => Type::boolean(), 'defaultValue' => false],
303
                            ],
304
                            'resolve' => static function (Type $type, $args) {
305 10
                                if ($type instanceof ObjectType || $type instanceof InterfaceType) {
306 10
                                    $fields = $type->getFields();
307
308 10
                                    if (empty($args['includeDeprecated'])) {
309 6
                                        $fields = array_filter(
310 6
                                            $fields,
311
                                            static function (FieldDefinition $field) {
312 6
                                                return ! $field->deprecationReason;
313 6
                                            }
314
                                        );
315
                                    }
316
317 10
                                    return array_values($fields);
318
                                }
319
320 4
                                return null;
321
                            },
322
                        ],
323
                        'interfaces'    => [
324
                            'type'    => Type::listOf(Type::nonNull(self::_type())),
325
                            'resolve' => static function ($type) {
326 4
                                if ($type instanceof ObjectType) {
327 3
                                    return $type->getInterfaces();
328
                                }
329
330 4
                                return null;
331
                            },
332
                        ],
333
                        'possibleTypes' => [
334
                            'type'    => Type::listOf(Type::nonNull(self::_type())),
335
                            'resolve' => static function ($type, $args, $context, ResolveInfo $info) {
336 4
                                if ($type instanceof InterfaceType || $type instanceof UnionType) {
337 1
                                    return $info->schema->getPossibleTypes($type);
338
                                }
339
340 3
                                return null;
341
                            },
342
                        ],
343
                        'enumValues'    => [
344
                            'type'    => Type::listOf(Type::nonNull(self::_enumValue())),
345
                            'args'    => [
346
                                'includeDeprecated' => ['type' => Type::boolean(), 'defaultValue' => false],
347
                            ],
348
                            'resolve' => static function ($type, $args) {
349 7
                                if ($type instanceof EnumType) {
350 6
                                    $values = array_values($type->getValues());
351
352 6
                                    if (empty($args['includeDeprecated'])) {
353 2
                                        $values = array_filter(
354 2
                                            $values,
355
                                            static function ($value) {
356 2
                                                return ! $value->deprecationReason;
357 2
                                            }
358
                                        );
359
                                    }
360
361 6
                                    return $values;
362
                                }
363
364 4
                                return null;
365
                            },
366
                        ],
367
                        'inputFields'   => [
368
                            'type'    => Type::listOf(Type::nonNull(self::_inputValue())),
369
                            'resolve' => static function ($type) {
370 5
                                if ($type instanceof InputObjectType) {
371 1
                                    return array_values($type->getFields());
372
                                }
373
374 4
                                return null;
375
                            },
376
                        ],
377
                        'ofType'        => [
378
                            'type'    => self::_type(),
379
                            'resolve' => static function ($type) {
380 6
                                if ($type instanceof WrappingType) {
381 6
                                    return $type->getWrappedType();
382
                                }
383
384 6
                                return null;
385
                            },
386
                        ],
387
                    ];
388
                },
389
            ]);
390
        }
391
392 871
        return self::$map['__Type'];
393
    }
394
395 871
    public static function _typeKind()
396
    {
397 871
        if (! isset(self::$map['__TypeKind'])) {
398
            self::$map['__TypeKind'] = new EnumType([
399
                'name'            => '__TypeKind',
400
                'isIntrospection' => true,
401
                'description'     => 'An enum describing what kind of type a given `__Type` is.',
402
                'values'          => [
403
                    'SCALAR'       => [
404
                        'value'       => TypeKind::SCALAR,
405
                        'description' => 'Indicates this type is a scalar.',
406
                    ],
407
                    'OBJECT'       => [
408
                        'value'       => TypeKind::OBJECT,
409
                        'description' => 'Indicates this type is an object. `fields` and `interfaces` are valid fields.',
410
                    ],
411
                    'INTERFACE'    => [
412
                        'value'       => TypeKind::INTERFACE_KIND,
413
                        'description' => 'Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.',
414
                    ],
415
                    'UNION'        => [
416
                        'value'       => TypeKind::UNION,
417
                        'description' => 'Indicates this type is a union. `possibleTypes` is a valid field.',
418
                    ],
419
                    'ENUM'         => [
420
                        'value'       => TypeKind::ENUM,
421
                        'description' => 'Indicates this type is an enum. `enumValues` is a valid field.',
422
                    ],
423
                    'INPUT_OBJECT' => [
424
                        'value'       => TypeKind::INPUT_OBJECT,
425
                        'description' => 'Indicates this type is an input object. `inputFields` is a valid field.',
426
                    ],
427
                    'LIST'         => [
428
                        'value'       => TypeKind::LIST_KIND,
429
                        'description' => 'Indicates this type is a list. `ofType` is a valid field.',
430
                    ],
431
                    'NON_NULL'     => [
432
                        'value'       => TypeKind::NON_NULL,
433
                        'description' => 'Indicates this type is a non-null. `ofType` is a valid field.',
434
                    ],
435
                ],
436
            ]);
437
        }
438
439 871
        return self::$map['__TypeKind'];
440
    }
441
442 871
    public static function _field()
443
    {
444 871
        if (! isset(self::$map['__Field'])) {
445
            self::$map['__Field'] = new ObjectType([
446
                'name'            => '__Field',
447
                'isIntrospection' => true,
448
                'description'     =>
449
                    'Object and Interface types are described by a list of Fields, each of ' .
450
                    'which has a name, potentially a list of arguments, and a return type.',
451
                'fields'          => static function () {
452
                    return [
453
                        'name'              => [
454
                            'type' => Type::nonNull(Type::string()),
455
                            'resolve' => static function (FieldDefinition $field) {
456 10
                                return $field->name;
457
                            },
458
                        ],
459
                        'description'       => [
460
                            'type' => Type::string(),
461
                            'resolve' => static function (FieldDefinition $field) {
462 3
                                return $field->description;
463
                            },
464
                        ],
465
                        'args'              => [
466
                            'type'    => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))),
0 ignored issues
show
Bug introduced by
self::_inputValue() of type GraphQL\Type\Definition\Type is incompatible with the type GraphQL\Type\Definition\NullableType expected by parameter $wrappedType of GraphQL\Type\Definition\Type::nonNull(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

466
                            'type'    => Type::nonNull(Type::listOf(Type::nonNull(/** @scrutinizer ignore-type */ self::_inputValue()))),
Loading history...
467
                            'resolve' => static function (FieldDefinition $field) {
468 4
                                return empty($field->args) ? [] : $field->args;
469
                            },
470
                        ],
471
                        'type'              => [
472
                            'type'    => Type::nonNull(self::_type()),
473
                            'resolve' => static function (FieldDefinition $field) {
474 5
                                return $field->getType();
475
                            },
476
                        ],
477
                        'isDeprecated'      => [
478
                            'type'    => Type::nonNull(Type::boolean()),
479
                            'resolve' => static function (FieldDefinition $field) {
480 4
                                return (bool) $field->deprecationReason;
481
                            },
482
                        ],
483
                        'deprecationReason' => [
484
                            'type'    => Type::string(),
485
                            'resolve' => static function (FieldDefinition $field) {
486 4
                                return $field->deprecationReason;
487
                            },
488
                        ],
489
                    ];
490
                },
491
            ]);
492
        }
493
494 871
        return self::$map['__Field'];
495
    }
496
497 871
    public static function _inputValue()
498
    {
499 871
        if (! isset(self::$map['__InputValue'])) {
500
            self::$map['__InputValue'] = new ObjectType([
501
                'name'            => '__InputValue',
502
                'isIntrospection' => true,
503
                'description'     =>
504
                    'Arguments provided to Fields or Directives and the input fields of an ' .
505
                    'InputObject are represented as Input Values which describe their type ' .
506
                    'and optionally a default value.',
507
                'fields'          => static function () {
508
                    return [
509
                        'name'         => [
510
                            'type' => Type::nonNull(Type::string()),
511
                            'resolve' => static function ($inputValue) {
512
                                /** @var FieldArgument|InputObjectField $inputValue */
513 5
                                return $inputValue->name;
514
                            },
515
                        ],
516
                        'description'  => [
517
                            'type' => Type::string(),
518
                            'resolve' => static function ($inputValue) {
519
                                /** @var FieldArgument|InputObjectField $inputValue */
520 3
                                return $inputValue->description;
521
                            },
522
                        ],
523
                        'type'         => [
524
                            'type'    => Type::nonNull(self::_type()),
0 ignored issues
show
Bug introduced by
self::_type() of type GraphQL\Type\Definition\Type is incompatible with the type GraphQL\Type\Definition\NullableType expected by parameter $wrappedType of GraphQL\Type\Definition\Type::nonNull(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

524
                            'type'    => Type::nonNull(/** @scrutinizer ignore-type */ self::_type()),
Loading history...
525
                            'resolve' => static function ($value) {
526 5
                                return method_exists($value, 'getType')
527 5
                                    ? $value->getType()
528 5
                                    : $value->type;
529
                            },
530
                        ],
531
                        'defaultValue' => [
532
                            'type'        => Type::string(),
533
                            'description' =>
534
                                'A GraphQL-formatted string representing the default value for this input value.',
535
                            'resolve'     => static function ($inputValue) {
536
                                /** @var FieldArgument|InputObjectField $inputValue */
537 5
                                return ! $inputValue->defaultValueExists()
538 5
                                    ? null
539 4
                                    : Printer::doPrint(AST::astFromValue(
540 4
                                        $inputValue->defaultValue,
541 5
                                        $inputValue->getType()
542
                                    ));
543
                            },
544
                        ],
545
                    ];
546
                },
547
            ]);
548
        }
549
550 871
        return self::$map['__InputValue'];
551
    }
552
553 871
    public static function _enumValue()
554
    {
555 871
        if (! isset(self::$map['__EnumValue'])) {
556
            self::$map['__EnumValue'] = new ObjectType([
557
                'name'            => '__EnumValue',
558
                'isIntrospection' => true,
559
                'description'     =>
560
                    'One possible value for a given Enum. Enum values are unique values, not ' .
561
                    'a placeholder for a string or numeric value. However an Enum value is ' .
562
                    'returned in a JSON response as a string.',
563
                'fields'          => [
564
                    'name'              => [
565
                        'type' => Type::nonNull(Type::string()),
566
                        'resolve' => static function ($enumValue) {
567 6
                            return $enumValue->name;
568
                        },
569
                    ],
570
                    'description'       => [
571
                        'type' => Type::string(),
572
                        'resolve' => static function ($enumValue) {
573 3
                            return $enumValue->description;
574
                        },
575
                    ],
576
                    'isDeprecated'      => [
577
                        'type'    => Type::nonNull(Type::boolean()),
578
                        'resolve' => static function ($enumValue) {
579 4
                            return (bool) $enumValue->deprecationReason;
580
                        },
581
                    ],
582
                    'deprecationReason' => [
583
                        'type' => Type::string(),
584
                        'resolve' => static function ($enumValue) {
585 4
                            return $enumValue->deprecationReason;
586
                        },
587
                    ],
588
                ],
589
            ]);
590
        }
591
592 871
        return self::$map['__EnumValue'];
593
    }
594
595 871
    public static function _directive()
596
    {
597 871
        if (! isset(self::$map['__Directive'])) {
598
            self::$map['__Directive'] = new ObjectType([
599
                'name'            => '__Directive',
600
                'isIntrospection' => true,
601
                'description'     => 'A Directive provides a way to describe alternate runtime execution and ' .
602
                    'type validation behavior in a GraphQL document.' .
603
                    "\n\nIn some cases, you need to provide options to alter GraphQL's " .
604
                    'execution behavior in ways field arguments will not suffice, such as ' .
605
                    'conditionally including or skipping a field. Directives provide this by ' .
606
                    'describing additional information to the executor.',
607
                'fields'          => [
608
                    'name'        => [
609
                        'type'    => Type::nonNull(Type::string()),
610
                        'resolve' => static function ($obj) {
611 3
                            return $obj->name;
612
                        },
613
                    ],
614
                    'description' => [
615
                        'type' => Type::string(),
616
                        'resolve' => static function ($obj) {
617 2
                            return $obj->description;
618
                        },
619
                    ],
620
                    'locations'   => [
621
                        'type' => Type::nonNull(Type::listOf(Type::nonNull(
622
                            self::_directiveLocation()
0 ignored issues
show
Bug introduced by
self::_directiveLocation() of type GraphQL\Type\Definition\Type is incompatible with the type GraphQL\Type\Definition\NullableType expected by parameter $wrappedType of GraphQL\Type\Definition\Type::nonNull(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

622
                            /** @scrutinizer ignore-type */ self::_directiveLocation()
Loading history...
623
                        ))),
624
                        'resolve' => static function ($obj) {
625 3
                            return $obj->locations;
626
                        },
627
                    ],
628
                    'args'        => [
629
                        'type'    => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))),
630
                        'resolve' => static function (Directive $directive) {
631 3
                            return $directive->args ?: [];
632
                        },
633
                    ],
634
                ],
635
            ]);
636
        }
637
638 871
        return self::$map['__Directive'];
639
    }
640
641 871
    public static function _directiveLocation()
642
    {
643 871
        if (! isset(self::$map['__DirectiveLocation'])) {
644
            self::$map['__DirectiveLocation'] = new EnumType([
645
                'name'            => '__DirectiveLocation',
646
                'isIntrospection' => true,
647
                'description'     =>
648
                    'A Directive can be adjacent to many parts of the GraphQL language, a ' .
649
                    '__DirectiveLocation describes one such possible adjacencies.',
650
                'values'          => [
651
                    'QUERY'                  => [
652
                        'value'       => DirectiveLocation::QUERY,
653
                        'description' => 'Location adjacent to a query operation.',
654
                    ],
655
                    'MUTATION'               => [
656
                        'value'       => DirectiveLocation::MUTATION,
657
                        'description' => 'Location adjacent to a mutation operation.',
658
                    ],
659
                    'SUBSCRIPTION'           => [
660
                        'value'       => DirectiveLocation::SUBSCRIPTION,
661
                        'description' => 'Location adjacent to a subscription operation.',
662
                    ],
663
                    'FIELD'                  => [
664
                        'value'       => DirectiveLocation::FIELD,
665
                        'description' => 'Location adjacent to a field.',
666
                    ],
667
                    'FRAGMENT_DEFINITION'    => [
668
                        'value'       => DirectiveLocation::FRAGMENT_DEFINITION,
669
                        'description' => 'Location adjacent to a fragment definition.',
670
                    ],
671
                    'FRAGMENT_SPREAD'        => [
672
                        'value'       => DirectiveLocation::FRAGMENT_SPREAD,
673
                        'description' => 'Location adjacent to a fragment spread.',
674
                    ],
675
                    'INLINE_FRAGMENT'        => [
676
                        'value'       => DirectiveLocation::INLINE_FRAGMENT,
677
                        'description' => 'Location adjacent to an inline fragment.',
678
                    ],
679
                    'SCHEMA'                 => [
680
                        'value'       => DirectiveLocation::SCHEMA,
681
                        'description' => 'Location adjacent to a schema definition.',
682
                    ],
683
                    'SCALAR'                 => [
684
                        'value'       => DirectiveLocation::SCALAR,
685
                        'description' => 'Location adjacent to a scalar definition.',
686
                    ],
687
                    'OBJECT'                 => [
688
                        'value'       => DirectiveLocation::OBJECT,
689
                        'description' => 'Location adjacent to an object type definition.',
690
                    ],
691
                    'FIELD_DEFINITION'       => [
692
                        'value'       => DirectiveLocation::FIELD_DEFINITION,
693
                        'description' => 'Location adjacent to a field definition.',
694
                    ],
695
                    'ARGUMENT_DEFINITION'    => [
696
                        'value'       => DirectiveLocation::ARGUMENT_DEFINITION,
697
                        'description' => 'Location adjacent to an argument definition.',
698
                    ],
699
                    'INTERFACE'              => [
700
                        'value'       => DirectiveLocation::IFACE,
701
                        'description' => 'Location adjacent to an interface definition.',
702
                    ],
703
                    'UNION'                  => [
704
                        'value'       => DirectiveLocation::UNION,
705
                        'description' => 'Location adjacent to a union definition.',
706
                    ],
707
                    'ENUM'                   => [
708
                        'value'       => DirectiveLocation::ENUM,
709
                        'description' => 'Location adjacent to an enum definition.',
710
                    ],
711
                    'ENUM_VALUE'             => [
712
                        'value'       => DirectiveLocation::ENUM_VALUE,
713
                        'description' => 'Location adjacent to an enum value definition.',
714
                    ],
715
                    'INPUT_OBJECT'           => [
716
                        'value'       => DirectiveLocation::INPUT_OBJECT,
717
                        'description' => 'Location adjacent to an input object type definition.',
718
                    ],
719
                    'INPUT_FIELD_DEFINITION' => [
720
                        'value'       => DirectiveLocation::INPUT_FIELD_DEFINITION,
721
                        'description' => 'Location adjacent to an input object field definition.',
722
                    ],
723
724
                ],
725
            ]);
726
        }
727
728 871
        return self::$map['__DirectiveLocation'];
729
    }
730
731 470
    public static function schemaMetaFieldDef() : FieldDefinition
732
    {
733 470
        if (! isset(self::$map[self::SCHEMA_FIELD_NAME])) {
734 1
            self::$map[self::SCHEMA_FIELD_NAME] = FieldDefinition::create([
735 1
                'name'        => self::SCHEMA_FIELD_NAME,
736 1
                'type'        => Type::nonNull(self::_schema()),
0 ignored issues
show
Bug introduced by
self::_schema() of type GraphQL\Type\Definition\Type is incompatible with the type GraphQL\Type\Definition\NullableType expected by parameter $wrappedType of GraphQL\Type\Definition\Type::nonNull(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

736
                'type'        => Type::nonNull(/** @scrutinizer ignore-type */ self::_schema()),
Loading history...
737 1
                'description' => 'Access the current type schema of this server.',
738
                'args'        => [],
739
                'resolve'     => static function (
740
                    $source,
741
                    $args,
742
                    $context,
743
                    ResolveInfo $info
744
                ) {
745 6
                    return $info->schema;
746 1
                },
747
            ]);
748
        }
749
750 470
        return self::$map[self::SCHEMA_FIELD_NAME];
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::map[self::SCHEMA_FIELD_NAME] returns the type GraphQL\Type\Definition\Type which is incompatible with the type-hinted return GraphQL\Type\Definition\FieldDefinition.
Loading history...
751
    }
752
753 471
    public static function typeMetaFieldDef() : FieldDefinition
754
    {
755 471
        if (! isset(self::$map[self::TYPE_FIELD_NAME])) {
756 1
            self::$map[self::TYPE_FIELD_NAME] = FieldDefinition::create([
757 1
                'name'        => self::TYPE_FIELD_NAME,
758 1
                'type'        => self::_type(),
759 1
                'description' => 'Request the type information of a single type.',
760
                'args'        => [
761 1
                    ['name' => 'name', 'type' => Type::nonNull(Type::string())],
762
                ],
763
                'resolve'     => static function ($source, $args, $context, ResolveInfo $info) {
764 15
                    return $info->schema->getType($args['name']);
765 1
                },
766
            ]);
767
        }
768
769 471
        return self::$map[self::TYPE_FIELD_NAME];
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::map[self::TYPE_FIELD_NAME] returns the type GraphQL\Type\Definition\Type which is incompatible with the type-hinted return GraphQL\Type\Definition\FieldDefinition.
Loading history...
770
    }
771
772 475
    public static function typeNameMetaFieldDef() : FieldDefinition
773
    {
774 475
        if (! isset(self::$map[self::TYPE_NAME_FIELD_NAME])) {
775 1
            self::$map[self::TYPE_NAME_FIELD_NAME] = FieldDefinition::create([
776 1
                'name'        => self::TYPE_NAME_FIELD_NAME,
777 1
                'type'        => Type::nonNull(Type::string()),
778 1
                'description' => 'The name of the current Object type at runtime.',
779
                'args'        => [],
780
                'resolve'     => static function (
781
                    $source,
782
                    $args,
783
                    $context,
784
                    ResolveInfo $info
785
                ) {
786 7
                    return $info->parentType->name;
787 1
                },
788
            ]);
789
        }
790
791 475
        return self::$map[self::TYPE_NAME_FIELD_NAME];
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::map[self::TYPE_NAME_FIELD_NAME] returns the type GraphQL\Type\Definition\Type which is incompatible with the type-hinted return GraphQL\Type\Definition\FieldDefinition.
Loading history...
792
    }
793
}
794