code: 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;
      }
docs: 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