in src/main/com/intellij/lang/jsgraphql/ide/completion/GraphQLCompletionContributor.java [1070:1152]
private void completeVariableName() {
CompletionProvider<CompletionParameters> provider = new CompletionProvider<>() {
@Override
protected void addCompletions(final @NotNull CompletionParameters parameters,
@NotNull ProcessingContext context,
@NotNull CompletionResultSet result) {
final PsiElement completionElement = parameters.getPosition();
final GraphQLTypeScopeProvider typeScopeProvider =
PsiTreeUtil.getParentOfType(completionElement, GraphQLTypeScopeProvider.class);
if (typeScopeProvider == null) {
return;
}
final GraphQLType typeScope = typeScopeProvider.getTypeScope();
if (typeScope == null) {
return;
}
final GraphQLTypedOperationDefinition query =
PsiTreeUtil.getParentOfType(completionElement, GraphQLTypedOperationDefinition.class);
if (query == null || query.getVariableDefinitions() == null) {
return;
}
final VariablesTypesMatcher variablesTypesMatcher = new VariablesTypesMatcher();
final GraphQLSchema schema = GraphQLSchemaProvider.getInstance(completionElement.getProject())
.getSchemaInfo(parameters.getOriginalFile()).getSchema();
for (GraphQLVariableDefinition variableDefinition : query.getVariableDefinitions().getVariableDefinitions()) {
if (variableDefinition.getType() == null) {
continue;
}
final GraphQLIdentifier variableTypeIdentifier =
PsiTreeUtil.findChildOfType(variableDefinition.getType(), GraphQLIdentifier.class);
if (variableTypeIdentifier == null) {
continue;
}
GraphQLType declaredType = schema.getType(variableTypeIdentifier.getText());
if (declaredType == null) {
continue;
}
if (variableTypeIdentifier.getNextSibling() instanceof LeafPsiElement && "!".equals(
variableTypeIdentifier.getNextSibling().getText())) {
declaredType = new GraphQLNonNull(declaredType);
}
PsiElement parent = variableTypeIdentifier.getParent();
while (parent != null && !(parent instanceof GraphQLVariableDefinition)) {
if (parent instanceof GraphQLListType) {
declaredType = new GraphQLList(declaredType);
}
else if (parent instanceof GraphQLNonNullType) {
declaredType = new GraphQLNonNull(declaredType);
}
parent = parent.getParent();
}
final String variableNameCompletion = variableDefinition.getVariable().getText();
if (variablesTypesMatcher.doesVariableTypesMatch(declaredType, null, typeScope)) {
String typeText = GraphQLSchemaUtil.formatAsTypeReference(declaredType);
result.addElement(GraphQLCompletionUtil.createVariableLookupElement(variableNameCompletion, typeText));
}
else {
PsiElement elementParent = completionElement.getParent();
PsiElement elementGrandParent = elementParent.getParent();
if ((elementParent instanceof GraphQLVariable && elementGrandParent instanceof GraphQLArrayValue) ||
(elementParent instanceof GraphQLIdentifier && elementGrandParent instanceof GraphQLEnumValue &&
elementGrandParent.getParent() instanceof GraphQLArrayValue)) {
// variable is used inside a list literal, e.g. [$myVar], so need to unwrap the type scope
GraphQLType typeScopeWithoutList = GraphQLSchemaUtil.unwrapListType(typeScope);
if (variablesTypesMatcher.doesVariableTypesMatch(declaredType, null, typeScopeWithoutList)) {
String typeText = GraphQLSchemaUtil.formatAsTypeReference(declaredType);
result.addElement(GraphQLCompletionUtil.createVariableLookupElement(variableNameCompletion, typeText));
}
}
}
}
}
};
extend(CompletionType.BASIC, psiElement().andOr(
psiElement(GraphQLElementTypes.VARIABLE_NAME),
psiElement(GraphQLElementTypes.NAME).inside(GraphQLEnumValue.class)
).inside(GraphQLArgument.class), provider);
}