类 com.intellij.codeInsight.completion.CompletionProvider 源码实例Demo

下面列出了怎么用 com.intellij.codeInsight.completion.CompletionProvider 的API类实例代码及写法,或者点击链接到github查看源代码。


public LSPCompletionContributor() {
    this.extend(CompletionType.BASIC, usePattern(), new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet result) {
            try {
                ApplicationUtil.runWithCheckCanceled(() -> {
                    Editor editor = parameters.getEditor();
                    int offset = parameters.getOffset();
                    Position serverPos = DocumentUtils.offsetToLSPPos(editor, offset);

                    EditorEventManager manager = EditorEventManagerBase.forEditor(editor);
                    if (manager != null) {
                        result.addAllElements(manager.completion(serverPos));
                    }
                    return null;
                }, ProgressIndicatorProvider.getGlobalProgressIndicator());
            } catch (ProcessCanceledException ignored) {
                // ProcessCanceledException can be ignored.
            } catch (Exception e) {
                LOG.warn("LSP Completions ended with an error", e);
            }
        }
    });
}
 

/**
 * Complete the "visibility" and "stricthtml" keywords in template definition open tags.
 */
private void extendWithTemplateDefinitionLevelKeywords() {
  extend(
      CompletionType.BASIC,
      psiElement().andOr(psiElement().inside(SoyBeginTemplate.class)),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            @NotNull CompletionParameters completionParameters,
            ProcessingContext processingContext,
            @NotNull CompletionResultSet completionResultSet) {
          if (isPrecededBy(
              completionParameters.getPosition(),
              elt -> elt instanceof SoyTemplateDefinitionIdentifier)) {
            completionResultSet.addElement(LookupElementBuilder.create("visibility=\"private\""));
            completionResultSet.addElement(LookupElementBuilder.create("stricthtml=\"true\""));
          }
        }
      });
}
 

public WorkspaceTypeCompletionContributor() {
  extend(
      CompletionType.BASIC,
      psiElement()
          .withLanguage(ProjectViewLanguage.INSTANCE)
          .inside(ProjectViewPsiScalarSection.class)
          .afterLeaf(psiElement().withText(":").afterLeaf(WorkspaceTypeSection.KEY.getName())),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            CompletionParameters parameters,
            ProcessingContext context,
            CompletionResultSet result) {
          for (WorkspaceType type : WorkspaceType.values()) {
            result.addElement(LookupElementBuilder.create(type.getName()));
          }
        }
      });
}
 

public AdditionalLanguagesCompletionContributor() {
  extend(
      CompletionType.BASIC,
      psiElement()
          .withLanguage(ProjectViewLanguage.INSTANCE)
          .inside(
              psiElement(ProjectViewPsiListSection.class)
                  .withText(
                      StandardPatterns.string()
                          .startsWith(AdditionalLanguagesSection.KEY.getName()))),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            CompletionParameters parameters,
            ProcessingContext context,
            CompletionResultSet result) {
          for (LanguageClass type :
              availableAdditionalLanguages(parameters.getEditor().getProject())) {
            result.addElement(LookupElementBuilder.create(type.getName()));
          }
        }
      });
}
 

public ProjectViewKeywordCompletionContributor() {
  extend(
      CompletionType.BASIC,
      psiElement()
          .withLanguage(ProjectViewLanguage.INSTANCE)
          .withElementType(ProjectViewTokenType.IDENTIFIERS)
          .andOr(psiElement().afterLeaf("\n"), psiElement().afterLeaf(psiElement().isNull())),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            CompletionParameters parameters,
            ProcessingContext context,
            CompletionResultSet result) {
          result.addAllElements(keywordLookups);
        }
      });
}
 

public BuiltInSymbolCompletionContributor() {
  extend(
      CompletionType.BASIC,
      psiElement()
          .withLanguage(BuildFileLanguage.INSTANCE)
          .withParent(ReferenceExpression.class)
          .andNot(psiComment())
          .andNot(psiElement().afterLeaf(psiElement(BuildToken.fromKind(TokenKind.INT))))
          .andNot(psiElement().inside(FuncallExpression.class))
          .andNot(psiElement().afterLeaf(psiElement().withText(".")))
          .andNot(psiElement().inFile(psiFile(BuildFileWithCustomCompletion.class))),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            CompletionParameters parameters,
            ProcessingContext context,
            CompletionResultSet result) {
          for (String symbol : BuiltInNamesProvider.GLOBALS) {
            result.addElement(LookupElementBuilder.create(symbol));
          }
        }
      });
}
 

private void extendForVariablesAndFunctions() {
    extend(CompletionType.BASIC, referencePattern(XQueryTypes.NCNAME).withReferenceOfAnyOfTypes
                    (XQueryFunctionReference.class),
            new CompletionProvider<CompletionParameters>() {
                @Override
                protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context,
                                              @NotNull CompletionResultSet result) {
                    XQueryFile originalFile = (XQueryFile) parameters.getOriginalFile();
                    VariableCollector variableCollector = new VariableCollector(parameters
                            .getPosition());

                    result.addAllElements(FunctionCollector.getLookUpItems(originalFile));
                    result.addAllElements(variableCollector.getProposedLookUpItems());
                }
            });
}
 

private static CompletionProvider<CompletionParameters> typeCompletionProvider() {
  return new CompletionProvider<CompletionParameters>() {
    @Override
    protected void addCompletions(
        @NotNull CompletionParameters completionParameters,
        ProcessingContext processingContext,
        @NotNull CompletionResultSet completionResultSet) {
      PsiElement element = completionParameters.getPosition();

      // Method parameter type in the Spec class
      // PsiIdentifier -> PsiJavaCodeReferenceElement -> PsiTypeElement -> PsiMethod -> PsiClass
      PsiElement typeElement = PsiTreeUtil.getParentOfType(element, PsiTypeElement.class);
      if (typeElement == null) {
        return;
      }
      PsiMethod containingMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
      if (containingMethod == null) {
        return;
      }
      PsiClass cls = containingMethod.getContainingClass();
      if (!LithoPluginUtils.isLithoSpec(cls)) {
        return;
      }

      // @Prop or @State annotation
      PsiModifierList parameterModifiers =
          PsiTreeUtil.getPrevSiblingOfType(typeElement, PsiModifierList.class);
      if (parameterModifiers == null) {
        return;
      }
      if (parameterModifiers.findAnnotation(Prop.class.getName()) != null) {
        addCompletionResult(
            completionResultSet, containingMethod, cls.getMethods(), LithoPluginUtils::isProp);
      } else if (parameterModifiers.findAnnotation(State.class.getName()) != null) {
        addCompletionResult(
            completionResultSet, containingMethod, cls.getMethods(), LithoPluginUtils::isState);
      }
    }
  };
}
 

KeywordCompletionContributor(ORTypes types) {
    extend(CompletionType.BASIC, psiElement(), new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet result) {
            PsiElement position = parameters.getPosition();
            PsiElement originalPosition = parameters.getOriginalPosition();
            PsiElement element = originalPosition == null ? position : originalPosition;
            IElementType prevNodeType = CompletionUtils.getPrevNodeType(element);
            PsiElement parent = element.getParent();
            PsiElement grandParent = parent == null ? null : parent.getParent();

            if (LOG.isTraceEnabled()) {
                LOG.trace("»» Completion: position: " + position + ", " + position.getText());
                LOG.trace("               original: " + originalPosition + ", " + (originalPosition == null ? null : originalPosition.getText()));
                LOG.trace("                element: " + element);
                LOG.trace("                 parent: " + parent);
                LOG.trace("           grand-parent: " + grandParent);
                LOG.trace("                   file: " + parameters.getOriginalFile());
            }

            if (originalPosition == null && parent instanceof FileBase) {
                if (prevNodeType != types.DOT && prevNodeType != types.SHARPSHARP && prevNodeType != types.C_LOWER_SYMBOL) {
                    addFileKeywords(result);
                }
            }
        }
    });
}
 

/**
 * Complete fully qualified namespace fragments for alias declaration.
 */
private void extendWithIdentifierFragmentsForAlias() {
  extend(
      CompletionType.BASIC,
      psiElement().inside(SoyAliasBlock.class),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            @NotNull CompletionParameters completionParameters,
            ProcessingContext processingContext,
            @NotNull CompletionResultSet completionResultSet) {
          PsiElement identifierElement =
              PsiTreeUtil.getParentOfType(
                  completionParameters.getPosition(), SoyNamespaceIdentifier.class);
          String identifier = identifierElement == null ? "" : identifierElement.getText();

          String prefix = identifier.replaceFirst(INTELLIJ_IDEA_RULEZZZ, "");
          Collection<TemplateNameUtils.Fragment> completions =
              TemplateNameUtils.getTemplateNamespaceFragments(
                  completionParameters.getPosition().getProject(), prefix);

          completionResultSet.addAllElements(
              completions.stream()
                  .map(
                      (fragment) ->
                          LookupElementBuilder.create(fragment.text)
                              .withTypeText(
                                  fragment.isFinalFragment ? "Namespace" : "Partial namespace"))
                  .collect(Collectors.toList()));
        }
      });
}
 

/**
 * Complete types in {@param ...} .
 */
private void extendWithParameterTypes() {
  // Complete types in @param.
  extend(
      CompletionType.BASIC,
      psiElement()
          .andOr(
              psiElement().inside(SoyAtParamSingle.class).afterLeaf(":"),
              psiElement().inside(SoyAtInjectSingle.class).afterLeaf(":"),
              psiElement().inside(SoyAtStateSingle.class).afterLeaf(":"),

              // List type literal.
              psiElement().inside(SoyListType.class).afterLeaf("<"),

              // Map type literal.
              psiElement().inside(SoyMapType.class).afterLeaf("<"),
              psiElement().inside(SoyMapType.class).afterLeaf(",")),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            @NotNull CompletionParameters completionParameters,
            ProcessingContext processingContext,
            @NotNull CompletionResultSet completionResultSet) {
          completionResultSet.addAllElements(SOY_TYPE_LITERALS);
        }
      });
}
 

public ArgumentCompletionContributor() {
  extend(
      CompletionType.BASIC,
      psiElement()
          .withLanguage(BuildFileLanguage.INSTANCE)
          .withElementType(BuildToken.fromKind(TokenKind.IDENTIFIER))
          .withParents(ReferenceExpression.class, Argument.Positional.class)
          .andNot(psiComment())
          .andNot(psiElement().afterLeaf("="))
          .andNot(psiElement().afterLeaf(psiElement(BuildToken.fromKind(TokenKind.IDENTIFIER)))),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            CompletionParameters parameters,
            ProcessingContext context,
            CompletionResultSet result) {
          Argument.Positional arg =
              PsiTreeUtil.getParentOfType(parameters.getPosition(), Argument.Positional.class);
          if (arg != null) {
            Object[] lookups = arg.getReference().getVariants();
            for (Object lookup : lookups) {
              if (lookup instanceof LookupElement) {
                result.addElement((LookupElement) lookup);
              }
            }
          }
        }
      });
}
 

private void extendForKeywords() {
    extend(CompletionType.BASIC, psiElement().inFile(instanceOf(XQueryFile.class)),
            new CompletionProvider<CompletionParameters>() {
                @Override
                protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context,
                                              @NotNull CompletionResultSet result) {
                    PsiElement position = parameters.getPosition();
                    if (isInsideOfUriLiteral(position)) return;
                    KeywordCollector keywordCollector = new KeywordCollector();
                    result.addAllElements(keywordCollector.getProposedLookUpItems(position));
                }
            });
}
 

private void extendForVariablesOnly() {
    extend(CompletionType.BASIC, referencePattern(XQueryTypes.NCNAME).withReferenceOfAnyOfTypes
                    (XQueryVariableReference.class),
            new CompletionProvider<CompletionParameters>() {
                @Override
                protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context,
                                              @NotNull CompletionResultSet result) {
                    VariableCollector variableCollector = new VariableCollector(parameters
                            .getPosition());
                    result.addAllElements(variableCollector.getProposedLookUpItems());
                }
            });
}
 

/**
 * Complete variable names that are in scope when in an expression.
 */
private void extendWithVariableNamesInScope() {
  extend(
      CompletionType.BASIC,
      psiElement()
          .andOr(
              psiElement().inside(SoyExpr.class),
              psiElement().inside(SoyBeginIf.class),
              psiElement().inside(SoyBeginElseIf.class),
              psiElement().inside(SoyBeginFor.class),
              psiElement().inside(SoyBeginForeach.class),
              psiElement().inside(SoyPrintStatement.class),
              psiElement().inside(SoyListComprehensionExpr.class),
              psiElement()
                  .inside(SoyBeginParamTag.class)
                  .and(
                      psiElement()
                          .afterLeafSkipping(
                              psiElement(PsiWhiteSpace.class), psiElement(SoyTypes.COLON))),
              psiElement()
                  .inside(
                      or(instanceOf(SoyAtParamSingle.class), instanceOf(SoyAtStateSingle.class)))
                  .and(
                      psiElement()
                          .afterLeafSkipping(
                              psiElement(PsiWhiteSpace.class),
                              or(psiElement(SoyTypes.EQUAL), psiElement(SoyTypes.COLON_EQUAL))))),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            @NotNull CompletionParameters completionParameters,
            @NotNull ProcessingContext processingContext,
            @NotNull CompletionResultSet completionResultSet) {

          PsiElement currentElement = completionParameters.getPosition();

          if (shouldSkipVariableCompletion(currentElement)) {
            return;
          }
          boolean isInsideDefaultInitializer = isInsideDefaultInitializer(currentElement);
          if (isInsideDefaultInitializer
              && PsiTreeUtil.getParentOfType(currentElement, SoyAtParamSingle.class) != null) {
            // Default parameters cannot depend on other parameters or state.
            return;
          }

          Collection<Variable> params = Scope.getScopeOrEmpty(currentElement).getVariables();
          completionResultSet.addAllElements(
              params.stream()
                  .filter(
                      variable ->
                          !isInsideDefaultInitializer
                              // State cannot be referenced in default initializers.
                              || !(variable instanceof StateVariable))
                  .map(param -> "$" + param.name)
                  .map(LookupElementBuilder::create)
                  .collect(Collectors.toList()));
        }
      });
}
 

/**
 * Complete parameter names for {param .. /} in template function calls.
 */
private void extendWithParameterNames() {
  extend(
      CompletionType.BASIC,
      psiElement()
          .inside(SoyBeginParamTag.class)
          .and(
              psiElement()
                  .afterLeafSkipping(
                      psiElement(PsiWhiteSpace.class), psiElement().withText("param"))),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            @NotNull CompletionParameters completionParameters,
            ProcessingContext processingContext,
            @NotNull CompletionResultSet completionResultSet) {
          PsiElement position = completionParameters.getPosition();
          CallStatementElement callStatement =
              (CallStatementElement)
                  PsiTreeUtil.findFirstParent(
                      position, elt -> elt instanceof CallStatementElement);

          if (callStatement == null) {
            return;
          }

          PsiElement identifier =
              PsiTreeUtil.findChildOfType(callStatement, SoyTemplateReferenceIdentifier.class);

          if (identifier == null) {
            return;
          }

          Collection<String> givenParameters =
              ParamUtils.getGivenParameters(callStatement)
                  .stream()
                  .map(ParameterSpecification::name)
                  .collect(Collectors.toSet());
          List<Variable> parameters =
              ParamUtils.getParametersForInvocation(position, identifier.getText()).stream()
                  .filter(v -> !givenParameters.contains(v.name))
                  .collect(Collectors.toList());

          completionResultSet.addAllElements(
              parameters.stream()
                  .map(
                      (variable) ->
                          LookupElementBuilder.create(variable.name).withTypeText(variable.type))
                  .collect(Collectors.toList()));
        }
      });
}
 

public CommonMacroCompletionContributor() {
  extend(
      CompletionType.BASIC,
      psiElement()
          .withLanguage(BuildFileLanguage.INSTANCE)
          .andNot(psiElement().afterLeaf(psiElement(BuildToken.fromKind(TokenKind.INT))))
          .andNot(psiComment())
          .and(
              // Handles only top-level rules.
              // There are several other possibilities (e.g. inside macros),
              // but leaving out less common cases to avoid cluttering the autocomplete
              // suggestions when it's not valid to enter a rule.
              psiElement()
                  .withParents(
                      ReferenceExpression.class,
                      BuildFile.class)) // leaf node => BuildReference => BuildFile
          .andNot(psiElement().inFile(psiFile(BuildFileWithCustomCompletion.class))),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            CompletionParameters parameters,
            ProcessingContext context,
            CompletionResultSet result) {
          if (!enabled.getValue()) {
            return;
          }
          BuildFile file = getBuildFile(parameters.getPosition());
          if (file == null) {
            return;
          }
          ImmutableSet<String> existingSymbols = symbolsInScope(file);
          for (CommonMacros macro : CommonMacroContributor.getAllMacros()) {
            String packageLocation = macro.location();
            for (String symbol : macro.functionNames()) {
              if (existingSymbols.contains(symbol)) {
                continue;
              }
              result.addElement(
                  LookupElementBuilder.create(symbol)
                      .withIcon(BlazeIcons.BuildRule)
                      .withInsertHandler(getInsertHandler(file, packageLocation, symbol)));
            }
          }
        }
      });
}
 

public BuiltInFunctionAttributeCompletionContributor() {
  extend(
      CompletionType.BASIC,
      psiElement()
          .withLanguage(BuildFileLanguage.INSTANCE)
          .inside(psiElement(FuncallExpression.class))
          .andNot(psiComment())
          .andNot(psiElement().afterLeaf("."))
          .andNot(psiElement().afterLeaf(psiElement(BuildToken.fromKind(TokenKind.INT))))
          .andOr(
              psiElement().withSuperParent(2, FuncallExpression.class),
              psiElement()
                  .andOr(
                      psiElement().withSuperParent(2, Argument.class),
                      psiElement().withParent(Argument.class))
                  .andNot(psiElement().afterLeaf("="))
                  .andNot(
                      psiElement()
                          .afterLeaf(psiElement(BuildToken.fromKind(TokenKind.IDENTIFIER)))))
          .andNot(psiElement().inFile(psiFile(BuildFileWithCustomCompletion.class))),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            CompletionParameters parameters,
            ProcessingContext context,
            CompletionResultSet result) {
          BuildLanguageSpec spec =
              BuildLanguageSpecProvider.getInstance()
                  .getLanguageSpec(parameters.getPosition().getProject());
          if (spec == null) {
            return;
          }
          FuncallExpression funcall = getEnclosingFuncall(parameters.getPosition());
          if (funcall == null) {
            return;
          }
          RuleDefinition rule = spec.getRule(funcall.getFunctionName());
          if (rule == null) {
            return;
          }
          Set<String> existingAttributes = funcall.getKeywordArgumentNames();
          for (String attributeName : rule.getKnownAttributeNames()) {
            if (!existingAttributes.contains(attributeName)) {
              result.addElement(
                  LookupElementBuilder.create(attributeName).withIcon(AllIcons.Nodes.Parameter));
            }
          }
        }
      });
}
 

public BuiltInFunctionCompletionContributor() {
  extend(
      CompletionType.BASIC,
      psiElement()
          .withLanguage(BuildFileLanguage.INSTANCE)
          .andNot(psiElement().afterLeaf(psiElement(BuildToken.fromKind(TokenKind.INT))))
          .andNot(psiComment())
          .andOr(
              // Handles only top-level rules, and rules inside a function statement.
              // There are several other possibilities (e.g. inside top-level list comprehension),
              // but leaving out less common cases to avoid cluttering the autocomplete
              // suggestions when it's not valid to enter a rule.
              psiElement()
                  .withParents(
                      ReferenceExpression.class,
                      BuildFile.class), // leaf node => BuildReference => BuildFile
              psiElement()
                  .inside(
                      psiElement(StatementList.class).inside(psiElement(FunctionStatement.class)))
                  .afterLeaf(
                      psiElement().withText(".").afterLeaf(psiElement().withText("native"))))
          .andNot(psiElement().inFile(psiFile(BuildFileWithCustomCompletion.class))),
      new CompletionProvider<CompletionParameters>() {
        @Override
        protected void addCompletions(
            CompletionParameters parameters,
            ProcessingContext context,
            CompletionResultSet result) {
          Project project = parameters.getPosition().getProject();
          ImmutableSet<String> builtInNames =
              BuiltInNamesProvider.getBuiltInFunctionNames(project);
          BuildLanguageSpec spec =
              BuildLanguageSpecProvider.getInstance().getLanguageSpec(project);
          for (String ruleName : builtInNames) {
            result.addElement(
                LookupElementBuilder.create(ruleName)
                    .withIcon(BlazeIcons.BuildRule)
                    .withInsertHandler(getInsertHandler(ruleName, spec)));
          }
        }
      });
}
 

public JSGraphQLEndpointCompletionContributor() {

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

				final PsiFile file = parameters.getOriginalFile();

				if (!(file instanceof JSGraphQLEndpointFile)) {
					return;
				}

				final boolean autoImport = parameters.isExtendedCompletion() || parameters.getCompletionType() == CompletionType.SMART;

				final PsiElement completionElement = Optional.ofNullable(parameters.getOriginalPosition()).orElse(parameters.getPosition());
				if (completionElement != null) {

					final PsiElement parent = completionElement.getParent();
					final PsiElement leafBeforeCompletion = PsiTreeUtil.prevVisibleLeaf(completionElement);

					// 1. complete on interface name after IMPLEMENTS token
					if (completeImplementableInterface(result, autoImport, completionElement, leafBeforeCompletion)) {
						return;
					}

					// 2. import file
					if (completeImportFile(result, file, parent)) {
						return;
					}

					// 3.A. top level completions, e.g. keywords and definition annotations
					if (completeKeywordsAndDefinitionAnnotations(result, autoImport, completionElement, leafBeforeCompletion, parent)) {
						return;
					}

					// 3.B. implements when type definition surrounds completion element (e.g. when it has a FieldDefinitionSet)
					if (completeImplementsInsideTypeDefinition(result, completionElement, parent)) {
						return;
					}

					// 4. completions inside FieldDefinitionSet
					final JSGraphQLEndpointFieldDefinitionSet fieldDefinitionSet = PsiTreeUtil.getParentOfType(completionElement, JSGraphQLEndpointFieldDefinitionSet.class);
					if (fieldDefinitionSet != null) {

						// 4.A. field/argument type completion
						if (completeFieldOrArgumentType(result, autoImport, completionElement)) {
							return;
						}

						// 4.B. annotations
						if (completeAnnotations(result, autoImport, file, completionElement)) {
							return;
						}

						// 4.C. annotation arguments
						if (completeAnnotationArguments(result, file, completionElement, leafBeforeCompletion)) {
							return;
						}

						// 4.D. override for interface fields
						if (completeOverrideFields(fieldDefinitionSet, completionElement, result)) {
							return;
						}
					}

					// 5. completions inside SchemaDefinition
					if (completeInsideSchemaDefinition(result, completionElement, leafBeforeCompletion)) {
						return;
					}

				}

			}
		};

		extend(CompletionType.BASIC, PlatformPatterns.psiElement(), provider);
		extend(CompletionType.SMART, PlatformPatterns.psiElement(), provider);

	}
 

public JSGraphQLEndpointDocCompletionContributor() {

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

				final PsiFile file = parameters.getOriginalFile();

				if (!(file instanceof JSGraphQLEndpointDocFile)) {
					return;
				}

				final PsiElement completionElement = Optional.ofNullable(parameters.getOriginalPosition()).orElse(parameters.getPosition());
				if (completionElement != null) {
					final PsiComment comment = PsiTreeUtil.getContextOfType(completionElement, PsiComment.class);
					if (comment != null && JSGraphQLEndpointDocPsiUtil.isDocumentationComment(comment)) {

						if (completionElement.getNode().getElementType() == JSGraphQLEndpointDocTokenTypes.DOCVALUE) {
							final JSGraphQLEndpointFieldDefinition fieldDefinition = PsiTreeUtil.getNextSiblingOfType(comment, JSGraphQLEndpointFieldDefinition.class);
							if (fieldDefinition != null && fieldDefinition.getArgumentsDefinition() != null) {
								final List<String> otherDocTagValues = JSGraphQLEndpointDocPsiUtil.getOtherDocTagValues(comment);
								for (JSGraphQLEndpointInputValueDefinition arg : PsiTreeUtil.findChildrenOfType(fieldDefinition.getArgumentsDefinition(), JSGraphQLEndpointInputValueDefinition.class)) {
									final String argName = arg.getInputValueDefinitionIdentifier().getText();
									if (!otherDocTagValues.contains(argName)) {
										result.addElement(LookupElementBuilder.create(argName).withInsertHandler(AddSpaceInsertHandler.INSTANCE));
									}
								}
							}
							return;
						}

						final JSGraphQLEndpointDocTag tagBefore = PsiTreeUtil.getPrevSiblingOfType(completionElement, JSGraphQLEndpointDocTag.class);
						final JSGraphQLEndpointDocTag tagParent = PsiTreeUtil.getParentOfType(completionElement, JSGraphQLEndpointDocTag.class);
						if (tagBefore == null || tagParent != null) {
							String completion = "param";
							final boolean includeAt = completionElement.getNode().getElementType() != JSGraphQLEndpointDocTokenTypes.DOCNAME;
							if (includeAt) {
								completion = "@" + completion;
							}
							result.addElement(LookupElementBuilder.create(completion).withInsertHandler(AddSpaceInsertHandler.INSTANCE_WITH_AUTO_POPUP));
						}
					}
				}
			}
		};

		extend(CompletionType.BASIC, PlatformPatterns.psiElement(), provider);

	}