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);
}