Spring Support: Automatic configuration by @Import and @ComponentScan ("basePackages"/"basePackageClasses")

#KT-12135 Fixed
 #KT-12139 Fixed
This commit is contained in:
Alexey Sedunov
2016-05-20 17:28:12 +03:00
parent 781a1e0694
commit 076e31c0f8
16 changed files with 131 additions and 0 deletions
+2
View File
@@ -80,7 +80,9 @@
- [`KT-11692`](https://youtrack.jetbrains.com/issue/KT-11692) Support Spring model diagrams for Kotlin classes
- [`KT-12079`](https://youtrack.jetbrains.com/issue/KT-12079) Support "Autowired members defined in invalid Spring bean" inspection on Kotlin declarations
- [`KT-12092`](https://youtrack.jetbrains.com/issue/KT-12092) Implement bean references in @Qualifier annotations
- [`KT-12135`](https://youtrack.jetbrains.com/issue/KT-12135) Automatically configure components based on 'basePackageClasses' attribute of @ComponentScan
- [`KT-12136`](https://youtrack.jetbrains.com/issue/KT-12136) Implement package references inside of string literals
- [`KT-12139`](https://youtrack.jetbrains.com/issue/KT-12139) Support Spring configurations linked via @Import annotation
- [`KT-12278`](https://youtrack.jetbrains.com/issue/KT-12278) Implement Spring @Autowired inspection
- [`KT-12465`](https://youtrack.jetbrains.com/issue/KT-12465) Implement Spring @ComponentScan inspection
@@ -87,6 +87,13 @@ class KtLightAnnotation(
override fun getValue() = delegate.value
}
inner class LightClassLiteral(
delegate: PsiClassObjectAccessExpression
) : LightExpressionValue<PsiClassObjectAccessExpression>(delegate), PsiClassObjectAccessExpression {
override fun getType() = delegate.type
override fun getOperand(): PsiTypeElement = delegate.operand
}
inner class LightArrayInitializerValue(private val delegate: PsiArrayInitializerMemberValue) : PsiArrayInitializerMemberValue by delegate {
private val _initializers by lazy(LazyThreadSafetyMode.PUBLICATION) { delegate.initializers.map { wrapAnnotationValue(it) }.toTypedArray() }
@@ -97,6 +104,7 @@ class KtLightAnnotation(
private fun wrapAnnotationValue(value: PsiAnnotationMemberValue): PsiAnnotationMemberValue {
return when {
value is PsiLiteralExpression && value.value is String -> LightStringLiteral(value)
value is PsiClassObjectAccessExpression -> LightClassLiteral(value)
value is PsiExpression -> LightExpressionValue(value)
value is PsiArrayInitializerMemberValue -> LightArrayInitializerValue(value)
else -> value
@@ -0,0 +1,8 @@
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import foo.FooBean
import bar.BarBean
@ComponentScan(basePackageClasses = arrayOf(FooBean::class, BarBean::class))
@Configuration
open class Config
@@ -0,0 +1,8 @@
package bar
import org.springframework.stereotype.Component
@Component
class BarBean {
}
@@ -0,0 +1,8 @@
{
springConfig: ["Config.kt"],
file: "foo/beans.kt",
icon: "SpringJavaBean",
tooltip: "Navigate to the spring bean declaration(s)",
naming: "generic",
targets: ["Config"]
}
@@ -0,0 +1,8 @@
package foo
import org.springframework.stereotype.Component
@Component
class Foo<caret>Bean {
}
@@ -0,0 +1,6 @@
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
@ComponentScan(basePackages = arrayOf("foo", "bar"))
@Configuration
open class Config
@@ -0,0 +1,8 @@
package bar
import org.springframework.stereotype.Component
@Component
class BarBean {
}
@@ -0,0 +1,8 @@
{
springConfig: ["Config.kt"],
file: "foo/beans.kt",
icon: "SpringJavaBean",
tooltip: "Navigate to the spring bean declaration(s)",
naming: "generic",
targets: ["Config"]
}
@@ -0,0 +1,8 @@
package foo
import org.springframework.stereotype.Component
@Component
class Foo<caret>Bean {
}
@@ -0,0 +1,7 @@
import org.springframework.context.annotation.Import
import org.springframework.context.annotation.Configuration
import baz.Config2
@Configuration
@Import(Config2::class)
open class Config
@@ -0,0 +1,8 @@
package bar
import org.springframework.stereotype.Component
@Component
class BarBean {
}
@@ -0,0 +1,10 @@
package baz
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import foo.FooBean
import bar.BarBean
@ComponentScan(basePackageClasses = arrayOf(FooBean::class, BarBean::class))
@Configuration
open class Config2
@@ -0,0 +1,8 @@
package foo
import org.springframework.stereotype.Component
@Component
class Foo<caret>Bean {
}
@@ -0,0 +1,8 @@
{
springConfig: ["Config.kt"],
file: "foo/beans.kt",
icon: "SpringJavaBean",
tooltip: "Navigate to the spring bean declaration(s)",
naming: "generic",
targets: []
}
@@ -71,6 +71,18 @@ public class SpringClassAnnotatorTestGenerated extends AbstractSpringClassAnnota
doTest(fileName);
}
@TestMetadata("componentScanWithBasePackageClasses/componentScanWithBasePackageClasses.test")
public void testComponentScanWithBasePackageClasses_ComponentScanWithBasePackageClasses() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/gutter/componentScanWithBasePackageClasses/componentScanWithBasePackageClasses.test");
doTest(fileName);
}
@TestMetadata("componentScanWithBasePackages/componentScanWithBasePackages.test")
public void testComponentScanWithBasePackages_ComponentScanWithBasePackages() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/gutter/componentScanWithBasePackages/componentScanWithBasePackages.test");
doTest(fileName);
}
@TestMetadata("contextBeanInjectionPoints/contextBeanInjectionPoints.test")
public void testContextBeanInjectionPoints_ContextBeanInjectionPoints() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/gutter/contextBeanInjectionPoints/contextBeanInjectionPoints.test");
@@ -83,6 +95,12 @@ public class SpringClassAnnotatorTestGenerated extends AbstractSpringClassAnnota
doTest(fileName);
}
@TestMetadata("importConfigClasses/importConfigClasses.test")
public void testImportConfigClasses_ImportConfigClasses() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/gutter/importConfigClasses/importConfigClasses.test");
doTest(fileName);
}
@TestMetadata("innerBean/innerBean.test")
public void testInnerBean_InnerBean() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/gutter/innerBean/innerBean.test");