diff --git a/ultimate/resources/inspectionDescriptions/KotlinSpringComponentScan.html b/ultimate/resources/inspectionDescriptions/KotlinSpringComponentScan.html
new file mode 100644
index 00000000000..cec04e3e970
--- /dev/null
+++ b/ultimate/resources/inspectionDescriptions/KotlinSpringComponentScan.html
@@ -0,0 +1,7 @@
+
+
+Checks @ComponentScan (and similar annotations) for setup errors.
+
+
+
+
\ No newline at end of file
diff --git a/ultimate/src/org/jetbrains/kotlin/idea/spring/inspections/KotlinSpringComponentScanInspection.kt b/ultimate/src/org/jetbrains/kotlin/idea/spring/inspections/KotlinSpringComponentScanInspection.kt
new file mode 100644
index 00000000000..75aa7228848
--- /dev/null
+++ b/ultimate/src/org/jetbrains/kotlin/idea/spring/inspections/KotlinSpringComponentScanInspection.kt
@@ -0,0 +1,34 @@
+package org.jetbrains.kotlin.idea.spring.inspections
+
+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.psi.PsiElementVisitor
+import com.intellij.spring.model.highlighting.jam.SpringComponentScanInspection
+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.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)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ultimate/testData/inspections/spring/componentScan/foo/beans.kt b/ultimate/testData/inspections/spring/componentScan/foo/beans.kt
new file mode 100644
index 00000000000..82874a1ce6f
--- /dev/null
+++ b/ultimate/testData/inspections/spring/componentScan/foo/beans.kt
@@ -0,0 +1,6 @@
+package foo
+
+// Make PsiPackage not empty
+fun dummyFun() {
+
+}
\ No newline at end of file
diff --git a/ultimate/testData/inspections/spring/componentScan/inspectionData/expected.xml b/ultimate/testData/inspections/spring/componentScan/inspectionData/expected.xml
new file mode 100644
index 00000000000..5fb321c5795
--- /dev/null
+++ b/ultimate/testData/inspections/spring/componentScan/inspectionData/expected.xml
@@ -0,0 +1,18 @@
+
+
+ test.kt
+ 14
+ light_idea_test_case
+
+ @ComponentScan setup (Kotlin)
+ Cannot resolve package bar
+
+
+ test.kt
+ 18
+ light_idea_test_case
+
+ @ComponentScan setup (Kotlin)
+ Cannot resolve package bar
+
+
diff --git a/ultimate/testData/inspections/spring/componentScan/inspectionData/inspections.test b/ultimate/testData/inspections/spring/componentScan/inspectionData/inspections.test
new file mode 100644
index 00000000000..bfa89cff534
--- /dev/null
+++ b/ultimate/testData/inspections/spring/componentScan/inspectionData/inspections.test
@@ -0,0 +1,3 @@
+// INSPECTION_CLASS: org.jetbrains.kotlin.idea.spring.inspections.KotlinSpringComponentScanInspection
+// FIXTURE_CLASS: org.jetbrains.kotlin.idea.spring.tests.SpringTestFixtureExtension
+// CONFIGURE_SPRING_FILE_SET
\ No newline at end of file
diff --git a/ultimate/testData/inspections/spring/componentScan/test.kt b/ultimate/testData/inspections/spring/componentScan/test.kt
new file mode 100644
index 00000000000..bc23e390234
--- /dev/null
+++ b/ultimate/testData/inspections/spring/componentScan/test.kt
@@ -0,0 +1,19 @@
+
+// WITH_RUNTIME
+
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Component
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.context.annotation.Configuration
+
+@Configuration
+@ComponentScan(basePackages = arrayOf("foo"))
+open class App1
+
+@Configuration
+@ComponentScan(basePackages = arrayOf("foo", "bar"))
+open class App2
+
+@Configuration
+@ComponentScan(basePackages = arrayOf("bar"))
+open class App3
\ No newline at end of file
diff --git a/ultimate/tests/org/jetbrains/kotlin/idea/spring/tests/inspections/SpringInspectionTestGenerated.java b/ultimate/tests/org/jetbrains/kotlin/idea/spring/tests/inspections/SpringInspectionTestGenerated.java
index 96846678af9..c9649b60772 100644
--- a/ultimate/tests/org/jetbrains/kotlin/idea/spring/tests/inspections/SpringInspectionTestGenerated.java
+++ b/ultimate/tests/org/jetbrains/kotlin/idea/spring/tests/inspections/SpringInspectionTestGenerated.java
@@ -47,6 +47,12 @@ public class SpringInspectionTestGenerated extends AbstractSpringInspectionTest
doTest(fileName);
}
+ @TestMetadata("componentScan/inspectionData/inspections.test")
+ public void testComponentScan_inspectionData_Inspections_test() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/inspections/spring/componentScan/inspectionData/inspections.test");
+ doTest(fileName);
+ }
+
@TestMetadata("finalSpringAnnotatedDeclaration/inspectionData/inspections.test")
public void testFinalSpringAnnotatedDeclaration_inspectionData_Inspections_test() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/inspections/spring/finalSpringAnnotatedDeclaration/inspectionData/inspections.test");