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;
                    
                    $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
Given a selectionSet adds all of the fields in that selection to the passed in map of fields and returns it at the end .