From 35b07a29a5866ddec1c7f3f9fe69b6827ae55230 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 30 Nov 2012 02:46:51 +0400 Subject: [PATCH] IDEA-92972 general purpose comment-based injector --- .../manipulators/PsiCommentManipulator.java | 3 ++ plugins/IntelliLang/src/META-INF/plugin.xml | 1 + .../inject/CommentLanguageInjector.java | 43 +++++++++++++++++++ .../intelliLang/inject/InjectorUtils.java | 20 ++++++++- 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/CommentLanguageInjector.java diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/PsiCommentManipulator.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/PsiCommentManipulator.java index 8d606cabeec2..f9346f68fee1 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/PsiCommentManipulator.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/PsiCommentManipulator.java @@ -46,6 +46,9 @@ public class PsiCommentManipulator extends AbstractElementManipulator")) return new TextRange(4, element.getTextLength()-3); + if (text.startsWith("--")) return new TextRange(2, element.getTextLength()); + if (text.startsWith("#")) return new TextRange(1, element.getTextLength()); return super.getRangeInElement(element); } } \ No newline at end of file diff --git a/plugins/IntelliLang/src/META-INF/plugin.xml b/plugins/IntelliLang/src/META-INF/plugin.xml index 01845b44d776..b9733316dd13 100644 --- a/plugins/IntelliLang/src/META-INF/plugin.xml +++ b/plugins/IntelliLang/src/META-INF/plugin.xml @@ -34,6 +34,7 @@ + diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/CommentLanguageInjector.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/CommentLanguageInjector.java new file mode 100644 index 000000000000..5e139de0303f --- /dev/null +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/CommentLanguageInjector.java @@ -0,0 +1,43 @@ +package org.intellij.plugins.intelliLang.inject; + +import com.intellij.lang.Language; +import com.intellij.lang.injection.MultiHostInjector; +import com.intellij.lang.injection.MultiHostRegistrar; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.Trinity; +import com.intellij.psi.*; +import org.intellij.plugins.intelliLang.inject.config.BaseInjection; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +/** + * @author gregsh + */ +public class CommentLanguageInjector implements MultiHostInjector { + + @NotNull + public List> elementsToInjectIn() { + return Collections.singletonList(PsiLanguageInjectionHost.class); + } + + public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull final PsiElement context) { + PsiLanguageInjectionHost host = (PsiLanguageInjectionHost)context; + final ElementManipulator manipulator = ElementManipulators.getManipulator(host); + if (manipulator == null) return; + PsiComment comment = InjectorUtils.findNearestComment(context); + if (comment == null) return; + + String text = ElementManipulators.getValueText(comment).trim(); + BaseInjection injection = InjectorUtils.detectInjectionFromText("comment", text); + if (injection == null) return; + InjectedLanguage injectedLanguage = InjectedLanguage.create(injection.getInjectedLanguageId(), injection.getPrefix(), injection.getSuffix(), false); + Language language = injectedLanguage != null ? injectedLanguage.getLanguage() : null; + if (language != null) { + Trinity info = + Trinity.create(host, injectedLanguage, manipulator.getRangeInElement(host)); + InjectorUtils.registerInjection(language, Collections.singletonList(info), context.getContainingFile(), registrar); + } + } +} 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 cff26eb2914e..7c1e7609e52c 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectorUtils.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectorUtils.java @@ -25,8 +25,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiLanguageInjectionHost; +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.util.ArrayUtil; @@ -219,4 +218,21 @@ public class InjectorUtils { injection.setSuffix(suffix); return injection; } + + @Nullable + public static PsiComment findNearestComment(PsiElement element) { + if (element instanceof PsiComment) return null; + PsiElement start = element; + for (int i=0; i<2 && start != null; i++) { + if (start instanceof PsiFile) return null; + for (PsiElement e = start.getPrevSibling(); e != null; e = e.getPrevSibling()) { + if (e instanceof PsiComment) return (PsiComment)e; + if (e instanceof PsiWhiteSpace) continue; + if (e instanceof PsiLanguageInjectionHost && StringUtil.isEmptyOrSpaces(e.getText())) continue; + break; + } + start = element.getParent(); + } + return null; + } }