KotlinSpringComponentScanInspection made to support platform JamReferenceContributor
This commit is contained in:
committed by
Nikolay Krasko
parent
0cad41bb0c
commit
79abc8743e
+38
-15
@@ -1,34 +1,57 @@
|
|||||||
package org.jetbrains.kotlin.idea.spring.inspections
|
package org.jetbrains.kotlin.idea.spring.inspections
|
||||||
|
|
||||||
|
import com.intellij.codeInspection.ProblemHighlightType
|
||||||
import com.intellij.codeInspection.ProblemsHolder
|
import com.intellij.codeInspection.ProblemsHolder
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.jam.NonPhysicalReferenceWrapper
|
||||||
import com.intellij.openapi.module.ModuleUtilCore
|
|
||||||
import com.intellij.psi.PsiClass
|
|
||||||
import com.intellij.psi.PsiElementVisitor
|
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.asJava.toLightClass
|
||||||
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
|
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.KtClassOrObject
|
||||||
|
import org.jetbrains.kotlin.psi.KtStringTemplateEntry
|
||||||
|
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
|
||||||
import org.jetbrains.kotlin.psi.KtVisitorVoid
|
import org.jetbrains.kotlin.psi.KtVisitorVoid
|
||||||
|
|
||||||
class KotlinSpringComponentScanInspection : AbstractKotlinInspection() {
|
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 {
|
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
|
||||||
return object: KtVisitorVoid() {
|
return object: KtVisitorVoid() {
|
||||||
override fun visitClassOrObject(classOrObject: KtClassOrObject) {
|
override fun visitClassOrObject(classOrObject: KtClassOrObject) {
|
||||||
val module = ModuleUtilCore.findModuleForPsiElement(classOrObject) ?: return
|
|
||||||
val lightClass = classOrObject.toLightClass() ?: return
|
val lightClass = classOrObject.toLightClass() ?: return
|
||||||
val tmpHolder = ProblemsHolder(holder.manager, classOrObject.containingFile, isOnTheFly)
|
val beansPackagesScan = SpringJamUtils.getInstance().getBeansPackagesScan(lightClass)
|
||||||
javaInspection.checkClass(lightClass, tmpHolder, module)
|
.filterIsInstance<SpringComponentScan>()
|
||||||
tmpHolder.resultsArray.registerWithElementsUnwrapped(holder, isOnTheFly)
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user