private void completeFieldNames()

in src/main/com/intellij/lang/jsgraphql/ide/completion/GraphQLCompletionContributor.java [893:968]


  private void completeFieldNames() {
    CompletionProvider<CompletionParameters> provider = new CompletionProvider<>() {
      @Override
      protected void addCompletions(final @NotNull CompletionParameters parameters,
                                    @NotNull ProcessingContext context,
                                    @NotNull CompletionResultSet result) {

        final PsiElement completionElement = Optional.ofNullable(parameters.getOriginalPosition()).orElse(parameters.getPosition());

        GraphQLTypeScopeProvider typeScopeProvider = PsiTreeUtil.getParentOfType(completionElement, GraphQLTypeScopeProvider.class);

        // check for incomplete field name, in which case we want the parent element as type scope to find this field name
        GraphQLField completionField = null;
        if (PsiUtilCore.getElementType(completionElement) == GraphQLElementTypes.NAME) {
          completionField = PsiTreeUtil.getParentOfType(completionElement, GraphQLField.class);
        }
        if (typeScopeProvider == completionField) {
          // completed on incomplete field name, use parent
          typeScopeProvider = PsiTreeUtil.getParentOfType(typeScopeProvider, GraphQLTypeScopeProvider.class);
        }

        if (typeScopeProvider == null) {
          return;
        }

        PsiElement prevLeaf = PsiTreeUtil.prevLeaf(completionElement);
        boolean isSpread = prevLeaf != null && prevLeaf.textContains('.');
        if (isSpread) {
          return;
        }

        GraphQLType typeScope = typeScopeProvider.getTypeScope();
        if (typeScope != null) {
          // we need the raw type to get the fields
          typeScope = GraphQLSchemaUtil.getUnmodified(typeScope);
        }
        if (typeScope instanceof GraphQLFieldsContainer) {
          ((GraphQLFieldsContainer)typeScope).getFieldDefinitions().forEach(field -> {
            String name = field.getName();
            if (name == null) {
              return;
            }
            String typeText = GraphQLSchemaUtil.formatAsTypeReference(field.getType());
            InsertHandler<LookupElement> insertHandler = getInsertHandler(field);
            result.addElement(GraphQLCompletionUtil.createFieldNameLookupElement(
              name, typeText, field.isDeprecated(), insertHandler));
          });
        }

        // and add the built-in __typename option
        result.addElement(
          GraphQLCompletionUtil.createFieldNameLookupElement(
            GraphQLKnownTypes.INTROSPECTION_TYPENAME_FIELD, null, false, null));
      }


      private static @Nullable InsertHandler<LookupElement> getInsertHandler(
        @NotNull com.intellij.lang.jsgraphql.types.schema.GraphQLFieldDefinition field) {
        if (GraphQLSchemaUtil.hasRequiredArgs(field)) {
          return GraphQLCompletionUtil.ARGUMENTS_LIST_HANDLER;
        }

        if (!field.getArguments().isEmpty()) {
          return null;
        }

        GraphQLUnmodifiedType type = GraphQLSchemaUtil.getUnmodified(field.getType());
        if (type instanceof GraphQLFieldsContainer || type instanceof GraphQLUnionType) {
          return GraphQLCompletionUtil.ADD_BRACES_HANDLER;
        }

        return null;
      }
    };
    extend(CompletionType.BASIC, psiElement(GraphQLElementTypes.NAME).withSuperParent(2, GraphQLField.class), provider);
  }