From fdfcca2c840465cfb7b48d9c473f1e35b303d06b Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 27 Oct 2015 19:04:37 +0300 Subject: [PATCH] TextMate: add support for language injection (IntelliLang) --- .../inject/java/ConcatenationInjector.java | 11 ++----- .../intelliLang/inject/InjectorUtils.java | 33 +++++++++++++++---- .../groovy/GrConcatenationAwareInjector.java | 11 ++----- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java index f033c6f1d163..62f8183b113a 100644 --- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java @@ -25,7 +25,6 @@ import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; -import com.intellij.psi.injection.ReferenceInjector; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.tree.IElementType; @@ -334,14 +333,8 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { } private void processInjectionWithContext(BaseInjection injection, boolean settingsAvailable) { - Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId()); - if (language == null) { - ReferenceInjector injector = ReferenceInjector.findById(injection.getInjectedLanguageId()); - if (injector != null) { - language = injector.toLanguage(); - } - else return; - } + Language language = InjectorUtils.getLanguage(injection); + if (language == null) return; final boolean separateFiles = !injection.isSingleFile() && StringUtil.isNotEmpty(injection.getValuePattern()); diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectorUtils.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectorUtils.java index 738874a57e54..d4c779571af5 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectorUtils.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectorUtils.java @@ -20,12 +20,16 @@ import com.intellij.codeInsight.completion.CompletionUtil; import com.intellij.lang.Language; import com.intellij.lang.injection.MultiHostRegistrar; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.MultiHostRegistrarImpl; import com.intellij.psi.impl.source.tree.injected.Place; +import com.intellij.psi.injection.ReferenceInjector; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiTreeUtil; @@ -61,12 +65,22 @@ public class InjectorUtils { private InjectorUtils() { } + @Nullable + public static Language getLanguage(@NotNull BaseInjection injection) { + String languageId = injection.getInjectedLanguageId(); + Language language = InjectedLanguage.findLanguageById(languageId); + if (language != null) return language; + ReferenceInjector injector = ReferenceInjector.findById(languageId); + if (injector != null) return injector.toLanguage(); + FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension(languageId); + return fileType instanceof LanguageFileType? ((LanguageFileType)fileType).getLanguage() : null; + } public static boolean registerInjectionSimple(@NotNull PsiLanguageInjectionHost host, @NotNull BaseInjection injection, @Nullable LanguageInjectionSupport support, @NotNull MultiHostRegistrar registrar) { - Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId()); + Language language = getLanguage(injection); if (language == null) return false; InjectedLanguage injectedLanguage = @@ -88,22 +102,29 @@ public class InjectorUtils { return !ranges.isEmpty(); } - public static void registerInjection(Language language, List> list, PsiFile containingFile, MultiHostRegistrar registrar) { + public static void registerInjection(Language language, + List> list, + PsiFile containingFile, + MultiHostRegistrar registrar) { // if language isn't injected when length == 0, subsequent edits will not cause the language to be injected as well. // Maybe IDEA core is caching a bit too aggressively here? if (language == null/* && (pair.second.getLength() > 0*/) { return; } boolean injectionStarted = false; - for (Trinity trinity : list) { - final PsiLanguageInjectionHost host = trinity.first; + for (Trinity t : list) { + PsiLanguageInjectionHost host = t.first; if (host.getContainingFile() != containingFile) continue; - final TextRange textRange = trinity.third; - final InjectedLanguage injectedLanguage = trinity.second; + TextRange textRange = t.third; + InjectedLanguage injectedLanguage = t.second; if (!injectionStarted) { registrar.startInjecting(language); + // TextMate language requires file extension + if (registrar instanceof MultiHostRegistrarImpl && !StringUtil.equalsIgnoreCase(language.getID(), t.second.getID())) { + ((MultiHostRegistrarImpl)registrar).setFileExtension(StringUtil.toLowerCase(t.second.getID())); + } injectionStarted = true; } registrar.addPlace(injectedLanguage.getPrefix(), injectedLanguage.getSuffix(), host, textRange); diff --git a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationAwareInjector.java b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationAwareInjector.java index 80d4c60a6084..03d72fcc1248 100644 --- a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationAwareInjector.java +++ b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationAwareInjector.java @@ -24,7 +24,6 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.Trinity; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; -import com.intellij.psi.injection.ReferenceInjector; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.tree.IElementType; @@ -356,14 +355,8 @@ public class GrConcatenationAwareInjector implements ConcatenationAwareInjector private void processInjectionWithContext(BaseInjection injection, boolean settingsAvailable) { - Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId()); - if (language == null) { - ReferenceInjector injector = ReferenceInjector.findById(injection.getInjectedLanguageId()); - if (injector != null) { - language = injector.toLanguage(); - } - else return; - } + Language language = InjectorUtils.getLanguage(injection); + if (language == null) return; String languageID = language.getID(); List> list = ContainerUtil.newArrayList();