KotlinLanguageInjector: support for nested annotations (#KT-21753)
This commit is contained in:
@@ -276,9 +276,14 @@ class KotlinLanguageInjector(
|
|||||||
private fun injectInAnnotationCall(host: KtElement): InjectionInfo? {
|
private fun injectInAnnotationCall(host: KtElement): InjectionInfo? {
|
||||||
if (!annotationInjectionsEnabled) return null
|
if (!annotationInjectionsEnabled) return null
|
||||||
val argument = host.parent as? KtValueArgument ?: return null
|
val argument = host.parent as? KtValueArgument ?: return null
|
||||||
val annotationEntry = argument.parent.parent as? KtAnnotationEntry ?: return null
|
val annotationEntry = argument.parent.parent as? KtCallElement ?: return null
|
||||||
if (!fastCheckInjectionsExists(annotationEntry)) return null
|
if (!fastCheckInjectionsExists(annotationEntry)) return null
|
||||||
val calleeReference = annotationEntry.calleeExpression?.constructorReferenceExpression?.mainReference
|
val calleeExpression = annotationEntry.calleeExpression ?: return null
|
||||||
|
val calleeReference = when (calleeExpression) {
|
||||||
|
is KtConstructorCalleeExpression -> calleeExpression.constructorReferenceExpression?.mainReference // for top annotations
|
||||||
|
is KtNameReferenceExpression -> calleeExpression.mainReference // for nested annotations
|
||||||
|
else -> return null
|
||||||
|
}
|
||||||
val callee = calleeReference?.resolve()
|
val callee = calleeReference?.resolve()
|
||||||
when (callee) {
|
when (callee) {
|
||||||
is KtFunction -> return injectionForKotlinCall(argument, callee, calleeReference)
|
is KtFunction -> return injectionForKotlinCall(argument, callee, calleeReference)
|
||||||
@@ -378,8 +383,13 @@ class KotlinLanguageInjector(
|
|||||||
}, configuration)
|
}, configuration)
|
||||||
}, false)
|
}, false)
|
||||||
|
|
||||||
private fun fastCheckInjectionsExists(annotationEntry: KtAnnotationEntry): Boolean {
|
private fun fastCheckInjectionsExists(annotationEntry: KtCallElement): Boolean {
|
||||||
val referencedName = (annotationEntry.typeReference?.typeElement as? KtUserType)?.referencedName ?: return false
|
val referencedName = when (annotationEntry) {
|
||||||
|
is KtAnnotationEntry -> // for top annotations
|
||||||
|
(annotationEntry.typeReference?.typeElement as? KtUserType)?.referencedName ?: return false
|
||||||
|
else -> // for nested annotations
|
||||||
|
(annotationEntry.calleeExpression as? KtNameReferenceExpression)?.getReferencedName() ?: return false
|
||||||
|
}
|
||||||
val annotationShortName = annotationEntry.containingKtFile.aliasImportMap()[referencedName].singleOrNull() ?: referencedName
|
val annotationShortName = annotationEntry.containingKtFile.aliasImportMap()[referencedName].singleOrNull() ?: referencedName
|
||||||
return annotationShortName in injectableTargetClassShortNames.value
|
return annotationShortName in injectableTargetClassShortNames.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -519,6 +519,39 @@ class KotlinInjectionTest : AbstractInjectionTest() {
|
|||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testInjectionInJavaNestedAnnotation() {
|
||||||
|
myFixture.addClass(
|
||||||
|
"""
|
||||||
|
package myinjection;
|
||||||
|
|
||||||
|
public @interface InHtml {
|
||||||
|
String html();
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
myFixture.addClass(
|
||||||
|
"""
|
||||||
|
package myinjection;
|
||||||
|
|
||||||
|
public @interface InHtmls {
|
||||||
|
InHtml[] htmls();
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
doAnnotationInjectionTest(
|
||||||
|
injectedLanguage = HTMLLanguage.INSTANCE.id,
|
||||||
|
pattern = """psiMethod().withName("html").withParameters().definedInClass("myinjection.InHtml")""",
|
||||||
|
kotlinCode = """
|
||||||
|
import myinjection.InHtml
|
||||||
|
import myinjection.InHtmls
|
||||||
|
|
||||||
|
@InHtmls(htmls = [InHtml(html = "<htm<caret>l></html>")])
|
||||||
|
fun foo() {
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun testInjectionInAliasedJavaAnnotation() {
|
fun testInjectionInAliasedJavaAnnotation() {
|
||||||
myFixture.addClass("""
|
myFixture.addClass("""
|
||||||
@interface InHtml {
|
@interface InHtml {
|
||||||
|
|||||||
Reference in New Issue
Block a user