Spring Support: Implement Spring @Autowired inspection

#KT-12278 Fixed
 #KT-12147 Fixed
 #KT-12366 Fixed
 #KT-12122 Fixed
This commit is contained in:
Alexey Sedunov
2016-05-17 18:19:46 +03:00
parent 36f3d30250
commit 85d07e5f6d
31 changed files with 820 additions and 129 deletions
@@ -0,0 +1,60 @@
// 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
open class AmbiguousConstructors
// Not reported if there is only one constructor
@Component
open class SingleConstructor1(n: Int)
@Component
open class SingleConstructor2 {
constructor(n: Int)
}
// Not reported if no-arg constructor is present
@Component
open class NoArgConstructor1() {
constructor(n: Int): this()
constructor(s: String): this()
}
@Component
open class NoArgConstructor2 {
constructor()
constructor(n: Int)
constructor(s: String)
}
// Not reported if @Autowired constructor is present
@Component
open class AutowiredConstructor1 {
@Autowired constructor(n: Int)
constructor(s: String)
}
@Component
open class AutowiredConstructor2 @Autowired constructor(n: Int) {
constructor(s: String): this(0)
}
// Reported
@Component
open class AmbigiousConstructor1 {
constructor(n: Int)
constructor(s: String)
}
@Component
open class AmbigiousConstructor2(n: Int) {
constructor(s: String): this(0)
}
@@ -0,0 +1,119 @@
<problems>
<problem>
<file>ambiguousConstructors.kt</file>
<line>52</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/ambiguousConstructors.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Class doesn't contain matching constructor for autowiring</description>
</problem>
<problem>
<file>ambiguousConstructors.kt</file>
<line>58</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/ambiguousConstructors.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Class doesn't contain matching constructor for autowiring</description>
</problem>
<problem>
<file>multipleAutowiredConstructors.kt</file>
<line>30</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/multipleAutowiredConstructors.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Only one constructor can have @Autowired annotation</description>
</problem>
<problem>
<file>multipleAutowiredConstructors.kt</file>
<line>31</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/multipleAutowiredConstructors.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Only one constructor can have @Autowired annotation</description>
</problem>
<problem>
<file>multipleAutowiredConstructors.kt</file>
<line>35</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/multipleAutowiredConstructors.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Only one constructor can have @Autowired annotation</description>
</problem>
<problem>
<file>multipleAutowiredConstructors.kt</file>
<line>36</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/multipleAutowiredConstructors.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Only one constructor can have @Autowired annotation</description>
</problem>
<problem>
<file>parameterlessFunction.kt</file>
<line>15</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/parameterlessFunction.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Autowired method without parameters</description>
</problem>
<problem>
<file>invalidAutowiredResource.kt</file>
<line>24</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/mismatchedType.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Could not autowire. Bean should be of 'invalidAutowiredResource.BarBean' type</description>
</problem>
<problem>
<file>invalidAutowiredResource.kt</file>
<line>31</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/invalidAutowiredResource.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Cannot resolve bean 'fooBeannn'</description>
</problem>
<problem>
<file>invalidAutowiredQualifier.kt</file>
<line>23</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/invalidAutowiredQualifier.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Could not autowire. Qualified bean must be of 'BarBean' type.</description>
</problem>
<problem>
<file>invalidAutowiredQualifier.kt</file>
<line>30</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/invalidAutowiredQualifier.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Cannot find bean with qualifier 'fooBeannn'</description>
</problem>
<problem>
<file>invalidAutowiredQualifier.kt</file>
<line>37</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/invalidAutowiredQualifier.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Cannot find bean qualified with @Qualifier</description>
</problem>
<problem>
<file>invalidAutowiredByType.kt</file>
<line>23</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/invalidAutowiredByType.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>Could not autowire. No beans of 'String' type found.</description>
</problem>
<problem>
<file>invalidAutowiredByType.kt</file>
<line>29</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/invalidAutowiredByType.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Autowiring for Bean Class (Kotlin)</problem_class>
<description>&lt;html&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Could not autowire. There is more than one bean of 'AbstractBarBean' type.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;table&gt;&lt;tr&gt;&lt;td valign='top'&gt;Beans:&lt;/td&gt;&lt;td&gt;abstractBarBean&amp;nbsp;&amp;nbsp; (invalidAutowiredByType.kt)&lt;br&gt;barBean1&amp;nbsp;&amp;nbsp; (invalidAutowiredByType.kt)&lt;br&gt;barBean2&amp;nbsp;&amp;nbsp; (invalidAutowiredByType.kt)&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/html&gt;</description>
</problem>
</problems>
@@ -0,0 +1,3 @@
// INSPECTION_CLASS: org.jetbrains.kotlin.idea.spring.inspections.SpringKotlinAutowiringInspection
// FIXTURE_CLASS: org.jetbrains.kotlin.idea.spring.tests.SpringTestFixtureExtension
// CONFIGURE_SPRING_FILE_SET
@@ -0,0 +1,30 @@
// 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
import org.springframework.beans.factory.annotation.Qualifier
@Configuration
@ComponentScan
open class InvalidAutowiredByTypeQualifiers
abstract class AbstractBarBean
@Component
open class BarBean1 : AbstractBarBean()
@Component
open class BarBean2 : AbstractBarBean()
@Component
open class NoAutowiredCandidates() {
@Autowired
lateinit var bean: String
}
@Component
open class MultipleAutowiredCandidates() {
@Autowired
lateinit var bean: AbstractBarBean
}
@@ -0,0 +1,39 @@
// 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
import org.springframework.beans.factory.annotation.Qualifier
@Configuration
@ComponentScan
open class MismatchedTypes
@Component
open class FooBean
@Component
open class BarBean
@Component
open class MismatchedType() {
@Autowired
@Qualifier("fooBean")
lateinit var bean1: BarBean
}
@Component
open class UnresolvedBeanRef() {
@Autowired
@Qualifier("fooBeannn")
lateinit var bean1: FooBean
}
@Component
open class NamelessQualifier() {
@Autowired
@Qualifier
lateinit var bean1: FooBean
}
@@ -0,0 +1,33 @@
// WITH_RUNTIME
// FULL_JDK
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import javax.annotation.Resource
@Configuration
@ComponentScan
open class MismatchedTypes
@Component
open class FooBean
@Component
open class BarBean
@Component
open class MismatchedType() {
@Autowired
@Resource(name = "fooBean")
lateinit var bean1: BarBean
}
@Component
open class UnresolvedBeanRef() {
@Autowired
@Resource(name = "fooBeannn")
lateinit var bean1: FooBean
}
@@ -0,0 +1,37 @@
// 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
open class MultipleAutowiredConstructors
// Not reported if required == false
@Component
open class NonRequiredAutowired1 {
@Autowired(required = false) constructor(n: Int)
@Autowired constructor(s: String)
}
@Component
open class NonRequiredAutowired2 @Autowired(required = false) constructor(n: Int) {
@Autowired constructor(s: String): this(0)
}
// Reported
@Component
open class BothAutowired1 {
@Autowired constructor(n: Int)
@Autowired constructor(s: String)
}
@Component
open class BothAutowired2 @Autowired constructor(n: Int) {
@Autowired constructor(s: String): this(0)
}
@@ -0,0 +1,16 @@
// 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
open class ParameterlessFunctions
@Component
open class ParameterlessFunction {
@Autowired fun foo() = 1
}
@@ -0,0 +1 @@
org.jetbrains.kotlin.idea.spring.inspections.SpringKotlinAutowiringInspection
@@ -0,0 +1,27 @@
// "Add qualifier" "true"
// FIXTURE_CLASS: org.jetbrains.kotlin.idea.spring.tests.SpringTestFixtureExtension
// CONFIGURE_SPRING_FILE_SET
// WITH_RUNTIME
// DISABLE-ERRORS
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.beans.factory.annotation.Qualifier
@Configuration
@ComponentScan
open class InvalidAutowiredByTypeQualifiers
abstract class BaseBarBean
@Component
open class BarBean1 : BaseBarBean()
@Component
open class BarBean2 : BaseBarBean()
@Component
open class MultipleAutowiredCandidates() {
@Autowired
lateinit var <caret>bean: BaseBarBean
}
@@ -0,0 +1,27 @@
// "Add qualifier" "true"
// FIXTURE_CLASS: org.jetbrains.kotlin.idea.spring.tests.SpringTestFixtureExtension
// CONFIGURE_SPRING_FILE_SET
// WITH_RUNTIME
// DISABLE-ERRORS
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.beans.factory.annotation.Qualifier
@Configuration
@ComponentScan
open class InvalidAutowiredByTypeQualifiers
abstract class BaseBarBean
@Component
open class BarBean1 : BaseBarBean()
@Component
open class BarBean2 : BaseBarBean()
@Component
open class MultipleAutowiredCandidates() {
@Qualifier("barBean1") @Autowired
lateinit var bean: BaseBarBean
}