Completed
Push — master ( 9e4cdb...1641ea )
by Alexandr
02:44
created

Processor   F

Complexity

Total Complexity 98

Size/Duplication

Total Lines 499
Duplicated Lines 7.21 %

Coupling/Cohesion

Components 1
Dependencies 30

Test Coverage

Coverage 92.81%

Importance

Changes 4
Bugs 1 Features 1
Metric Value
wmc 98
lcom 1
cbo 30
dl 36
loc 499
ccs 258
cts 278
cp 0.9281
rs 1.3043
c 4
b 1
f 1

21 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
A getResponseData() 0 14 3
A getExecutionContext() 0 4 1
A getMaxComplexity() 0 4 1
A setMaxComplexity() 0 4 1
A resolveQuery() 0 14 3
C resolveField() 13 59 14
A prepareAstArguments() 0 10 3
A resolveScalar() 0 11 1
A parseAndCreateRequest() 0 13 2
A doResolve() 0 8 2
A getAlias() 0 4 2
A createResolveInfo() 0 4 1
B processPayload() 0 27 6
D prepareArgumentValue() 0 48 16
B getVariableReferenceArgumentValue() 0 20 8
B resolveObject() 0 22 4
C collectResult() 23 56 10
C resolveList() 0 65 10
B resolveComposite() 0 28 3
B parseArgumentsValues() 0 25 5

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Processor 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 Processor, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Date: 03.11.16
4
 *
5
 * @author Portey Vasil <[email protected]>
6
 */
7
8
namespace Youshido\GraphQL\Execution;
9
10
11
use Youshido\GraphQL\Exception\ResolveException;
12
use Youshido\GraphQL\Execution\Container\Container;
13
use Youshido\GraphQL\Execution\Context\ExecutionContext;
14
use Youshido\GraphQL\Execution\Visitor\MaxComplexityQueryVisitor;
15
use Youshido\GraphQL\Field\Field;
16
use Youshido\GraphQL\Field\FieldInterface;
17
use Youshido\GraphQL\Field\InputField;
18
use Youshido\GraphQL\Parser\Ast\ArgumentValue\InputList as AstInputList;
19
use Youshido\GraphQL\Parser\Ast\ArgumentValue\InputObject as AstInputObject;
20
use Youshido\GraphQL\Parser\Ast\ArgumentValue\Literal as AstLiteral;
21
use Youshido\GraphQL\Parser\Ast\ArgumentValue\VariableReference;
22
use Youshido\GraphQL\Parser\Ast\Field as AstField;
23
use Youshido\GraphQL\Parser\Ast\FragmentReference;
24
use Youshido\GraphQL\Parser\Ast\Interfaces\FieldInterface as AstFieldInterface;
25
use Youshido\GraphQL\Parser\Ast\Mutation as AstMutation;
26
use Youshido\GraphQL\Parser\Ast\Query as AstQuery;
27
use Youshido\GraphQL\Parser\Ast\TypedFragmentReference;
28
use Youshido\GraphQL\Parser\Parser;
29
use Youshido\GraphQL\Schema\AbstractSchema;
30
use Youshido\GraphQL\Type\AbstractType;
31
use Youshido\GraphQL\Type\InputObject\AbstractInputObjectType;
32
use Youshido\GraphQL\Type\InterfaceType\AbstractInterfaceType;
33
use Youshido\GraphQL\Type\ListType\AbstractListType;
34
use Youshido\GraphQL\Type\Object\AbstractObjectType;
35
use Youshido\GraphQL\Type\Scalar\AbstractScalarType;
36
use Youshido\GraphQL\Type\TypeMap;
37
use Youshido\GraphQL\Type\Union\AbstractUnionType;
38
use Youshido\GraphQL\Validator\RequestValidator\RequestValidator;
39
use Youshido\GraphQL\Validator\ResolveValidator\ResolveValidator;
40
use Youshido\GraphQL\Validator\ResolveValidator\ResolveValidatorInterface;
41
42
class Processor
43
{
44
45
    const TYPE_NAME_QUERY = '__typename';
46
47
    /** @var ExecutionContext */
48
    protected $executionContext;
49
50
    /** @var ResolveValidatorInterface */
51
    protected $resolveValidator;
52
53
    /** @var  array */
54
    protected $data;
55
56
    /** @var int */
57
    protected $maxComplexity;
58
59 41
    public function __construct(AbstractSchema $schema)
60
    {
61 41
        if (empty($this->executionContext)) {
62 41
            $this->executionContext = new ExecutionContext($schema);
63 41
            $this->executionContext->setContainer(new Container());
64 41
        }
65
66 41
        $this->resolveValidator = new ResolveValidator($this->executionContext);
0 ignored issues
show
Unused Code introduced by
The call to ResolveValidator::__construct() has too many arguments starting with $this->executionContext.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
67 41
    }
68
69 39
    public function processPayload($payload, $variables = [], $reducers = [])
70
    {
71 39
        $this->data = [];
72
73
        try {
74 39
            $this->parseAndCreateRequest($payload, $variables);
75
76 38
            if ($this->maxComplexity) {
77 1
                $reducers[] = new MaxComplexityQueryVisitor($this->maxComplexity);
78 1
            }
79
80 38
            if ($reducers) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $reducers of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
81 2
                $reducer = new Reducer();
82 2
                $reducer->reduceQuery($this->executionContext, $reducers);
83 2
            }
84
85 38
            foreach ($this->executionContext->getRequest()->getAllOperations() as $query) {
86 38
                if ($operationResult = $this->resolveQuery($query)) {
87 38
                    $this->data = array_merge($this->data, $operationResult);
88 38
                };
89 38
            }
90 39
        } catch (\Exception $e) {
91 5
            $this->executionContext->addError($e);
92
        }
93
94 39
        return $this;
95
    }
96
97 39
    public function getResponseData()
98
    {
99 39
        $result = [];
100
101 39
        if (!empty($this->data)) {
102 38
            $result['data'] = $this->data;
103 38
        }
104
105 39
        if ($this->executionContext->hasErrors()) {
106 15
            $result['errors'] = $this->executionContext->getErrorsArray();
107 15
        }
108
109 39
        return $result;
110
    }
111
112
    /**
113
     * You can access ExecutionContext to check errors and inject dependencies
114
     *
115
     * @return ExecutionContext
116
     */
117 10
    public function getExecutionContext()
118
    {
119 10
        return $this->executionContext;
120
    }
121
122
    /**
123
     * @return int
124
     */
125
    public function getMaxComplexity()
126
    {
127
        return $this->maxComplexity;
128
    }
129
130
    /**
131
     * @param int $maxComplexity
132
     */
133 1
    public function setMaxComplexity($maxComplexity)
134
    {
135 1
        $this->maxComplexity = $maxComplexity;
136 1
    }
137
138 38
    protected function resolveQuery(AstQuery $query)
139
    {
140 38
        $schema = $this->executionContext->getSchema();
141 38
        $type   = $query instanceof AstMutation ? $schema->getMutationType() : $schema->getQueryType();
142 38
        $field  = new Field([
143 38
            'name' => $query instanceof AstMutation ? 'mutation' : 'query',
144
            'type' => $type
145 38
        ]);
146
147 38
        $this->resolveValidator->assetTypeHasField($type, $query);
148 38
        $value = $this->resolveField($field, $query);
149
150 38
        return [$this->getAlias($query) => $value];
151
    }
152
153 38
    protected function resolveField(FieldInterface $field, AstFieldInterface $ast, $parentValue = null, $fromObject = false)
154
    {
155
        try {
156
            /** @var AbstractObjectType $type */
157 38
            $type        = $field->getType();
158 38
            $nonNullType = $type->getNullableType();
159
160 38
            if (self::TYPE_NAME_QUERY == $ast->getName()) {
161 2
                return $nonNullType->getName();
162
            }
163
164 38
            $this->resolveValidator->assetTypeHasField($nonNullType, $ast);
165
166 38
            $targetField = $nonNullType->getField($ast->getName());
167
168 38
            $this->prepareAstArguments($targetField, $ast, $this->executionContext->getRequest());
169 37
            $this->resolveValidator->assertValidArguments($targetField, $ast, $this->executionContext->getRequest());
170
171 35
            switch ($kind = $targetField->getType()->getNullableType()->getKind()) {
172 35
                case TypeMap::KIND_ENUM:
173 35
                case TypeMap::KIND_SCALAR:
174 29
                    if ($ast instanceof AstQuery && $ast->hasFields()) {
175 2
                        throw new ResolveException(sprintf('You can\'t specify fields for scalar type "%s"', $targetField->getType()->getNullableType()->getName()), $ast->getLocation());
176
                    }
177
178 29
                    return $this->resolveScalar($targetField, $ast, $parentValue);
179
180 28 View Code Duplication
                case TypeMap::KIND_OBJECT:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
181
                    /** @var $type AbstractObjectType */
182 20
                    if (!$ast instanceof AstQuery) {
183 1
                        throw new ResolveException(sprintf('You have to specify fields for "%s"', $ast->getName()), $ast->getLocation());
184
                    }
185
186 20
                    return $this->resolveObject($targetField, $ast, $parentValue);
187
188 17
                case TypeMap::KIND_LIST:
189 14
                    return $this->resolveList($targetField, $ast, $parentValue);
190
191 6
                case TypeMap::KIND_UNION:
192 6 View Code Duplication
                case TypeMap::KIND_INTERFACE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
193 6
                    if (!$ast instanceof AstQuery) {
194
                        throw new ResolveException(sprintf('You have to specify fields for "%s"', $ast->getName()), $ast->getLocation());
195
                    }
196
197 6
                    return $this->resolveComposite($targetField, $ast, $parentValue);
198
199
                default:
200
                    throw new ResolveException(sprintf('Resolving type with kind "%s" not supported', $kind));
201
            }
202 12
        } catch (\Exception $e) {
203 12
            $this->executionContext->addError($e);
204
205 12
            if ($fromObject) {
206 4
                throw $e;
207
            }
208
209 10
            return null;
210
        }
211
    }
212
213 38
    private function prepareAstArguments(FieldInterface $field, AstFieldInterface $query, Request $request)
214
    {
215 38
        foreach ($query->getArguments() as $astArgument) {
216 17
            if ($field->hasArgument($astArgument->getName())) {
217 17
                $argumentType = $field->getArgument($astArgument->getName())->getType()->getNullableType();
218
219 17
                $astArgument->setValue($this->prepareArgumentValue($astArgument->getValue(), $argumentType, $request));
220 16
            }
221 37
        }
222 37
    }
223
224 17
    private function prepareArgumentValue($argumentValue, AbstractType $argumentType, Request $request)
225
    {
226 17
        switch ($argumentType->getKind()) {
227 17
            case TypeMap::KIND_LIST:
228
                /** @var $argumentType AbstractListType */
229 2
                $result = [];
230 2
                if ($argumentValue instanceof AstInputList || is_array($argumentValue)) {
231 2
                    $list = is_array($argumentValue) ? $argumentValue : $argumentValue->getValue();
232 2
                    foreach ($list as $item) {
233 2
                        $result[] = $this->prepareArgumentValue($item, $argumentType->getItemType()->getNullableType(), $request);
234 2
                    }
235 2
                } else if ($argumentValue instanceof VariableReference) {
236
                    return $this->getVariableReferenceArgumentValue($argumentValue, $argumentType, $request);
237
                }
238
239 2
                return $result;
240
241 17
            case TypeMap::KIND_INPUT_OBJECT:
242
                /** @var $argumentType AbstractInputObjectType */
243 2
                $result = [];
244 2
                if ($argumentValue instanceof AstInputObject) {
245 2
                    foreach ($argumentValue->getValue() as $key => $item) {
246 2
                        if ($argumentType->hasField($key)) {
247 2
                            $result[$key] = $this->prepareArgumentValue($item, $argumentType->getField($key)->getType()->getNullableType(), $request);
248 2
                        } else {
249
                            $result[$key] = $item;
250
                        }
251 2
                    }
252 2
                } else if ($argumentValue instanceof VariableReference) {
253
                    return $this->getVariableReferenceArgumentValue($argumentValue, $argumentType, $request);
254
                }
255
256 2
                return $result;
257
258 17
            case TypeMap::KIND_SCALAR:
259 17
            case TypeMap::KIND_ENUM:
260
                /** @var $argumentValue AstLiteral|VariableReference */
261 17
                if ($argumentValue instanceof VariableReference) {
262 4
                    return $this->getVariableReferenceArgumentValue($argumentValue, $argumentType, $request);
263 14
                } else if ($argumentValue instanceof AstLiteral) {
264 12
                    return $argumentValue->getValue();
265
                } else {
266 3
                    return $argumentValue;
267
                }
268
        }
269
270
        throw new ResolveException('Argument type not supported');
271
    }
272
273 4
    private function getVariableReferenceArgumentValue(VariableReference $variableReference, AbstractType $argumentType, Request $request)
274
    {
275 4
        $variable = $variableReference->getVariable();
276 4
        if ($argumentType->getKind() == TypeMap::KIND_LIST) {
277
            if ($variable->getTypeName() != $argumentType->getNamedType()->getName() || !$variable->isArray()) {
278
                throw new ResolveException(sprintf('Invalid variable "%s" type, allowed type is "%s"', $variable->getName(), $argumentType->getName()), $variable->getLocation());
279
            }
280
        } else {
281 4
            if ($variable->getTypeName() != $argumentType->getName()) {
282 1
                throw new ResolveException(sprintf('Invalid variable "%s" type, allowed type is "%s"', $variable->getName(), $argumentType->getName()), $variable->getLocation());
283
            }
284
        }
285
286 3
        $requestValue = $request->getVariable($variable->getName());
287 3
        if (!$request->hasVariable($variable->getName()) || (null === $requestValue && $variable->isNullable())) {
288
            throw  new ResolveException(sprintf('Variable "%s" does not exist in request', $variable->getName()), $variable->getLocation());
289
        }
290
291 3
        return $requestValue;
292
    }
293
294 25
    protected function resolveObject(FieldInterface $field, AstFieldInterface $ast, $parentValue, $fromUnion = false)
295
    {
296 25
        if (!$fromUnion) {
297 20
            $resolvedValue = $this->doResolve($field, $ast, $parentValue);
298 20
        } else {
299 7
            $resolvedValue = $parentValue;
300
        }
301
302 25
        $this->resolveValidator->assertValidResolvedValueForField($field, $resolvedValue);
303
304 25
        if (null === $resolvedValue) {
305 5
            return null;
306
        }
307
        /** @var AbstractObjectType $type */
308 24
        $type = $field->getType()->getNullableType();
309
310
        try {
311 24
            return $this->collectResult($field, $type, $ast, $resolvedValue);
312 4
        } catch (\Exception $e) {
313 4
            return null;
314
        }
315
    }
316
317 24
    private function collectResult(FieldInterface $field, AbstractObjectType $type, $ast, $resolvedValue)
318
    {
319
        /** @var AstQuery $ast */
320 24
        $result = [];
321
322 24
        foreach ($ast->getFields() as $astField) {
323 24
            switch (true) {
324 24
                case $astField instanceof TypedFragmentReference:
325 2
                    $astName  = $astField->getTypeName();
326 2
                    $typeName = $type->getName();
327
328 2 View Code Duplication
                    if ($typeName !== $astName) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
329 2
                        foreach ($type->getInterfaces() as $interface) {
330 1
                            if ($interface->getName() === $astName) {
331
                                $result = array_merge($result, $this->collectResult($field, $type, $astField, $resolvedValue));
332
333
                                break;
334
                            }
335 2
                        }
336
337 2
                        continue;
338
                    }
339
340 2
                    $result = array_merge($result, $this->collectResult($field, $type, $astField, $resolvedValue));
341
342 2
                    break;
343
344 24
                case $astField instanceof FragmentReference:
345 3
                    $astFragment      = $this->executionContext->getRequest()->getFragment($astField->getName());
346 3
                    $astFragmentModel = $astFragment->getModel();
347 3
                    $typeName         = $type->getName();
348
349 3 View Code Duplication
                    if ($typeName !== $astFragmentModel) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
350 1
                        foreach ($type->getInterfaces() as $interface) {
351 1
                            if ($interface->getName() === $astFragmentModel) {
352 1
                                $result = array_merge($result, $this->collectResult($field, $type, $astFragment, $resolvedValue));
353
354 1
                                break;
355
                            }
356
357 1
                        }
358
359 1
                        continue;
360
                    }
361
362 3
                    $result = array_merge($result, $this->collectResult($field, $type, $astFragment, $resolvedValue));
363
364 3
                    break;
365
366 24
                default:
367 24
                    $result[$this->getAlias($astField)] = $this->resolveField($field, $astField, $resolvedValue, true);
368 24
            }
369 24
        }
370
371 24
        return $result;
372
    }
373
374 30
    protected function resolveScalar(FieldInterface $field, AstFieldInterface $ast, $parentValue)
375
    {
376 30
        $resolvedValue = $this->doResolve($field, $ast, $parentValue);
377
378 30
        $this->resolveValidator->assertValidResolvedValueForField($field, $resolvedValue);
379
380
        /** @var AbstractScalarType $type */
381 29
        $type = $field->getType()->getNullableType();
382
383 29
        return $type->serialize($resolvedValue);
384
    }
385
386 14
    protected function resolveList(FieldInterface $field, AstFieldInterface $ast, $parentValue)
387
    {
388
        /** @var AstQuery $ast */
389 14
        $resolvedValue = $this->doResolve($field, $ast, $parentValue);
390
391 14
        $this->resolveValidator->assertValidResolvedValueForField($field, $resolvedValue);
392
393 13
        if (null === $resolvedValue) {
394 5
            return null;
395
        }
396
397
        /** @var AbstractListType $type */
398 12
        $type     = $field->getType()->getNullableType();
399 12
        $itemType = $type->getNamedType();
400
401 12
        $fakeAst = clone $ast;
402 12
        if ($fakeAst instanceof AstQuery) {
403 12
            $fakeAst->setArguments([]);
404 12
        }
405
406 12
        $fakeField = new Field([
407 12
            'name' => $field->getName(),
408 12
            'type' => $itemType,
409 12
        ]);
410
411 12
        $result = [];
412 12
        foreach ($resolvedValue as $resolvedValueItem) {
413
            try {
414 11
                $fakeField->getConfig()->set('resolve', function () use ($resolvedValueItem) {
415 11
                    return $resolvedValueItem;
416 11
                });
417
418 11
                switch ($itemType->getNullableType()->getKind()) {
419 11
                    case TypeMap::KIND_ENUM:
420 11
                    case TypeMap::KIND_SCALAR:
421 4
                        $value = $this->resolveScalar($fakeField, $fakeAst, $resolvedValueItem);
422
423 3
                        break;
424
425
426 8
                    case TypeMap::KIND_OBJECT:
427 6
                        $value = $this->resolveObject($fakeField, $fakeAst, $resolvedValueItem);
428
429 6
                        break;
430
431 3
                    case TypeMap::KIND_UNION:
432 3
                    case TypeMap::KIND_INTERFACE:
433 3
                        $value = $this->resolveComposite($fakeField, $fakeAst, $resolvedValueItem);
434
435 3
                        break;
436
437
                    default:
438
                        $value = null;
439 10
                }
440 11
            } catch (\Exception $e) {
441 2
                $this->executionContext->addError($e);
442
443 2
                $value = null;
444
            }
445
446 11
            $result[] = $value;
447 12
        }
448
449 12
        return $result;
450
    }
451
452 7
    protected function resolveComposite(FieldInterface $field, AstFieldInterface $ast, $parentValue)
453
    {
454
        /** @var AstQuery $ast */
455 7
        $resolvedValue = $this->doResolve($field, $ast, $parentValue);
456
457 7
        $this->resolveValidator->assertValidResolvedValueForField($field, $resolvedValue);
458
459
        /** @var AbstractUnionType $type */
460 7
        $type         = $field->getType()->getNullableType();
461 7
        $resolvedType = $type->resolveType($resolvedValue);
462
463 7
        if (!$resolvedType) {
464
            throw new ResolveException('Resoling function must return type');
465
        }
466
467 7
        if ($type instanceof AbstractInterfaceType) {
468 6
            $this->resolveValidator->assertTypeImplementsInterface($resolvedType, $type);
469 6
        } else {
470 1
            $this->resolveValidator->assertTypeInUnionTypes($resolvedType, $type);
471
        }
472
473 7
        $fakeField = new Field([
474 7
            'name' => $field->getName(),
475 7
            'type' => $resolvedType,
476 7
        ]);
477
478 7
        return $this->resolveObject($fakeField, $ast, $resolvedValue, true);
479
    }
480
481 39
    protected function parseAndCreateRequest($payload, $variables = [])
482
    {
483 39
        if (empty($payload)) {
484 1
            throw new \InvalidArgumentException('Must provide an operation.');
485
        }
486
487 39
        $parser  = new Parser();
488 39
        $request = new Request($parser->parse($payload), $variables);
489
490 39
        (new RequestValidator())->validate($request);
491
492 38
        $this->executionContext->setRequest($request);
493 38
    }
494
495 35
    protected function doResolve(FieldInterface $field, AstFieldInterface $ast, $parentValue = null)
496
    {
497
        /** @var AstQuery|AstField $ast */
498 35
        $arguments = $this->parseArgumentsValues($field, $ast);
499 35
        $astFields = $ast instanceof AstQuery ? $ast->getFields() : [];
500
501 35
        return $field->resolve($parentValue, $arguments, $this->createResolveInfo($field, $astFields));
502
    }
503
504 35
    protected function parseArgumentsValues(FieldInterface $field, AstFieldInterface $ast)
505
    {
506 35
        $values   = [];
507 35
        $defaults = [];
508
509 35
        foreach ($field->getArguments() as $argument) {
510
            /** @var $argument InputField */
511 21
            if ($argument->getConfig()->has('default')) {
512 6
                $defaults[$argument->getName()] = $argument->getConfig()->getDefaultValue();
513 6
            }
514 35
        }
515
516 35
        foreach ($ast->getArguments() as $astArgument) {
517 15
            $argument     = $field->getArgument($astArgument->getName());
518 15
            $argumentType = $argument->getType()->getNullableType();
519
520 15
            $values[$argument->getName()] = $argumentType->parseValue($astArgument->getValue());
521
522 15
            if (isset($defaults[$argument->getName()])) {
523 3
                unset($defaults[$argument->getName()]);
524 3
            }
525 35
        }
526
527 35
        return array_merge($values, $defaults);
528
    }
529
530 38
    private function getAlias(AstFieldInterface $ast)
531
    {
532 38
        return $ast->getAlias() ?: $ast->getName();
533
    }
534
535 35
    protected function createResolveInfo(FieldInterface $field, array $astFields)
536
    {
537 35
        return new ResolveInfo($field, $astFields, $this->executionContext);
538
    }
539
540
}
541