Completed
Push — master ( 4406e7...95db8c )
by Alexandr
02:55
created

Processor::prepareArgumentValue()   C

Complexity

Conditions 18
Paths 14

Size

Total Lines 54
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 34
CRAP Score 18.3782

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 54
ccs 34
cts 38
cp 0.8947
rs 6.6386
cc 18
eloc 34
nc 14
nop 3
crap 18.3782

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 53
    public function __construct(AbstractSchema $schema)
60
    {
61 53
        if (empty($this->executionContext)) {
62 53
            $this->executionContext = new ExecutionContext($schema);
63 53
            $this->executionContext->setContainer(new Container());
64 53
        }
65
66 53
        $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 53
    }
68
69 51
    public function processPayload($payload, $variables = [], $reducers = [])
70
    {
71 51
        $this->data = [];
72
73
        try {
74 51
            $this->parseAndCreateRequest($payload, $variables);
75
76 50
            if ($this->maxComplexity) {
77 1
                $reducers[] = new MaxComplexityQueryVisitor($this->maxComplexity);
78 1
            }
79
80 50
            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 50
            foreach ($this->executionContext->getRequest()->getAllOperations() as $query) {
86 50
                if ($operationResult = $this->resolveQuery($query)) {
87 50
                    $this->data = array_merge($this->data, $operationResult);
88 50
                };
89 50
            }
90 51
        } catch (\Exception $e) {
91 5
            $this->executionContext->addError($e);
92
        }
93
94 51
        return $this;
95
    }
96
97 51
    public function getResponseData()
98
    {
99 51
        $result = [];
100
101 51
        if (!empty($this->data)) {
102 50
            $result['data'] = $this->data;
103 50
        }
104
105 51
        if ($this->executionContext->hasErrors()) {
106 18
            $result['errors'] = $this->executionContext->getErrorsArray();
107 18
        }
108
109 51
        return $result;
110
    }
111
112
    /**
113
     * You can access ExecutionContext to check errors and inject dependencies
114
     *
115
     * @return ExecutionContext
116
     */
117 11
    public function getExecutionContext()
118
    {
119 11
        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 50
    protected function resolveQuery(AstQuery $query)
139
    {
140 50
        $schema = $this->executionContext->getSchema();
141 50
        $type   = $query instanceof AstMutation ? $schema->getMutationType() : $schema->getQueryType();
142 50
        $field  = new Field([
143 50
            'name' => $query instanceof AstMutation ? 'mutation' : 'query',
144
            'type' => $type
145 50
        ]);
146
147 50
        if (self::TYPE_NAME_QUERY == $query->getName()) {
148 1
            return [$this->getAlias($query) => $type->getName()];
149
        }
150
151 50
        $this->resolveValidator->assetTypeHasField($type, $query);
152 50
        $value = $this->resolveField($field, $query);
153
154 50
        return [$this->getAlias($query) => $value];
155
    }
156
157 50
    protected function resolveField(FieldInterface $field, AstFieldInterface $ast, $parentValue = null, $fromObject = false)
158
    {
159
        try {
160
            /** @var AbstractObjectType $type */
161 50
            $type        = $field->getType();
162 50
            $nonNullType = $type->getNullableType();
163
164 50
            if (self::TYPE_NAME_QUERY == $ast->getName()) {
165 2
                return $nonNullType->getName();
166
            }
167
168 50
            $this->resolveValidator->assetTypeHasField($nonNullType, $ast);
169
170 50
            $targetField = $nonNullType->getField($ast->getName());
171
172 50
            $this->prepareAstArguments($targetField, $ast, $this->executionContext->getRequest());
173 49
            $this->resolveValidator->assertValidArguments($targetField, $ast, $this->executionContext->getRequest());
174
175 45
            switch ($kind = $targetField->getType()->getNullableType()->getKind()) {
176 45
                case TypeMap::KIND_ENUM:
177 45
                case TypeMap::KIND_SCALAR:
178 39
                    if ($ast instanceof AstQuery && $ast->hasFields()) {
179 2
                        throw new ResolveException(sprintf('You can\'t specify fields for scalar type "%s"', $targetField->getType()->getNullableType()->getName()), $ast->getLocation());
180
                    }
181
182 39
                    return $this->resolveScalar($targetField, $ast, $parentValue);
183
184 30 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...
185
                    /** @var $type AbstractObjectType */
186 22
                    if (!$ast instanceof AstQuery) {
187 1
                        throw new ResolveException(sprintf('You have to specify fields for "%s"', $ast->getName()), $ast->getLocation());
188
                    }
189
190 22
                    return $this->resolveObject($targetField, $ast, $parentValue);
191
192 17
                case TypeMap::KIND_LIST:
193 14
                    return $this->resolveList($targetField, $ast, $parentValue);
194
195 6
                case TypeMap::KIND_UNION:
196 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...
197 6
                    if (!$ast instanceof AstQuery) {
198
                        throw new ResolveException(sprintf('You have to specify fields for "%s"', $ast->getName()), $ast->getLocation());
199
                    }
200
201 6
                    return $this->resolveComposite($targetField, $ast, $parentValue);
202
203
                default:
204
                    throw new ResolveException(sprintf('Resolving type with kind "%s" not supported', $kind));
205
            }
206 16
        } catch (\Exception $e) {
207 16
            $this->executionContext->addError($e);
208
209 16
            if ($fromObject) {
210 4
                throw $e;
211
            }
212
213 14
            return null;
214
        }
215
    }
216
217 50
    private function prepareAstArguments(FieldInterface $field, AstFieldInterface $query, Request $request)
218
    {
219 50
        foreach ($query->getArguments() as $astArgument) {
220 27
            if ($field->hasArgument($astArgument->getName())) {
221 27
                $argumentType = $field->getArgument($astArgument->getName())->getType()->getNullableType();
222
223 27
                $astArgument->setValue($this->prepareArgumentValue($astArgument->getValue(), $argumentType, $request));
224 26
            }
225 49
        }
226 49
    }
227
228 27
    private function prepareArgumentValue($argumentValue, AbstractType $argumentType, Request $request)
229
    {
230 27
        switch ($argumentType->getKind()) {
231 27
            case TypeMap::KIND_LIST:
232
                /** @var $argumentType AbstractListType */
233 6
                $result = [];
234 6
                if ($argumentValue instanceof AstInputList || is_array($argumentValue)) {
235 5
                    $list = is_array($argumentValue) ? $argumentValue : $argumentValue->getValue();
236 5
                    foreach ($list as $item) {
237 5
                        $result[] = $this->prepareArgumentValue($item, $argumentType->getItemType()->getNullableType(), $request);
238 5
                    }
239 6
                } else if ($argumentValue instanceof VariableReference) {
240 1
                    return $this->getVariableReferenceArgumentValue($argumentValue, $argumentType, $request);
241
                }
242
243 5
                return $result;
244
245 26
            case TypeMap::KIND_INPUT_OBJECT:
246
                /** @var $argumentType AbstractInputObjectType */
247 3
                $result = [];
248 3
                if ($argumentValue instanceof AstInputObject) {
249 3
                    foreach ($argumentType->getFields() as $field) {
250
                        /** @var $field Field */
251 3
                        if ($field->getConfig()->has('default')) {
252 1
                            $result[$field->getName()] = $field->getType()->getNullableType()->parseInputValue($field->getConfig()->get('default'));
253 1
                        }
254 3
                    }
255 3
                    foreach ($argumentValue->getValue() as $key => $item) {
256 3
                        if ($argumentType->hasField($key)) {
257 3
                            $result[$key] = $this->prepareArgumentValue($item, $argumentType->getField($key)->getType()->getNullableType(), $request);
258 3
                        } else {
259
                            $result[$key] = $item;
260
                        }
261 3
                    }
262 3
                } else if ($argumentValue instanceof VariableReference) {
263
                    return $this->getVariableReferenceArgumentValue($argumentValue, $argumentType, $request);
264
                }
265
266 3
                return $result;
267
268 26
            case TypeMap::KIND_SCALAR:
269 26
            case TypeMap::KIND_ENUM:
270
                /** @var $argumentValue AstLiteral|VariableReference */
271 26
                if ($argumentValue instanceof VariableReference) {
272 4
                    return $this->getVariableReferenceArgumentValue($argumentValue, $argumentType, $request);
273 23
                } else if ($argumentValue instanceof AstLiteral) {
274 17
                    return $argumentValue->getValue();
275
                } else {
276 7
                    return $argumentValue;
277
                }
278
        }
279
280
        throw new ResolveException('Argument type not supported');
281
    }
282
283 5
    private function getVariableReferenceArgumentValue(VariableReference $variableReference, AbstractType $argumentType, Request $request)
284
    {
285 5
        $variable = $variableReference->getVariable();
286 5
        if ($argumentType->getKind() === TypeMap::KIND_LIST) {
287
            if (
288 1
                !$variable->isArray() ||
289 1
                ($variable->getTypeName() !== $argumentType->getNamedType()->getNullableType()->getName()) ||
290 1
                ($argumentType->getNamedType()->getKind() === TypeMap::KIND_NON_NULL && $variable->isArrayElementNullable())
291 1
            ) {
292 1
                throw new ResolveException(sprintf('Invalid variable "%s" type, allowed type is "%s"', $variable->getName(), $argumentType->getNamedType()->getNullableType()->getName()), $variable->getLocation());
293
            }
294 1
        } else {
295 4
            if ($variable->getTypeName() !== $argumentType->getName()) {
296 1
                throw new ResolveException(sprintf('Invalid variable "%s" type, allowed type is "%s"', $variable->getName(), $argumentType->getName()), $variable->getLocation());
297
            }
298
        }
299
300 4
        $requestValue = $request->getVariable($variable->getName());
301 4
        if ((null === $requestValue && $variable->isNullable()) && !$request->hasVariable($variable->getName())) {
302
            throw  new ResolveException(sprintf('Variable "%s" does not exist in request', $variable->getName()), $variable->getLocation());
303
        }
304
305 4
        return $requestValue;
306
    }
307
308 27
    protected function resolveObject(FieldInterface $field, AstFieldInterface $ast, $parentValue, $fromUnion = false)
309
    {
310 27
        $resolvedValue = $parentValue;
311 27
        if (!$fromUnion) {
312 22
            $resolvedValue = $this->doResolve($field, $ast, $parentValue);
313 22
        }
314
315 27
        $this->resolveValidator->assertValidResolvedValueForField($field, $resolvedValue);
316
317 27
        if (null === $resolvedValue) {
318 5
            return null;
319
        }
320
        /** @var AbstractObjectType $type */
321 26
        $type = $field->getType()->getNullableType();
322
323
        try {
324 26
            return $this->collectResult($field, $type, $ast, $resolvedValue);
325 4
        } catch (\Exception $e) {
326 4
            return null;
327
        }
328
    }
329
330 26
    private function collectResult(FieldInterface $field, AbstractObjectType $type, $ast, $resolvedValue)
331
    {
332
        /** @var AstQuery $ast */
333 26
        $result = [];
334
335 26
        foreach ($ast->getFields() as $astField) {
336 26
            switch (true) {
337 26
                case $astField instanceof TypedFragmentReference:
338 2
                    $astName  = $astField->getTypeName();
339 2
                    $typeName = $type->getName();
340
341 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...
342 2
                        foreach ($type->getInterfaces() as $interface) {
343 1
                            if ($interface->getName() === $astName) {
344
                                $result = array_merge($result, $this->collectResult($field, $type, $astField, $resolvedValue));
345
346
                                break;
347
                            }
348 2
                        }
349
350 2
                        continue;
351
                    }
352
353 2
                    $result = array_merge($result, $this->collectResult($field, $type, $astField, $resolvedValue));
354
355 2
                    break;
356
357 26
                case $astField instanceof FragmentReference:
358 4
                    $astFragment      = $this->executionContext->getRequest()->getFragment($astField->getName());
359 4
                    $astFragmentModel = $astFragment->getModel();
360 4
                    $typeName         = $type->getName();
361
362 4 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...
363 1
                        foreach ($type->getInterfaces() as $interface) {
364 1
                            if ($interface->getName() === $astFragmentModel) {
365 1
                                $result = array_merge($result, $this->collectResult($field, $type, $astFragment, $resolvedValue));
366
367 1
                                break;
368
                            }
369
370 1
                        }
371
372 1
                        continue;
373
                    }
374
375 4
                    $result = array_merge($result, $this->collectResult($field, $type, $astFragment, $resolvedValue));
376
377 4
                    break;
378
379 26
                default:
380 26
                    $result[$this->getAlias($astField)] = $this->resolveField($field, $astField, $resolvedValue, true);
381 26
            }
382 26
        }
383
384 26
        return $result;
385
    }
386
387 39
    protected function resolveScalar(FieldInterface $field, AstFieldInterface $ast, $parentValue)
388
    {
389 39
        $resolvedValue = $this->doResolve($field, $ast, $parentValue);
390
391 39
        $this->resolveValidator->assertValidResolvedValueForField($field, $resolvedValue);
392
393
        /** @var AbstractScalarType $type */
394 38
        $type = $field->getType()->getNullableType();
395
396 38
        return $type->serialize($resolvedValue);
397
    }
398
399 14
    protected function resolveList(FieldInterface $field, AstFieldInterface $ast, $parentValue)
400
    {
401
        /** @var AstQuery $ast */
402 14
        $resolvedValue = $this->doResolve($field, $ast, $parentValue);
403
404 14
        $this->resolveValidator->assertValidResolvedValueForField($field, $resolvedValue);
405
406 12
        if (null === $resolvedValue) {
407 5
            return null;
408
        }
409
410
        /** @var AbstractListType $type */
411 11
        $type     = $field->getType()->getNullableType();
412 11
        $itemType = $type->getNamedType();
413
414 11
        $fakeAst = clone $ast;
415 11
        if ($fakeAst instanceof AstQuery) {
416 11
            $fakeAst->setArguments([]);
417 11
        }
418
419 11
        $fakeField = new Field([
420 11
            'name' => $field->getName(),
421 11
            'type' => $itemType,
422 11
        ]);
423
424 11
        $result = [];
425 11
        foreach ($resolvedValue as $resolvedValueItem) {
426
            try {
427 10
                $fakeField->getConfig()->set('resolve', function () use ($resolvedValueItem) {
428 10
                    return $resolvedValueItem;
429 10
                });
430
431 10
                switch ($itemType->getNullableType()->getKind()) {
432 10
                    case TypeMap::KIND_ENUM:
433 10
                    case TypeMap::KIND_SCALAR:
434 3
                        $value = $this->resolveScalar($fakeField, $fakeAst, $resolvedValueItem);
435
436 2
                        break;
437
438
439 8
                    case TypeMap::KIND_OBJECT:
440 6
                        $value = $this->resolveObject($fakeField, $fakeAst, $resolvedValueItem);
441
442 6
                        break;
443
444 3
                    case TypeMap::KIND_UNION:
445 3
                    case TypeMap::KIND_INTERFACE:
446 3
                        $value = $this->resolveComposite($fakeField, $fakeAst, $resolvedValueItem);
447
448 3
                        break;
449
450
                    default:
451
                        $value = null;
452 9
                }
453 10
            } catch (\Exception $e) {
454 1
                $this->executionContext->addError($e);
455
456 1
                $value = null;
457
            }
458
459 10
            $result[] = $value;
460 11
        }
461
462 11
        return $result;
463
    }
464
465 7
    protected function resolveComposite(FieldInterface $field, AstFieldInterface $ast, $parentValue)
466
    {
467
        /** @var AstQuery $ast */
468 7
        $resolvedValue = $this->doResolve($field, $ast, $parentValue);
469
470 7
        $this->resolveValidator->assertValidResolvedValueForField($field, $resolvedValue);
471
472
        /** @var AbstractUnionType $type */
473 7
        $type         = $field->getType()->getNullableType();
474 7
        $resolvedType = $type->resolveType($resolvedValue);
475
476 7
        if (!$resolvedType) {
477
            throw new ResolveException('Resoling function must return type');
478
        }
479
480 7
        if ($type instanceof AbstractInterfaceType) {
481 6
            $this->resolveValidator->assertTypeImplementsInterface($resolvedType, $type);
482 6
        } else {
483 1
            $this->resolveValidator->assertTypeInUnionTypes($resolvedType, $type);
484
        }
485
486 7
        $fakeField = new Field([
487 7
            'name' => $field->getName(),
488 7
            'type' => $resolvedType,
489 7
        ]);
490
491 7
        return $this->resolveObject($fakeField, $ast, $resolvedValue, true);
492
    }
493
494 51
    protected function parseAndCreateRequest($payload, $variables = [])
495
    {
496 51
        if (empty($payload)) {
497 1
            throw new \InvalidArgumentException('Must provide an operation.');
498
        }
499
500 51
        $parser  = new Parser();
501 51
        $request = new Request($parser->parse($payload), $variables);
502
503 51
        (new RequestValidator())->validate($request);
504
505 50
        $this->executionContext->setRequest($request);
506 50
    }
507
508 45
    protected function doResolve(FieldInterface $field, AstFieldInterface $ast, $parentValue = null)
509
    {
510
        /** @var AstQuery|AstField $ast */
511 45
        $arguments = $this->parseArgumentsValues($field, $ast);
512 45
        $astFields = $ast instanceof AstQuery ? $ast->getFields() : [];
513
514 45
        return $field->resolve($parentValue, $arguments, $this->createResolveInfo($field, $astFields));
515
    }
516
517 45
    protected function parseArgumentsValues(FieldInterface $field, AstFieldInterface $ast)
518
    {
519 45
        $values   = [];
520 45
        $defaults = [];
521
522 45
        foreach ($field->getArguments() as $argument) {
523
            /** @var $argument InputField */
524 31
            if ($argument->getConfig()->has('default')) {
525 6
                $defaults[$argument->getName()] = $argument->getConfig()->getDefaultValue();
526 6
            }
527 45
        }
528
529 45
        foreach ($ast->getArguments() as $astArgument) {
530 24
            $argument     = $field->getArgument($astArgument->getName());
531 24
            $argumentType = $argument->getType()->getNullableType();
532
533 24
            $values[$argument->getName()] = $argumentType->parseValue($astArgument->getValue());
534
535 24
            if (isset($defaults[$argument->getName()])) {
536 3
                unset($defaults[$argument->getName()]);
537 3
            }
538 45
        }
539
540 45
        return array_merge($values, $defaults);
541
    }
542
543 50
    private function getAlias(AstFieldInterface $ast)
544
    {
545 50
        return $ast->getAlias() ?: $ast->getName();
546
    }
547
548 45
    protected function createResolveInfo(FieldInterface $field, array $astFields)
549
    {
550 45
        return new ResolveInfo($field, $astFields, $this->executionContext);
551
    }
552
553
}
554