TextMate: add support for language injection (IntelliLang)

This commit is contained in:
Gregory.Shrago
2015-10-27 19:30:28 +03:00
parent 6fe3fe80d4
commit fdfcca2c84
3 changed files with 31 additions and 24 deletions
@@ -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());
@@ -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<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> list, PsiFile containingFile, MultiHostRegistrar registrar) {
public static void registerInjection(Language language,
List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> 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<PsiLanguageInjectionHost, InjectedLanguage, TextRange> trinity : list) {
final PsiLanguageInjectionHost host = trinity.first;
for (Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange> 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);
@@ -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<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> list = ContainerUtil.newArrayList();