Spring Support: Implement bean references in @Qualifier annotations
#KT-12092 Fixed
This commit is contained in:
@@ -23,6 +23,7 @@ New features:
|
|||||||
- [KT-11807](https://youtrack.jetbrains.com/issue/KT-11807) Use function body template when generating overriding functions with default body
|
- [KT-11807](https://youtrack.jetbrains.com/issue/KT-11807) Use function body template when generating overriding functions with default body
|
||||||
- [KT-12079](https://youtrack.jetbrains.com/issue/KT-12079) Support "Autowired members defined in invalid Spring bean" inspection on Kotlin declarations
|
- [KT-12079](https://youtrack.jetbrains.com/issue/KT-12079) Support "Autowired members defined in invalid Spring bean" inspection on Kotlin declarations
|
||||||
- [KT-11704](https://youtrack.jetbrains.com/issue/KT-11704) Support file path references inside of Kotlin string literals
|
- [KT-11704](https://youtrack.jetbrains.com/issue/KT-11704) Support file path references inside of Kotlin string literals
|
||||||
|
- [KT-12092](https://youtrack.jetbrains.com/issue/KT-12092) Implement bean references in @Qualifier annotations
|
||||||
|
|
||||||
Issues fixed:
|
Issues fixed:
|
||||||
|
|
||||||
|
|||||||
@@ -132,10 +132,14 @@ private fun isNonAbstractMember(member: KtDeclaration?): Boolean {
|
|||||||
private val DEFAULT_IMPLS_CLASS_NAME = Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME)
|
private val DEFAULT_IMPLS_CLASS_NAME = Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME)
|
||||||
fun FqName.defaultImplsChild() = child(DEFAULT_IMPLS_CLASS_NAME)
|
fun FqName.defaultImplsChild() = child(DEFAULT_IMPLS_CLASS_NAME)
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
fun KtAnnotationEntry.toLightAnnotation(): PsiAnnotation? {
|
fun KtAnnotationEntry.toLightAnnotation(): PsiAnnotation? {
|
||||||
val ktDeclaration = getStrictParentOfType<KtModifierList>()?.parent as? KtDeclaration ?: return null
|
val ktDeclaration = getStrictParentOfType<KtModifierList>()?.parent as? KtDeclaration ?: return null
|
||||||
val lightElement = ktDeclaration.toLightElements().firstOrNull() as? PsiModifierListOwner ?: return null
|
for (lightElement in ktDeclaration.toLightElements()) {
|
||||||
return lightElement.modifierList?.annotations?.firstOrNull { it is KtLightAnnotation && it.kotlinOrigin == this }
|
if (lightElement !is PsiModifierListOwner) continue
|
||||||
|
lightElement.modifierList?.annotations?.firstOrNull { it is KtLightAnnotation && it.kotlinOrigin == this }?.let { return it }
|
||||||
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun propertyNameByAccessor(name: String, accessor: KtLightMethod): String? {
|
fun propertyNameByAccessor(name: String, accessor: KtLightMethod): String? {
|
||||||
|
|||||||
@@ -54,8 +54,11 @@ public final class NavigationTestUtils {
|
|||||||
List<String> expectedReferences = InTextDirectivesUtils.findListWithPrefixes(editor.getDocument().getText(), "// REF:");
|
List<String> expectedReferences = InTextDirectivesUtils.findListWithPrefixes(editor.getDocument().getText(), "// REF:");
|
||||||
for (int i = 0; i < expectedReferences.size(); i++) {
|
for (int i = 0; i < expectedReferences.size(); i++) {
|
||||||
String expectedText = expectedReferences.get(i);
|
String expectedText = expectedReferences.get(i);
|
||||||
if (expectedText.startsWith("<")) continue;
|
expectedText = expectedText.replace("\\n", "\n");
|
||||||
expectedReferences.set(i, PathUtil.toSystemDependentName(expectedText).replace("//", "/"));
|
if (!expectedText.startsWith("<")) {
|
||||||
|
expectedText = PathUtil.toSystemDependentName(expectedText).replace("//", "/");
|
||||||
|
}
|
||||||
|
expectedReferences.set(i, expectedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.sort(expectedReferences);
|
Collections.sort(expectedReferences);
|
||||||
|
|||||||
+28
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.spring.references
|
|||||||
|
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.psi.PsiReference
|
import com.intellij.psi.PsiReference
|
||||||
|
import com.intellij.psi.PsiReferenceBase
|
||||||
import com.intellij.psi.PsiReferenceRegistrar
|
import com.intellij.psi.PsiReferenceRegistrar
|
||||||
import com.intellij.spring.constants.SpringAnnotationsConstants
|
import com.intellij.spring.constants.SpringAnnotationsConstants
|
||||||
import com.intellij.spring.constants.SpringConstants
|
import com.intellij.spring.constants.SpringConstants
|
||||||
@@ -43,6 +44,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeAsSequence
|
|||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
|
|
||||||
|
// TODO: Use Kotlin patterns
|
||||||
class KotlinSpringReferenceContributor : AbstractKotlinReferenceContributor() {
|
class KotlinSpringReferenceContributor : AbstractKotlinReferenceContributor() {
|
||||||
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
|
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
|
||||||
registrar.registerProvider<KtStringTemplateExpression> {
|
registrar.registerProvider<KtStringTemplateExpression> {
|
||||||
@@ -125,5 +127,31 @@ class KotlinSpringReferenceContributor : AbstractKotlinReferenceContributor() {
|
|||||||
val resourcesBuilder = SpringResourcesBuilder.create(it, content).fromRoot(content.startsWith("/")).soft(false)
|
val resourcesBuilder = SpringResourcesBuilder.create(it, content).fromRoot(content.startsWith("/")).soft(false)
|
||||||
SpringResourcesUtil.getInstance().getClassPathReferences(resourcesBuilder)
|
SpringResourcesUtil.getInstance().getClassPathReferences(resourcesBuilder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registrar.registerProvider<KtStringTemplateExpression>(PsiReferenceRegistrar.HIGHER_PRIORITY) {
|
||||||
|
if (!it.isPlain()) return@registerProvider null
|
||||||
|
|
||||||
|
val argument = it.parent as? KtValueArgument ?: return@registerProvider null
|
||||||
|
val argumentName = argument.getArgumentName()
|
||||||
|
if (argumentName != null && argumentName.asName.asString() != "value") return@registerProvider null
|
||||||
|
|
||||||
|
val entry = argument.getStrictParentOfType<KtAnnotationEntry>() ?: return@registerProvider null
|
||||||
|
val bindingContext = entry.analyze(BodyResolveMode.PARTIAL)
|
||||||
|
val resolvedCall = entry.getResolvedCall(bindingContext) ?: return@registerProvider null
|
||||||
|
val annotation = (resolvedCall.resultingDescriptor as? ConstructorDescriptor)?.containingDeclaration
|
||||||
|
?: return@registerProvider null
|
||||||
|
if (annotation.importableFqName?.asString() != SpringAnnotationsConstants.QUALIFIER) return@registerProvider null
|
||||||
|
|
||||||
|
val annotated = entry.getStrictParentOfType<KtModifierListOwner>() ?: return@registerProvider null
|
||||||
|
if (annotated is KtClassOrObject) {
|
||||||
|
object : PsiReferenceBase<KtStringTemplateExpression>(it) {
|
||||||
|
override fun resolve() = entry
|
||||||
|
override fun getVariants(): Array<Any> = arrayOf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
KtSpringQualifierReference(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+104
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.spring.references
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.spring.model.DefaultSpringBeanQualifier
|
||||||
|
import com.intellij.spring.model.converters.SpringConverterUtil
|
||||||
|
import com.intellij.spring.model.highlighting.SpringAutowireUtil
|
||||||
|
import com.intellij.spring.model.jam.qualifiers.SpringJamQualifier
|
||||||
|
import com.intellij.spring.model.utils.SpringModelSearchers
|
||||||
|
import org.jetbrains.kotlin.asJava.toLightAnnotation
|
||||||
|
import org.jetbrains.kotlin.asJava.toLightElements
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||||
|
import org.jetbrains.kotlin.idea.spring.springModel
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
// Based on com.intellij.spring.references.SpringQualifierReference
|
||||||
|
class KtSpringQualifierReference(element: KtStringTemplateExpression) : PsiReferenceBase.Poly<KtStringTemplateExpression>(element, false) {
|
||||||
|
private fun getAnnotationFqName(): String? {
|
||||||
|
val annotationEntry = element.getStrictParentOfType<KtAnnotationEntry>() ?: return null
|
||||||
|
val context = annotationEntry.analyze(BodyResolveMode.PARTIAL)
|
||||||
|
val annotationType = context[BindingContext.TYPE, annotationEntry.typeReference] ?: return null
|
||||||
|
return annotationType.constructor.declarationDescriptor?.importableFqName?.asString()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun multiResolve(incompleteCode: Boolean): Array<out ResolveResult> {
|
||||||
|
val annotationEntry = element.getStrictParentOfType<KtAnnotationEntry>() ?: return ResolveResult.EMPTY_ARRAY
|
||||||
|
val lightAnnotation = annotationEntry.toLightAnnotation() ?: return ResolveResult.EMPTY_ARRAY
|
||||||
|
val springModel = element.springModel ?: return ResolveResult.EMPTY_ARRAY
|
||||||
|
|
||||||
|
val results = ArrayList<ResolveResult>()
|
||||||
|
val jamQualifier = SpringJamQualifier(lightAnnotation, null)
|
||||||
|
|
||||||
|
val qualifiedBeans = springModel.findQualifiedBeans(jamQualifier)
|
||||||
|
qualifiedBeans.mapTo(results) { PsiElementResolveResult(it.springBean.springQualifier!!.identifyingPsiElement) }
|
||||||
|
|
||||||
|
val qualifierValue = jamQualifier.qualifierValue
|
||||||
|
if (qualifierValue != null) {
|
||||||
|
val beanPointer = SpringModelSearchers.findBean(springModel, qualifierValue)
|
||||||
|
val psiElement = if (beanPointer != null && beanPointer.isValid) beanPointer.psiElement else null
|
||||||
|
if (psiElement != null) results += PsiElementResolveResult(psiElement)
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.toTypedArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can't get light elements for property in the synthetic completion KtFile, so look for original one instead
|
||||||
|
private fun getOriginalProperty(): KtProperty? {
|
||||||
|
val currentProperty = element.getStrictParentOfType<KtProperty>() ?: return null
|
||||||
|
val originalFile = element.containingFile.originalFile as? KtFile ?: return null
|
||||||
|
return originalFile.findElementAt(currentProperty.startOffset)?.getNonStrictParentOfType<KtProperty>()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getVariants(): Array<out Any> {
|
||||||
|
val annotationFqName = getAnnotationFqName() ?: return LookupElement.EMPTY_ARRAY
|
||||||
|
val springModel = element.springModel ?: return LookupElement.EMPTY_ARRAY
|
||||||
|
val property = getOriginalProperty() ?: return LookupElement.EMPTY_ARRAY
|
||||||
|
val lightElement = property.toLightElements().firstOrNull {
|
||||||
|
it is PsiField || (it is PsiMethod && !it.name.startsWith("set"))
|
||||||
|
}
|
||||||
|
val expectedPsiType = when (lightElement) {
|
||||||
|
is PsiMethod -> lightElement.returnType
|
||||||
|
is PsiField -> lightElement.type
|
||||||
|
else -> null
|
||||||
|
} ?: return LookupElement.EMPTY_ARRAY
|
||||||
|
return SpringAutowireUtil
|
||||||
|
.autowireByType(springModel, expectedPsiType)
|
||||||
|
.mapNotNull {
|
||||||
|
val qualifier = it.springBean.springQualifier
|
||||||
|
val value = qualifier?.qualifierValue
|
||||||
|
when {
|
||||||
|
qualifier == null ->
|
||||||
|
SpringConverterUtil.createCompletionVariant(it)
|
||||||
|
value != null && (qualifier is DefaultSpringBeanQualifier || qualifier.qualifierType?.qualifiedName == annotationFqName) ->
|
||||||
|
SpringConverterUtil.createCompletionVariant(it, value)
|
||||||
|
else ->
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.toTypedArray()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,8 +18,11 @@ package org.jetbrains.kotlin.idea.spring
|
|||||||
|
|
||||||
import com.intellij.codeInsight.AnnotationUtil
|
import com.intellij.codeInsight.AnnotationUtil
|
||||||
import com.intellij.openapi.module.ModuleUtilCore
|
import com.intellij.openapi.module.ModuleUtilCore
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiModifierListOwner
|
import com.intellij.psi.PsiModifierListOwner
|
||||||
|
import com.intellij.spring.CommonSpringModel
|
||||||
import com.intellij.spring.model.jam.utils.JamAnnotationTypeUtil
|
import com.intellij.spring.model.jam.utils.JamAnnotationTypeUtil
|
||||||
|
import com.intellij.spring.model.utils.SpringModelUtils
|
||||||
|
|
||||||
internal fun PsiModifierListOwner.isAnnotatedWith(annotationFqName: String): Boolean {
|
internal fun PsiModifierListOwner.isAnnotatedWith(annotationFqName: String): Boolean {
|
||||||
val module = ModuleUtilCore.findModuleForPsiElement(this) ?: return false
|
val module = ModuleUtilCore.findModuleForPsiElement(this) ?: return false
|
||||||
@@ -28,3 +31,6 @@ internal fun PsiModifierListOwner.isAnnotatedWith(annotationFqName: String): Boo
|
|||||||
.mapNotNull { it.qualifiedName }
|
.mapNotNull { it.qualifiedName }
|
||||||
.any { AnnotationUtil.isAnnotated(this, it, true) }
|
.any { AnnotationUtil.isAnnotated(this, it, true) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val PsiElement.springModel: CommonSpringModel?
|
||||||
|
get() = SpringModelUtils.getInstance().getSpringModel(this)
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// ELEMENT: existingBean1
|
||||||
|
// CHAR: \n
|
||||||
|
package bean
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
|
|
||||||
|
class MultiHolder(var thing: String)
|
||||||
|
|
||||||
|
class AutoMultiUser() {
|
||||||
|
@Qualifier("exist<caret>ing") @Autowired lateinit var multi1: MultiHolder
|
||||||
|
}
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// ELEMENT: existingBean1
|
||||||
|
// CHAR: \n
|
||||||
|
package bean
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
|
|
||||||
|
class MultiHolder(var thing: String)
|
||||||
|
|
||||||
|
class AutoMultiUser() {
|
||||||
|
@Qualifier("existingBean1ing") @Autowired lateinit var multi1: MultiHolder
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// ELEMENT: existingBean1
|
||||||
|
// CHAR: \t
|
||||||
|
package bean
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
|
|
||||||
|
class MultiHolder(var thing: String)
|
||||||
|
|
||||||
|
class AutoMultiUser() {
|
||||||
|
@Qualifier("exist<caret>ing") @Autowired lateinit var multi1: MultiHolder
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// ELEMENT: existingBean1
|
||||||
|
// CHAR: \t
|
||||||
|
package bean
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
|
|
||||||
|
class MultiHolder(var thing: String)
|
||||||
|
|
||||||
|
class AutoMultiUser() {
|
||||||
|
@Qualifier("existingBean1") @Autowired lateinit var multi1: MultiHolder
|
||||||
|
}
|
||||||
+12
@@ -4,4 +4,16 @@
|
|||||||
<bean id="fooBean" class="java.lang.String"/>
|
<bean id="fooBean" class="java.lang.String"/>
|
||||||
<bean id="barBean" class="java.lang.String"/>
|
<bean id="barBean" class="java.lang.String"/>
|
||||||
<bean id="scopedBean" class="test.ScopedBean"/>
|
<bean id="scopedBean" class="test.ScopedBean"/>
|
||||||
|
|
||||||
|
<bean class="bean.MultiHolder" name="existingBean1">
|
||||||
|
<constructor-arg name="thing" value="1"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="bean.MultiHolder" name="existingBean2">
|
||||||
|
<constructor-arg name="thing" value="2"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="bean.MultiHolder" name="anotherBean">
|
||||||
|
<constructor-arg name="thing" value="0"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="bean.AutoMultiUser" name="existingBean3">
|
||||||
|
</bean>
|
||||||
</beans>
|
</beans>
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||||
|
<bean class="bean.MultiHolder" name="existingBean1">
|
||||||
|
<constructor-arg name="thing" value="1"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="bean.MultiHolder" name="existingBean2">
|
||||||
|
<constructor-arg name="thing" value="2"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="bean.MultiHolder" name="anotherBean">
|
||||||
|
<constructor-arg name="thing" value="0"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="bean.AutoMultiUser" name="existingBean3">
|
||||||
|
</bean>
|
||||||
|
</beans>
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// NUMBER: 3
|
||||||
|
// EXIST: { lookupString:"anotherBean" }
|
||||||
|
// EXIST: { lookupString:"existingBean1" }
|
||||||
|
// EXIST: { lookupString:"existingBean2" }
|
||||||
|
|
||||||
|
package bean
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
|
|
||||||
|
class MultiHolder(var thing: String)
|
||||||
|
|
||||||
|
class AutoMultiUser() {
|
||||||
|
@Qualifier("<caret>existingBean1") @Autowired lateinit var multi1: MultiHolder
|
||||||
|
}
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||||
|
<bean class="bean.MultiHolder" name="existingBean1">
|
||||||
|
<constructor-arg name="thing" value="1"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="bean.MultiHolder" name="existingBean2">
|
||||||
|
<constructor-arg name="thing" value="2"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="bean.MultiHolder" name="anotherBean">
|
||||||
|
<constructor-arg name="thing" value="0"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="bean.AutoMultiUser" name="existingBean3">
|
||||||
|
</bean>
|
||||||
|
</beans>
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// NUMBER: 2
|
||||||
|
// EXIST: { lookupString:"existingBean1" }
|
||||||
|
// EXIST: { lookupString:"existingBean2" }
|
||||||
|
|
||||||
|
package bean
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
|
|
||||||
|
class MultiHolder(var thing: String)
|
||||||
|
|
||||||
|
class AutoMultiUser() {
|
||||||
|
@Qualifier("existing<caret>Bean2") @Autowired lateinit var multi2: MultiHolder
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// REF: <bean class="bean.MultiHolder" name="existingBean1">\n <constructor-arg name="thing" value="1"/>\n </bean>
|
||||||
|
package bean
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
|
|
||||||
|
class MultiHolder(var thing: String)
|
||||||
|
|
||||||
|
class AutoMultiUser() {
|
||||||
|
@Qualifier("<caret>existingBean1") @Autowired lateinit var multi1: MultiHolder
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||||
|
<bean class="bean.MultiHolder" name="existingBean1">
|
||||||
|
<constructor-arg name="thing" value="1"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="bean.MultiHolder" name="existingBean2">
|
||||||
|
<constructor-arg name="thing" value="2"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="bean.MultiHolder" name="anotherBean">
|
||||||
|
<constructor-arg name="thing" value="0"/>
|
||||||
|
</bean>
|
||||||
|
<bean class="bean.AutoMultiUser" name="existingBean3">
|
||||||
|
</bean>
|
||||||
|
</beans>
|
||||||
+12
@@ -35,6 +35,18 @@ public class SpringReferenceCompletionHandlerTestGenerated extends AbstractSprin
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("ultimate/testData/spring/core/references/completion/handler"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("ultimate/testData/spring/core/references/completion/handler"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifierReferenceEnter.kt")
|
||||||
|
public void testQualifierReferenceEnter() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/references/completion/handler/qualifierReferenceEnter.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifierReferenceTab.kt")
|
||||||
|
public void testQualifierReferenceTab() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/references/completion/handler/qualifierReferenceTab.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("scopeReference.kt")
|
@TestMetadata("scopeReference.kt")
|
||||||
public void testScopeReference() throws Exception {
|
public void testScopeReference() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/references/completion/handler/scopeReference.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/references/completion/handler/scopeReference.kt");
|
||||||
|
|||||||
+12
@@ -47,6 +47,18 @@ public class SpringReferenceCompletionTestGenerated extends AbstractSpringRefere
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifierReference1Xml.kt")
|
||||||
|
public void testQualifierReference1Xml() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/references/completion/variants/qualifierReference1Xml.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifierReference2Xml.kt")
|
||||||
|
public void testQualifierReference2Xml() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/references/completion/variants/qualifierReference2Xml.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("scopeReferenceXml.kt")
|
@TestMetadata("scopeReferenceXml.kt")
|
||||||
public void testScopeReferenceXml() throws Exception {
|
public void testScopeReferenceXml() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/references/completion/variants/scopeReferenceXml.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/references/completion/variants/scopeReferenceXml.kt");
|
||||||
|
|||||||
+6
@@ -47,6 +47,12 @@ public class SpringReferenceNavigationTestGenerated extends AbstractSpringRefere
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifierReference.kt")
|
||||||
|
public void testQualifierReference() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/references/navigation/qualifierReference.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("scopeReference.kt")
|
@TestMetadata("scopeReference.kt")
|
||||||
public void testScopeReference() throws Exception {
|
public void testScopeReference() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/references/navigation/scopeReference.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/references/navigation/scopeReference.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user