KotlinLanguageInjector understands patterns-injections into Java annotations
This commit is contained in:
committed by
Nikolay Krasko
parent
743dc80b4d
commit
1435911437
@@ -35,6 +35,7 @@ import org.intellij.plugins.intelliLang.inject.TemporaryPlacesRegistry
|
||||
import org.intellij.plugins.intelliLang.inject.config.BaseInjection
|
||||
import org.intellij.plugins.intelliLang.inject.java.JavaLanguageInjectionSupport
|
||||
import org.intellij.plugins.intelliLang.util.AnnotationUtilEx
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
@@ -44,7 +45,9 @@ import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.annotations.argumentValue
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
@@ -153,6 +156,7 @@ class KotlinLanguageInjector(
|
||||
private fun findInjectionInfo(place: KtElement, originalHost: Boolean = true): InjectionInfo? {
|
||||
return injectWithExplicitCodeInstruction(place)
|
||||
?: injectWithCall(place)
|
||||
?: injectInAnnotationCall(place)
|
||||
?: injectWithReceiver(place)
|
||||
?: injectWithVariableUsage(place, originalHost)
|
||||
?: injectWithAnnotationEntry(place)
|
||||
@@ -262,6 +266,16 @@ class KotlinLanguageInjector(
|
||||
return null
|
||||
}
|
||||
|
||||
private fun injectInAnnotationCall(host: KtElement): InjectionInfo? {
|
||||
val argument = host.parent as? KtValueArgument ?: return null
|
||||
val annotationEntry = argument.parent.parent as? KtAnnotationEntry ?: return null
|
||||
val callDescriptor = annotationEntry.getResolvedCall(annotationEntry.analyze())?.candidateDescriptor
|
||||
val psiClass = (callDescriptor as? DeclarationDescriptorWithSource)?.source?.getPsi() as? PsiClass ?: return null
|
||||
val argumentName = argument.getArgumentName()?.asName?.identifier ?: "value"
|
||||
val method = psiClass.findMethodsByName(argumentName, false).singleOrNull() ?: return null
|
||||
return findInjection(method, Configuration.getInstance().getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID))
|
||||
}
|
||||
|
||||
private fun injectionForJavaMethod(argument: KtValueArgument, javaMethod: PsiMethod): InjectionInfo? {
|
||||
val argumentIndex = (argument.parent as KtValueArgumentList).arguments.indexOf(argument)
|
||||
val psiParameter = javaMethod.parameterList.parameters.getOrNull(argumentIndex) ?: return null
|
||||
|
||||
@@ -488,4 +488,65 @@ class KotlinInjectionTest : AbstractInjectionTest() {
|
||||
Configuration.getInstance().replaceInjections(listOf(), listOf(customInjection), true)
|
||||
}
|
||||
}
|
||||
|
||||
fun testInjectionInJavaAnnotation() {
|
||||
val customInjection = BaseInjection("java")
|
||||
customInjection.injectedLanguageId = HTMLLanguage.INSTANCE.id
|
||||
val elementPattern = customInjection.compiler.createElementPattern(
|
||||
"""psiMethod().withName("value").withParameters().definedInClass("InHtml")""",
|
||||
"SuppressWarnings temp rule")
|
||||
customInjection.setInjectionPlaces(InjectionPlace(elementPattern, true))
|
||||
|
||||
try {
|
||||
Configuration.getInstance().replaceInjections(listOf(customInjection), listOf(), true)
|
||||
|
||||
doInjectionPresentTest(
|
||||
"""
|
||||
@InHtml("<htm<caret>l></html>")
|
||||
fun foo() {
|
||||
}
|
||||
""", """
|
||||
@interface InHtml {
|
||||
String value();
|
||||
}
|
||||
""".trimIndent(),
|
||||
HTMLLanguage.INSTANCE.id,
|
||||
unInjectShouldBePresent = false
|
||||
)
|
||||
}
|
||||
finally {
|
||||
Configuration.getInstance().replaceInjections(listOf(), listOf(customInjection), true)
|
||||
}
|
||||
}
|
||||
|
||||
fun testInjectionInJavaAnnotationWithNamedParam() {
|
||||
val customInjection = BaseInjection("java")
|
||||
customInjection.injectedLanguageId = HTMLLanguage.INSTANCE.id
|
||||
val elementPattern = customInjection.compiler.createElementPattern(
|
||||
"""psiMethod().withName("html").withParameters().definedInClass("InHtml")""",
|
||||
"SuppressWarnings temp rule")
|
||||
customInjection.setInjectionPlaces(InjectionPlace(elementPattern, true))
|
||||
|
||||
try {
|
||||
Configuration.getInstance().replaceInjections(listOf(customInjection), listOf(), true)
|
||||
|
||||
doInjectionPresentTest(
|
||||
"""
|
||||
@InHtml(html = "<htm<caret>l></html>")
|
||||
fun foo() {
|
||||
}
|
||||
""", """
|
||||
@interface InHtml {
|
||||
String html();
|
||||
}
|
||||
""".trimIndent(),
|
||||
HTMLLanguage.INSTANCE.id,
|
||||
unInjectShouldBePresent = false
|
||||
)
|
||||
}
|
||||
finally {
|
||||
Configuration.getInstance().replaceInjections(listOf(), listOf(customInjection), true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user