private void completeVariableName()

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