From 79abc8743e1609791bf4cfdfb47f4ce39f9c3296 Mon Sep 17 00:00:00 2001 From: Nicolay Mitropolsky Date: Wed, 29 Nov 2017 21:19:20 +0300 Subject: [PATCH] `KotlinSpringComponentScanInspection` made to support platform `JamReferenceContributor` --- .../KotlinSpringComponentScanInspection.kt | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/ultimate/src/org/jetbrains/kotlin/idea/spring/inspections/KotlinSpringComponentScanInspection.kt b/ultimate/src/org/jetbrains/kotlin/idea/spring/inspections/KotlinSpringComponentScanInspection.kt index 75aa7228848..8c63dd9ff1f 100644 --- a/ultimate/src/org/jetbrains/kotlin/idea/spring/inspections/KotlinSpringComponentScanInspection.kt +++ b/ultimate/src/org/jetbrains/kotlin/idea/spring/inspections/KotlinSpringComponentScanInspection.kt @@ -1,34 +1,57 @@ package org.jetbrains.kotlin.idea.spring.inspections +import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemsHolder -import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleUtilCore -import com.intellij.psi.PsiClass +import com.intellij.jam.NonPhysicalReferenceWrapper import com.intellij.psi.PsiElementVisitor -import com.intellij.spring.model.highlighting.jam.SpringComponentScanInspection +import com.intellij.psi.PsiReference +import com.intellij.psi.impl.source.resolve.reference.impl.providers.PsiPackageReference +import com.intellij.spring.model.jam.stereotype.SpringComponentScan +import com.intellij.spring.model.jam.utils.SpringJamUtils +import org.jetbrains.kotlin.asJava.elements.KtLightAnnotationForSourceEntry import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection -import org.jetbrains.kotlin.idea.inspections.registerWithElementsUnwrapped import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtStringTemplateEntry +import org.jetbrains.kotlin.psi.KtTreeVisitorVoid import org.jetbrains.kotlin.psi.KtVisitorVoid class KotlinSpringComponentScanInspection : AbstractKotlinInspection() { - private val javaInspection by lazy { - object : SpringComponentScanInspection() { - // make base method visible - override public fun checkClass(aClass: PsiClass, holder: ProblemsHolder, module: Module) = super.checkClass(aClass, holder, module) - } - } override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { return object: KtVisitorVoid() { override fun visitClassOrObject(classOrObject: KtClassOrObject) { - val module = ModuleUtilCore.findModuleForPsiElement(classOrObject) ?: return val lightClass = classOrObject.toLightClass() ?: return - val tmpHolder = ProblemsHolder(holder.manager, classOrObject.containingFile, isOnTheFly) - javaInspection.checkClass(lightClass, tmpHolder, module) - tmpHolder.resultsArray.registerWithElementsUnwrapped(holder, isOnTheFly) + val beansPackagesScan = SpringJamUtils.getInstance().getBeansPackagesScan(lightClass) + .filterIsInstance() + val kotlinAnnotations = beansPackagesScan + .mapNotNull { (it.annotation as? KtLightAnnotationForSourceEntry)?.kotlinOrigin } + if (kotlinAnnotations.isEmpty()) return + val literalVisitor = PsiPackageReferenceChecker(holder) + for (kotlinAnnotation in kotlinAnnotations) { + kotlinAnnotation.accept(literalVisitor) + } } } } + + private class PsiPackageReferenceChecker(private val holder: ProblemsHolder) : KtTreeVisitorVoid() { + override fun visitStringTemplateEntry(entry: KtStringTemplateEntry) { + for (reference in entry.references) { + val packageReference = psiPackageReference(reference) ?: continue + if (packageReference.multiResolve(false).isEmpty()) { + holder.registerProblem(reference, //registering on physical reference + ProblemsHolder.unresolvedReferenceMessage(packageReference), //but getting message from logical reference + ProblemHighlightType.LIKE_UNKNOWN_SYMBOL) + } + } + } + + private fun psiPackageReference(reference: PsiReference): PsiPackageReference? = when (reference) { + is PsiPackageReference -> reference + is NonPhysicalReferenceWrapper -> psiPackageReference(reference.wrappedReference) + else -> null + } + } + } \ No newline at end of file