void (@NotNull PsiProvidesStatement statement, @NotNull PsiFile file, @NotNull Consumer<? super HighlightInfo.Builder> errorSink) { PsiReferenceList implRefList = statement.getImplementationList(); if (implRefList == null) return; PsiJavaCodeReferenceElement intRef = statement.getInterfaceReference(); PsiElement intTarget = intRef != null ? intRef.resolve() : null; Set<String> filter = new HashSet<>(); for (PsiJavaCodeReferenceElement implRef : implRefList.getReferenceElements()) { String refText = implRef.getQualifiedName(); if (!filter.add(refText)) { String message = JavaErrorBundle.message("module.duplicate.impl", refText); HighlightInfo.Builder info = createDuplicateReference(implRef, message); errorSink.accept(info); continue; } if (!(intTarget instanceof PsiClass)) continue; PsiElement implTarget = implRef.resolve(); if (implTarget instanceof PsiClass implClass) { if (ModuleUtilCore.findModuleForFile(file) != ModuleUtilCore.findModuleForFile(implClass.getContainingFile())) { String message = JavaErrorBundle.message("module.service.alien"); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message); errorSink.accept(info); } PsiMethod provider = ContainerUtil.find( implClass.findMethodsByName("provider", false), m -> m.hasModifierProperty(PsiModifier.PUBLIC) && m.hasModifierProperty(PsiModifier.STATIC) && m.getParameterList().isEmpty()); if (provider != null) { PsiType type = provider.getReturnType(); PsiClass typeClass = type instanceof PsiClassType ? ((PsiClassType)type).resolve() : null; if (!InheritanceUtil.isInheritorOrSelf(typeClass, (PsiClass)intTarget, true)) { String message = JavaErrorBundle.message("module.service.provider.type", implClass.getName()); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message); errorSink.accept(info); } } else if (InheritanceUtil.isInheritorOrSelf(implClass, (PsiClass)intTarget, true)) { if (implClass.hasModifierProperty(PsiModifier.ABSTRACT)) { String message = JavaErrorBundle.message("module.service.abstract", implClass.getName()); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message); errorSink.accept(info); } else if (!(ClassUtil.isTopLevelClass(implClass) || implClass.hasModifierProperty(PsiModifier.STATIC))) { String message = JavaErrorBundle.message("module.service.inner", implClass.getName()); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message); errorSink.accept(info); } else if (!PsiUtil.hasDefaultConstructor(implClass)) { String message = JavaErrorBundle.message("module.service.no.ctor", implClass.getName()); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message); errorSink.accept(info); } } else { String message = JavaErrorBundle.message("module.service.impl"); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message); PsiClassType type = JavaPsiFacade.getElementFactory(file.getProject()).createType((PsiClass)intTarget); IntentionAction action = QuickFixFactory.getInstance().createExtendsListFix(implClass, type, true); info.registerFix(action, null, null, null, null); errorSink.accept(info); } } } }