提交 12002aed 编写于 作者: N Nikolay Krasko

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
上级 0191c8c6
...@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.injection ...@@ -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 ...@@ -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 ...@@ -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() { ...@@ -90,17 +87,21 @@ class KotlinLanguageInjectionSupport : AbstractLanguageInjectionSupport() {
return true return true
} }
fun findInjectionComment(host: KtElement): PsiComment? { override fun findCommentInjection(host: PsiElement, commentRef: Ref<PsiElement>?): BaseInjection? {
if (findCommentInjection(host, null) == null) return null // Do not inject through CommentLanguageInjector, because it injects as simple injection.
// We need to behave special for interpolated strings.
return null
}
val commentsToCheck: Sequence<PsiComment> = fun findInjectionCommentLanguageId(host: KtElement): String? {
findElementToInjectWithAnnotation(host)?.findChildrenComments() ?: return InjectorUtils.findCommentInjection(host, "", null)?.injectedLanguageId
findElementToInjectWithComment(host)?.findCommentsBeforeElement() ?: }
return null
return commentsToCheck.firstOrNull { fun findInjectionComment(host: KtElement): PsiComment? {
it.node.elementType == KtTokens.EOL_COMMENT && it.text.matches(LINE_LANGUAGE_REGEXP_COMMENT) val commentRef = Ref.create<PsiElement>(null)
} InjectorUtils.findCommentInjection(host, "", commentRef) ?: return null
return commentRef.get() as? PsiComment
} }
fun findAnnotationInjectionLanguageId(host: KtElement): String? { fun findAnnotationInjectionLanguageId(host: KtElement): String? {
...@@ -210,14 +211,6 @@ private fun checkIsValidPlaceForInjectionWithLineComment(statement: KtExpression ...@@ -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 { ...@@ -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)
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册