Support prefix and suffix in Kotlin injection with comments and annotations (KT-23005)
#KT-23005 Fixed
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.injection
|
||||
|
||||
import org.intellij.plugins.intelliLang.inject.config.BaseInjection
|
||||
|
||||
internal class InjectionInfo(val languageId: String?, val prefix: String?, val suffix: String?) {
|
||||
fun toBaseInjection(injectionSupport: KotlinLanguageInjectionSupport): BaseInjection? {
|
||||
if (languageId == null) return null
|
||||
|
||||
val baseInjection = BaseInjection(injectionSupport.id)
|
||||
baseInjection.injectedLanguageId = languageId
|
||||
|
||||
if (prefix != null) {
|
||||
baseInjection.prefix = prefix
|
||||
}
|
||||
|
||||
if (suffix != null) {
|
||||
baseInjection.suffix = suffix
|
||||
}
|
||||
|
||||
return baseInjection
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromBaseInjection(baseInjection: BaseInjection?): InjectionInfo? {
|
||||
if (baseInjection == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return InjectionInfo(
|
||||
baseInjection.injectedLanguageId,
|
||||
baseInjection.prefix,
|
||||
baseInjection.suffix
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
-8
@@ -95,27 +95,39 @@ class KotlinLanguageInjectionSupport : AbstractLanguageInjectionSupport() {
|
||||
return null
|
||||
}
|
||||
|
||||
fun findInjectionCommentLanguageId(host: KtElement): String? {
|
||||
return InjectorUtils.findCommentInjection(host, "", null)?.injectedLanguageId
|
||||
fun findCommentInjection(host: KtElement): BaseInjection? {
|
||||
return InjectorUtils.findCommentInjection(host, "", null)
|
||||
}
|
||||
|
||||
fun findInjectionComment(host: KtElement): PsiComment? {
|
||||
private fun findInjectionComment(host: KtElement): PsiComment? {
|
||||
val commentRef = Ref.create<PsiElement>(null)
|
||||
InjectorUtils.findCommentInjection(host, "", commentRef) ?: return null
|
||||
|
||||
return commentRef.get() as? PsiComment
|
||||
}
|
||||
|
||||
fun findAnnotationInjectionLanguageId(host: KtElement): String? {
|
||||
internal fun findAnnotationInjectionLanguageId(host: KtElement): InjectionInfo? {
|
||||
val annotationEntry = findAnnotationInjection(host) ?: return null
|
||||
return extractLanguageFromInjectAnnotation(annotationEntry)
|
||||
val extractLanguageFromInjectAnnotation = extractLanguageFromInjectAnnotation(annotationEntry) ?: return null
|
||||
val prefix = extractStringArgumentByName(annotationEntry, "prefix")
|
||||
val suffix = extractStringArgumentByName(annotationEntry, "suffix")
|
||||
return InjectionInfo(extractLanguageFromInjectAnnotation, prefix, suffix)
|
||||
}
|
||||
}
|
||||
|
||||
fun extractLanguageFromInjectAnnotation(annotationEntry: KtAnnotationEntry): String? {
|
||||
val firstArgument: ValueArgument = annotationEntry.valueArguments.firstOrNull() ?: return null
|
||||
private fun extractStringArgumentByName(annotationEntry: KtAnnotationEntry, name: String): String? {
|
||||
val namedArgument: ValueArgument = annotationEntry.valueArguments.firstOrNull { it.getArgumentName()?.asName?.asString() == name } ?: return null
|
||||
return extractStringValue(namedArgument)
|
||||
}
|
||||
|
||||
val firstStringArgument = firstArgument.getArgumentExpression() as? KtStringTemplateExpression ?: return null
|
||||
|
||||
private fun extractLanguageFromInjectAnnotation(annotationEntry: KtAnnotationEntry): String? {
|
||||
val firstArgument: ValueArgument = annotationEntry.valueArguments.firstOrNull() ?: return null
|
||||
return extractStringValue(firstArgument)
|
||||
}
|
||||
|
||||
private fun extractStringValue(valueArgument: ValueArgument): String? {
|
||||
val firstStringArgument = valueArgument.getArgumentExpression() as? KtStringTemplateExpression ?: return null
|
||||
val firstStringEntry = firstStringArgument.entries.singleOrNull() ?: return null
|
||||
|
||||
return firstStringEntry.text
|
||||
|
||||
@@ -176,11 +176,7 @@ class KotlinLanguageInjector(
|
||||
|
||||
private fun injectWithExplicitCodeInstruction(host: KtElement): InjectionInfo? {
|
||||
val support = kotlinSupport ?: return null
|
||||
val languageId =
|
||||
support.findInjectionCommentLanguageId(host) ?:
|
||||
support.findAnnotationInjectionLanguageId(host) ?:
|
||||
return null
|
||||
return InjectionInfo(languageId, null, null)
|
||||
return InjectionInfo.fromBaseInjection(support.findCommentInjection(host)) ?: support.findAnnotationInjectionLanguageId(host)
|
||||
}
|
||||
|
||||
private fun injectWithReceiver(host: KtElement): InjectionInfo? {
|
||||
@@ -354,25 +350,6 @@ class KotlinLanguageInjector(
|
||||
return configuration.advancedConfiguration.dfaOption == Configuration.DfaOption.OFF
|
||||
}
|
||||
|
||||
private class InjectionInfo(val languageId: String?, val prefix: String?, val suffix: String?) {
|
||||
fun toBaseInjection(injectionSupport: KotlinLanguageInjectionSupport): BaseInjection? {
|
||||
if (languageId == null) return null
|
||||
|
||||
val baseInjection = BaseInjection(injectionSupport.id)
|
||||
baseInjection.injectedLanguageId = languageId
|
||||
|
||||
if (prefix != null) {
|
||||
baseInjection.prefix = prefix
|
||||
}
|
||||
|
||||
if (suffix != null) {
|
||||
baseInjection.suffix = suffix
|
||||
}
|
||||
|
||||
return baseInjection
|
||||
}
|
||||
}
|
||||
|
||||
private fun processAnnotationInjectionInner(annotations: Array<PsiAnnotation>): InjectionInfo? {
|
||||
val id = AnnotationUtilEx.calcAnnotationValue(annotations, "value")
|
||||
val prefix = AnnotationUtilEx.calcAnnotationValue(annotations, "prefix")
|
||||
|
||||
@@ -416,6 +416,24 @@ class KotlinInjectionTest : AbstractInjectionTest() {
|
||||
)
|
||||
)
|
||||
|
||||
fun testSuffixPrefixWithAnnotation() = doInjectionPresentTest(
|
||||
"""
|
||||
@org.intellij.lang.annotations.Language("TEXT", prefix = "abc", suffix = "ghi")
|
||||
val test = "<caret>def"
|
||||
""",
|
||||
languageId = PlainTextLanguage.INSTANCE.id, unInjectShouldBePresent = false,
|
||||
shreds = listOf(ShredInfo(range(0, 9), hostRange=range(1, 4), prefix = "abc", suffix = "ghi"))
|
||||
)
|
||||
|
||||
fun testSuffixPrefixInComment() = doInjectionPresentTest(
|
||||
"""
|
||||
// language="TEXT" prefix="abc" suffix=ghi
|
||||
val test = "<caret>def"
|
||||
""",
|
||||
languageId = PlainTextLanguage.INSTANCE.id, unInjectShouldBePresent = false,
|
||||
shreds = listOf(ShredInfo(range(0, 9), hostRange=range(1, 4), prefix = "abc", suffix = "ghi"))
|
||||
)
|
||||
|
||||
fun testJavaAnnotationsPattern() {
|
||||
myFixture.addClass("""
|
||||
@interface Matches { String value(); }
|
||||
|
||||
Reference in New Issue
Block a user