From 12002aed57b65ee9081e41a254186c918830a0a4 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 16 May 2017 18:34:01 +0300 Subject: [PATCH] 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 --- .../KotlinLanguageInjectionSupport.kt | 39 ++++++++----------- .../idea/injection/KotlinLanguageInjector.kt | 5 ++- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjectionSupport.kt b/idea/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjectionSupport.kt index 1cc721a66b7..39c19ca66f7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjectionSupport.kt +++ b/idea/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjectionSupport.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.injection import com.intellij.codeInsight.AnnotationUtil import com.intellij.lang.Language import com.intellij.openapi.module.ModuleUtilCore +import com.intellij.openapi.util.Ref import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.* 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.util.Processor import org.intellij.plugins.intelliLang.Configuration -import org.intellij.plugins.intelliLang.inject.AbstractLanguageInjectionSupport -import org.intellij.plugins.intelliLang.inject.InjectLanguageAction -import org.intellij.plugins.intelliLang.inject.InjectedLanguage -import org.intellij.plugins.intelliLang.inject.TemporaryPlacesRegistry +import org.intellij.plugins.intelliLang.inject.* +import org.intellij.plugins.intelliLang.inject.config.BaseInjection import org.jetbrains.annotations.NonNls import org.jetbrains.kotlin.idea.patterns.KotlinPatterns import org.jetbrains.kotlin.idea.util.addAnnotation import org.jetbrains.kotlin.idea.util.application.executeWriteCommand import org.jetbrains.kotlin.idea.util.findAnnotation -import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* 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 @NonNls val KOTLIN_SUPPORT_ID = "kotlin" -val LINE_LANGUAGE_REGEXP_COMMENT = Regex("//\\s*language=[\\w-]+") class KotlinLanguageInjectionSupport : AbstractLanguageInjectionSupport() { override fun getId(): String = KOTLIN_SUPPORT_ID @@ -90,17 +87,21 @@ class KotlinLanguageInjectionSupport : AbstractLanguageInjectionSupport() { return true } - fun findInjectionComment(host: KtElement): PsiComment? { - if (findCommentInjection(host, null) == null) return null + override fun findCommentInjection(host: PsiElement, commentRef: Ref?): BaseInjection? { + // Do not inject through CommentLanguageInjector, because it injects as simple injection. + // We need to behave special for interpolated strings. + return null + } - val commentsToCheck: Sequence = - findElementToInjectWithAnnotation(host)?.findChildrenComments() ?: - findElementToInjectWithComment(host)?.findCommentsBeforeElement() ?: - return null + fun findInjectionCommentLanguageId(host: KtElement): String? { + return InjectorUtils.findCommentInjection(host, "", null)?.injectedLanguageId + } - return commentsToCheck.firstOrNull { - it.node.elementType == KtTokens.EOL_COMMENT && it.text.matches(LINE_LANGUAGE_REGEXP_COMMENT) - } + fun findInjectionComment(host: KtElement): PsiComment? { + val commentRef = Ref.create(null) + InjectorUtils.findCommentInjection(host, "", commentRef) ?: return null + + return commentRef.get() as? PsiComment } fun findAnnotationInjectionLanguageId(host: KtElement): String? { @@ -210,14 +211,6 @@ private fun checkIsValidPlaceForInjectionWithLineComment(statement: KtExpression return true } -private fun PsiElement.findChildrenComments(): Sequence { - return firstChild.siblings().takeWhile { it is PsiComment || it is PsiWhiteSpace }.filterIsInstance() -} - -private fun PsiElement.findCommentsBeforeElement(): Sequence { - return siblings(forward = false, withItself = false).takeWhile { it is PsiComment || it is PsiWhiteSpace }.filterIsInstance() -} - private fun PsiElement.firstNonCommentChild(): PsiElement? { return firstChild.siblings().dropWhile { it is PsiComment || it is PsiWhiteSpace }.firstOrNull() } diff --git a/idea/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjector.kt b/idea/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjector.kt index 22ff322daf8..72d0bf3cafb 100644 --- a/idea/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjector.kt +++ b/idea/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjector.kt @@ -80,7 +80,10 @@ class KotlinLanguageInjector : MultiHostInjector { private fun injectWithExplicitCodeInstruction(host: KtElement): InjectionInfo? { 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) } -- GitLab