Do injection with comments through our injector (KT-6610)
Hide Kotlin from CommentLanguageInjector as it only can insert simple injection. Process injection by commented strings on our own. #KT-6610 In Progress
This commit is contained in:
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.injection
|
|||||||
import com.intellij.codeInsight.AnnotationUtil
|
import com.intellij.codeInsight.AnnotationUtil
|
||||||
import com.intellij.lang.Language
|
import com.intellij.lang.Language
|
||||||
import com.intellij.openapi.module.ModuleUtilCore
|
import com.intellij.openapi.module.ModuleUtilCore
|
||||||
|
import com.intellij.openapi.util.Ref
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
@@ -26,16 +27,13 @@ import com.intellij.psi.util.PsiTreeUtil
|
|||||||
import com.intellij.psi.util.PsiTreeUtil.getDeepestLast
|
import com.intellij.psi.util.PsiTreeUtil.getDeepestLast
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import org.intellij.plugins.intelliLang.Configuration
|
import org.intellij.plugins.intelliLang.Configuration
|
||||||
import org.intellij.plugins.intelliLang.inject.AbstractLanguageInjectionSupport
|
import org.intellij.plugins.intelliLang.inject.*
|
||||||
import org.intellij.plugins.intelliLang.inject.InjectLanguageAction
|
import org.intellij.plugins.intelliLang.inject.config.BaseInjection
|
||||||
import org.intellij.plugins.intelliLang.inject.InjectedLanguage
|
|
||||||
import org.intellij.plugins.intelliLang.inject.TemporaryPlacesRegistry
|
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
import org.jetbrains.kotlin.idea.patterns.KotlinPatterns
|
import org.jetbrains.kotlin.idea.patterns.KotlinPatterns
|
||||||
import org.jetbrains.kotlin.idea.util.addAnnotation
|
import org.jetbrains.kotlin.idea.util.addAnnotation
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||||
import org.jetbrains.kotlin.idea.util.findAnnotation
|
import org.jetbrains.kotlin.idea.util.findAnnotation
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
|
||||||
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.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
@@ -43,7 +41,6 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
|
||||||
@NonNls val KOTLIN_SUPPORT_ID = "kotlin"
|
@NonNls val KOTLIN_SUPPORT_ID = "kotlin"
|
||||||
val LINE_LANGUAGE_REGEXP_COMMENT = Regex("//\\s*language=[\\w-]+")
|
|
||||||
|
|
||||||
class KotlinLanguageInjectionSupport : AbstractLanguageInjectionSupport() {
|
class KotlinLanguageInjectionSupport : AbstractLanguageInjectionSupport() {
|
||||||
override fun getId(): String = KOTLIN_SUPPORT_ID
|
override fun getId(): String = KOTLIN_SUPPORT_ID
|
||||||
@@ -90,17 +87,21 @@ class KotlinLanguageInjectionSupport : AbstractLanguageInjectionSupport() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findCommentInjection(host: PsiElement, commentRef: Ref<PsiElement>?): BaseInjection? {
|
||||||
|
// Do not inject through CommentLanguageInjector, because it injects as simple injection.
|
||||||
|
// We need to behave special for interpolated strings.
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findInjectionCommentLanguageId(host: KtElement): String? {
|
||||||
|
return InjectorUtils.findCommentInjection(host, "", null)?.injectedLanguageId
|
||||||
|
}
|
||||||
|
|
||||||
fun findInjectionComment(host: KtElement): PsiComment? {
|
fun findInjectionComment(host: KtElement): PsiComment? {
|
||||||
if (findCommentInjection(host, null) == null) return null
|
val commentRef = Ref.create<PsiElement>(null)
|
||||||
|
InjectorUtils.findCommentInjection(host, "", commentRef) ?: return null
|
||||||
|
|
||||||
val commentsToCheck: Sequence<PsiComment> =
|
return commentRef.get() as? PsiComment
|
||||||
findElementToInjectWithAnnotation(host)?.findChildrenComments() ?:
|
|
||||||
findElementToInjectWithComment(host)?.findCommentsBeforeElement() ?:
|
|
||||||
return null
|
|
||||||
|
|
||||||
return commentsToCheck.firstOrNull {
|
|
||||||
it.node.elementType == KtTokens.EOL_COMMENT && it.text.matches(LINE_LANGUAGE_REGEXP_COMMENT)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findAnnotationInjectionLanguageId(host: KtElement): String? {
|
fun findAnnotationInjectionLanguageId(host: KtElement): String? {
|
||||||
@@ -210,14 +211,6 @@ private fun checkIsValidPlaceForInjectionWithLineComment(statement: KtExpression
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PsiElement.findChildrenComments(): Sequence<PsiComment> {
|
|
||||||
return firstChild.siblings().takeWhile { it is PsiComment || it is PsiWhiteSpace }.filterIsInstance<PsiComment>()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun PsiElement.findCommentsBeforeElement(): Sequence<PsiComment> {
|
|
||||||
return siblings(forward = false, withItself = false).takeWhile { it is PsiComment || it is PsiWhiteSpace }.filterIsInstance<PsiComment>()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun PsiElement.firstNonCommentChild(): PsiElement? {
|
private fun PsiElement.firstNonCommentChild(): PsiElement? {
|
||||||
return firstChild.siblings().dropWhile { it is PsiComment || it is PsiWhiteSpace }.firstOrNull()
|
return firstChild.siblings().dropWhile { it is PsiComment || it is PsiWhiteSpace }.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,10 @@ class KotlinLanguageInjector : MultiHostInjector {
|
|||||||
|
|
||||||
private fun injectWithExplicitCodeInstruction(host: KtElement): InjectionInfo? {
|
private fun injectWithExplicitCodeInstruction(host: KtElement): InjectionInfo? {
|
||||||
val support = kotlinSupport ?: return null
|
val support = kotlinSupport ?: return null
|
||||||
val languageId = support.findAnnotationInjectionLanguageId(host) ?: return null
|
val languageId =
|
||||||
|
support.findInjectionCommentLanguageId(host) ?:
|
||||||
|
support.findAnnotationInjectionLanguageId(host) ?:
|
||||||
|
return null
|
||||||
return InjectionInfo(languageId, null, null)
|
return InjectionInfo(languageId, null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user