in src/main/com/intellij/lang/jsgraphql/ide/validation/GraphQLValidationAnnotator.java [111:219]
private static void checkIdentifierReferences(@NotNull PsiElement element, @NotNull AnnotationHolder annotationHolder) {
Project project = element.getProject();
final PsiReference reference = element.getReference();
if (reference != null && reference.resolve() != null) {
return;
}
final PsiElement parent = element.getParent();
final GraphQLTypeScopeProvider typeScopeProvider = PsiTreeUtil.getParentOfType(parent, GraphQLTypeScopeProvider.class);
GraphQLType typeScope = null;
if (typeScopeProvider != null) {
typeScope = typeScopeProvider.getTypeScope();
if (typeScope != null) {
// unwrap non-nulls and lists for type and field hints
typeScope = GraphQLSchemaUtil.getUnmodified(typeScope);
}
}
String message = null;
// fixes to automatically rename misspelled identifiers
final List<LocalQuickFix> fixes = new ArrayList<>();
Consumer<List<String>> createFixes = (List<String> suggestions) ->
suggestions.forEach(suggestion -> fixes.add(new RenameElementFix((PsiNamedElement)element, suggestion)));
if (parent instanceof GraphQLField) {
message = GraphQLBundle.message("graphql.validation.unknown.field.0", element.getText());
if (typeScope != null) {
String definitionType = "";
if (typeScope instanceof GraphQLObjectType) {
definitionType = GraphQLBundle.message("graphql.validation.object.type");
}
else if (typeScope instanceof GraphQLInterfaceType) {
definitionType = GraphQLBundle.message("graphql.validation.interface.type");
}
if (!definitionType.isEmpty()) {
definitionType += " ";
}
message += " " + GraphQLBundle.message("graphql.validation.on.0.type.1", definitionType, GraphQLSchemaUtil.getTypeName(typeScope));
final List<String> suggestions = getFieldNameSuggestions(element.getText(), typeScope);
if (suggestions != null && !suggestions.isEmpty()) {
message += GraphQLBundle.message("graphql.validation.did.you.mean.0", formatSuggestions(suggestions));
createFixes.accept(suggestions);
}
}
else {
// no type info available from the parent
message += GraphQLBundle.message("graphql.validation.parent.selection.or.operation.does.not.resolve.to.a.valid.schema.type");
}
}
else if (parent instanceof GraphQLFragmentSpread) {
message = GraphQLBundle.message("graphql.validation.unknown.fragment.spread.0", element.getText());
}
else if (parent instanceof GraphQLArgument) {
message = GraphQLBundle.message("graphql.validation.unknown.argument.0", element.getText());
if (typeScope != null) {
final List<String> suggestions = getArgumentNameSuggestions(element);
if (!suggestions.isEmpty()) {
message += GraphQLBundle.message("graphql.validation.did.you.mean.0", formatSuggestions(suggestions));
createFixes.accept(suggestions);
}
}
}
else if (parent instanceof GraphQLDirective) {
message = GraphQLBundle.message("graphql.validation.unknown.directive.0", element.getText());
}
else if (parent instanceof GraphQLObjectField) {
message = GraphQLBundle.message("graphql.validation.unknown.field.0", element.getText());
if (typeScope != null) {
message += " " + GraphQLBundle.message("graphql.validation.on.input.type.0", GraphQLSchemaUtil.getTypeName(typeScope));
final List<String> suggestions = getFieldNameSuggestions(element.getText(), typeScope);
if (suggestions != null && !suggestions.isEmpty()) {
message += GraphQLBundle.message("graphql.validation.did.you.mean.0", formatSuggestions(suggestions));
createFixes.accept(suggestions);
}
}
}
else if (parent instanceof GraphQLTypeName) {
message = GraphQLBundle.message("graphql.validation.unknown.type.0", element.getText());
fixes.addAll(GraphQLMissingTypeFix.getApplicableFixes((GraphQLIdentifier)element));
}
if (message == null) {
return;
}
String finalMessage = message;
createAnnotation(annotationHolder, element, message, GraphQLUnresolvedReferenceInspection.class, builder -> {
builder = builder.highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
if (!fixes.isEmpty()) {
final InspectionManager inspectionManager = InspectionManager.getInstance(project);
final ProblemDescriptor problemDescriptor = inspectionManager.createProblemDescriptor(
element,
element,
finalMessage,
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL,
true,
LocalQuickFix.EMPTY_ARRAY
);
for (LocalQuickFix fix : fixes) {
builder = builder.newLocalQuickFix(fix, problemDescriptor).registerFix();
}
}
return builder;
});
}