src/Executor/ReferenceExecutor.php
private function collectFields(
        ObjectType $runtimeType,
        SelectionSetNode $selectionSet,
        $fields,
        $visitedFragmentNames
    ) {
        $exeContext = $this->exeContext;
        foreach ($selectionSet->selections as $selection) {
            switch ($selection->kind) {
                case NodeKind::FIELD:
                    if (! $this->shouldIncludeNode($selection)) {
                        break;
                    }
                    $name = self::getFieldEntryKey($selection);
                    if (! isset($fields[$name])) {
                        $fields[$name] = new ArrayObject();
                    }
                    $fields[$name][] = $selection;
                    break;
                case NodeKind::INLINE_FRAGMENT:
                    if (! $this->shouldIncludeNode($selection) ||
                        ! $this->doesFragmentConditionMatch($selection, $runtimeType)
                    ) {
                        break;
                    }
                    $this->collectFields(
                        $runtimeType,
                        $selection->selectionSet,
                        $fields,
                        $visitedFragmentNames
                    );
                    break;
                case NodeKind::FRAGMENT_SPREAD:
                    $fragName = $selection->name->value;
                    if (! empty($visitedFragmentNames[$fragName]) || ! $this->shouldIncludeNode($selection)) {
                        break;
                    }
                    $visitedFragmentNames[$fragName] = true;
                    /** @var FragmentDefinitionNode|null $fragment */
                    $fragment = $exeContext->fragments[$fragName] ?? null;
                    if (! $fragment || ! $this->doesFragmentConditionMatch($fragment, $runtimeType)) {
                        break;
                    }
                    $this->collectFields(
                        $runtimeType,
                        $fragment->selectionSet,
                        $fields,
                        $visitedFragmentNames
                    );
                    break;
            }
        }

        return $fields;
    }
private function collectFields(
        ObjectType $runtimeType,
        SelectionSetNode $selectionSet,
        $fields,
        $visitedFragmentNames
    ) {
        $exeContext = $this->exeContext;
        foreach ($selectionSet->selections as $selection) {
            switch ($selection->kind) {
                case NodeKind::FIELD:
                    if (! $this->shouldIncludeNode($selection)) {
                        break;
                    }
                    $name = self::getFieldEntryKey($selection);
                    if (! isset($fields[$name])) {
                        $fields[$name] = new ArrayObject();
                    }
                    $fields[$name][] = $selection;
                    break;
                case NodeKind::INLINE_FRAGMENT:
                    if (! $this->shouldIncludeNode($selection) ||
                        ! $this->doesFragmentConditionMatch($selection, $runtimeType)
                    ) {
                        break;
                    }
                    $this->collectFields(
                        $runtimeType,
                        $selection->selectionSet,
                        $fields,
                        $visitedFragmentNames
                    );
                    break;
                case NodeKind::FRAGMENT_SPREAD:
                    $fragName = $selection->name->value;
                    if (! empty($visitedFragmentNames[$fragName]) || ! $this->shouldIncludeNode($selection)) {
                        break;
                    }
                    $visitedFragmentNames[$fragName] = true;
                    /** @var FragmentDefinitionNode|null $fragment */
                    $fragment = $exeContext->fragments[$fragName] ?? null;
                    if (! $fragment || ! $this->doesFragmentConditionMatch($fragment, $runtimeType)) {
                        break;
                    }
                    $this->collectFields(
                        $runtimeType,
                        $fragment->selectionSet,
                        $fields,
                        $visitedFragmentNames
                    );
                    break;
            }
        }

        return $fields;
    }
Given a selectionSet, adds all of the fields in that selection to
the passed in map of fields, and returns it at the end.

CollectFields requires the "runtime type" of an object. For a field which
returns an Interface or Union type, the "runtime type" will be the actual
Object type returned by that field.

@param ArrayObject $fields
@param ArrayObject $visitedFragmentNames

@return ArrayObject