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.config.BaseInjection
|
||||||
import org.intellij.plugins.intelliLang.inject.java.JavaLanguageInjectionSupport
|
import org.intellij.plugins.intelliLang.inject.java.JavaLanguageInjectionSupport
|
||||||
import org.intellij.plugins.intelliLang.util.AnnotationUtilEx
|
import org.intellij.plugins.intelliLang.util.AnnotationUtilEx
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.references.KtReference
|
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.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.annotations.argumentValue
|
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.lazy.BodyResolveMode
|
||||||
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
@@ -153,6 +156,7 @@ class KotlinLanguageInjector(
|
|||||||
private fun findInjectionInfo(place: KtElement, originalHost: Boolean = true): InjectionInfo? {
|
private fun findInjectionInfo(place: KtElement, originalHost: Boolean = true): InjectionInfo? {
|
||||||
return injectWithExplicitCodeInstruction(place)
|
return injectWithExplicitCodeInstruction(place)
|
||||||
?: injectWithCall(place)
|
?: injectWithCall(place)
|
||||||
|
?: injectInAnnotationCall(place)
|
||||||
?: injectWithReceiver(place)
|
?: injectWithReceiver(place)
|
||||||
?: injectWithVariableUsage(place, originalHost)
|
?: injectWithVariableUsage(place, originalHost)
|
||||||
?: injectWithAnnotationEntry(place)
|
?: injectWithAnnotationEntry(place)
|
||||||
@@ -262,6 +266,16 @@ class KotlinLanguageInjector(
|
|||||||
return null
|
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? {
|
private fun injectionForJavaMethod(argument: KtValueArgument, javaMethod: PsiMethod): InjectionInfo? {
|
||||||
val argumentIndex = (argument.parent as KtValueArgumentList).arguments.indexOf(argument)
|
val argumentIndex = (argument.parent as KtValueArgumentList).arguments.indexOf(argument)
|
||||||
val psiParameter = javaMethod.parameterList.parameters.getOrNull(argumentIndex) ?: return null
|
val psiParameter = javaMethod.parameterList.parameters.getOrNull(argumentIndex) ?: return null
|
||||||
|
|||||||
@@ -488,4 +488,65 @@ class KotlinInjectionTest : AbstractInjectionTest() {
|
|||||||
Configuration.getInstance().replaceInjections(listOf(), listOf(customInjection), true)
|
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