diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/MethodParameterInjection.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/MethodParameterInjection.java index 3b2a2fbad60b..464aa38ccc03 100644 --- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/MethodParameterInjection.java +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/MethodParameterInjection.java @@ -26,7 +26,7 @@ import com.intellij.psi.*; import com.intellij.psi.util.PsiFormatUtil; import com.intellij.util.IncorrectOperationException; import gnu.trove.THashMap; -import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport; +import org.intellij.plugins.intelliLang.inject.java.JavaLanguageInjectionSupport; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -42,7 +42,7 @@ public class MethodParameterInjection extends BaseInjection { private final Map myParameterMap = new THashMap(); public MethodParameterInjection() { - super(LanguageInjectionSupport.JAVA_SUPPORT_ID); + super(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID); } @NotNull 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 1bbcbaa55ac8..e5de908ce464 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 @@ -69,7 +69,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { myConfiguration = configuration; myProject = project; myTemporaryPlacesRegistry = temporaryPlacesRegistry; - mySupport = InjectorUtils.findNotNullInjectionSupport(LanguageInjectionSupport.JAVA_SUPPORT_ID); + mySupport = InjectorUtils.findNotNullInjectionSupport(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID); myXmlIndex = CachedValuesManager.getManager(myProject).createCachedValue(new CachedValueProvider>() { public Result> compute() { final Map, BaseInjection> map = new THashMap, BaseInjection>(); @@ -139,7 +139,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { if (!hasLiteral) return; final Language tempLanguage = tempInjectedLanguage == null ? null : tempInjectedLanguage.getLanguage(); final PsiFile finalContainingFile = containingFile; - InjectionProcessor injectionProcessor = new InjectionProcessor(myConfiguration, operands) { + InjectionProcessor injectionProcessor = new InjectionProcessor(myConfiguration, mySupport, operands) { @Override protected void processInjection(Language language, List> list, @@ -162,7 +162,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { } }; if (tempLanguage != null) { - BaseInjection baseInjection = new BaseInjection(LanguageInjectionSupport.JAVA_SUPPORT_ID); + BaseInjection baseInjection = new BaseInjection(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID); baseInjection.setInjectedLanguageId(tempInjectedLanguage.getID()); injectionProcessor.processInjectionInner(baseInjection, false); InjectorUtils.putInjectedFileUserData(registrar, LanguageInjectionSupport.TEMPORARY_INJECTED_LANGUAGE, tempInjectedLanguage); @@ -175,12 +175,14 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { public static class InjectionProcessor { private final Configuration myConfiguration; + private final LanguageInjectionSupport mySupport; private final PsiElement[] myOperands; private boolean myShouldStop; private boolean myUnparsable; - public InjectionProcessor(Configuration configuration, PsiElement... operands) { + public InjectionProcessor(Configuration configuration, LanguageInjectionSupport support, PsiElement... operands) { myConfiguration = configuration; + mySupport = support; myOperands = operands; } @@ -301,11 +303,11 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { } private boolean processCommentInjections(PsiVariable owner) { - Ref causeRef = Ref.create(); + Ref causeRef = Ref.create(); PsiElement anchor = owner.getFirstChild() instanceof PsiComment? (owner.getModifierList() != null? owner.getModifierList() : owner.getTypeElement()) : owner; if (anchor == null) return true; - BaseInjection injection = InjectorUtils.findCommentInjection(anchor, LanguageInjectionSupport.JAVA_SUPPORT_ID, causeRef); + BaseInjection injection = mySupport.findInjectionComment(anchor, causeRef); return injection == null || processCommentInjectionInner(owner, causeRef.get(), injection); } @@ -351,7 +353,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { final String id = AnnotationUtilEx.calcAnnotationValue(annotations, "value"); final String prefix = AnnotationUtilEx.calcAnnotationValue(annotations, "prefix"); final String suffix = AnnotationUtilEx.calcAnnotationValue(annotations, "suffix"); - final BaseInjection injection = new BaseInjection(LanguageInjectionSupport.JAVA_SUPPORT_ID); + final BaseInjection injection = new BaseInjection(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID); if (prefix != null) injection.setPrefix(prefix); if (suffix != null) injection.setSuffix(suffix); if (id != null) injection.setInjectedLanguageId(id); diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java index 70843dbd4763..7bf11d2cdb65 100644 --- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java @@ -61,6 +61,7 @@ import org.intellij.plugins.intelliLang.inject.config.ui.configurables.MethodPar import org.intellij.plugins.intelliLang.util.ContextComputationProcessor; import org.intellij.plugins.intelliLang.util.PsiUtilEx; import org.jdom.Element; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -75,6 +76,8 @@ import static org.intellij.plugins.intelliLang.inject.config.MethodParameterInje */ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSupport { + @NonNls public static final String JAVA_SUPPORT_ID = "java"; + private static boolean isMine(final PsiLanguageInjectionHost psiElement) { return PsiUtilEx.isStringOrCharacterLiteral(psiElement); } @@ -93,6 +96,11 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo return new Configurable[]{new AdvancedSettingsUI(project, configuration)}; } + @Override + public boolean isApplicableTo(PsiLanguageInjectionHost host) { + return host instanceof PsiLiteralExpression; + } + public boolean addInjectionInPlace(final Language language, final PsiLanguageInjectionHost psiElement) { if (!isMine(psiElement)) return false; return doInjectInJava(psiElement.getProject(), psiElement, language.getID()); @@ -105,7 +113,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo final PsiLiteralExpression host = (PsiLiteralExpression)psiElement; final Project project = host.getProject(); final Configuration configuration = Configuration.getProjectInstance(project); - collectInjections(host, configuration, injectionsMap, annotations); + collectInjections(host, configuration, this, injectionsMap, annotations); if (injectionsMap.isEmpty() && annotations.isEmpty()) return false; final ArrayList originalInjections = new ArrayList(injectionsMap.keySet()); @@ -129,7 +137,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo final PsiLiteralExpression host = (PsiLiteralExpression)psiElement; final Project project = host.getProject(); final Configuration configuration = Configuration.getProjectInstance(project); - collectInjections(host, configuration, injectionsMap, annotations); + collectInjections(host, configuration, this, injectionsMap, annotations); if (injectionsMap.isEmpty() || !annotations.isEmpty()) return false; final BaseInjection originalInjection = injectionsMap.keySet().iterator().next(); @@ -146,7 +154,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo } - private BaseInjection showInjectionUI(final Project project, final MethodParameterInjection methodParameterInjection) { + private static BaseInjection showInjectionUI(final Project project, final MethodParameterInjection methodParameterInjection) { final AbstractInjectionPanel panel = new MethodParameterPanel(methodParameterInjection, project); panel.reset(); final DialogBuilder builder = new DialogBuilder(project); @@ -343,10 +351,12 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo } } - private static void collectInjections(final PsiLiteralExpression host, final Configuration configuration, + private static void collectInjections(PsiLiteralExpression host, + Configuration configuration, + JavaLanguageInjectionSupport support, final HashMap> injectionsMap, final ArrayList annotations) { - new ConcatenationInjector.InjectionProcessor(configuration, host) { + new ConcatenationInjector.InjectionProcessor(configuration, support, host) { @Override protected boolean processCommentInjectionInner(PsiVariable owner, PsiElement comment, BaseInjection injection) { diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java index 867833638a08..821284f9abc9 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java @@ -186,14 +186,10 @@ public class Configuration implements PersistentStateComponent, Modific @NonNls public static final String COMPONENT_NAME = "LanguageInjectionConfiguration"; // element names - @NonNls private static final String TAG_INJECTION_NAME = "TAGS"; - @NonNls private static final String ATTRIBUTE_INJECTION_NAME = "ATTRIBUTES"; - @NonNls private static final String PARAMETER_INJECTION_NAME = "PARAMETERS"; @NonNls private static final String INSTRUMENTATION_TYPE_NAME = "INSTRUMENTATION"; @NonNls private static final String LANGUAGE_ANNOTATION_NAME = "LANGUAGE_ANNOTATION"; @NonNls private static final String PATTERN_ANNOTATION_NAME = "PATTERN_ANNOTATION"; @NonNls private static final String SUBST_ANNOTATION_NAME = "SUBST_ANNOTATION"; - @NonNls private static final String ENTRY_NAME = "entry"; @NonNls private static final String RESOLVE_REFERENCES = "RESOLVE_REFERENCES"; @NonNls private static final String LOOK_FOR_VAR_ASSIGNMENTS = "LOOK_FOR_VAR_ASSIGNMENTS"; @NonNls private static final String USE_DFA_IF_AVAILABLE = "USE_DFA_IF_AVAILABLE"; @@ -242,7 +238,6 @@ public class Configuration implements PersistentStateComponent, Modific for (LanguageInjectionSupport support : InjectorUtils.getActiveInjectionSupports()) { supports.put(support.getId(), support); } - loadStateOld(element, supports.get(LanguageInjectionSupport.XML_SUPPORT_ID), supports.get(LanguageInjectionSupport.JAVA_SUPPORT_ID)); for (Element child : element.getChildren("injection")){ final String key = child.getAttributeValue("injector-id"); final LanguageInjectionSupport support = supports.get(key); @@ -268,31 +263,6 @@ public class Configuration implements PersistentStateComponent, Modific return places.length != 0 && result.length == 0? null : result; } - private void loadStateOld(Element element, final LanguageInjectionSupport xmlSupport, final LanguageInjectionSupport javaSupport) { - if (xmlSupport != null) { - final Element xmlTagMarker = new Element("XmlTagInjection"); - myInjections.get(LanguageInjectionSupport.XML_SUPPORT_ID).addAll(readExternal(element.getChild(TAG_INJECTION_NAME), new Factory() { - public BaseInjection create() { - return xmlSupport.createInjection(xmlTagMarker); - } - })); - final Element xmlAttributeMarker = new Element("XmlAttributeInjection"); - myInjections.get(LanguageInjectionSupport.XML_SUPPORT_ID).addAll(readExternal(element.getChild(ATTRIBUTE_INJECTION_NAME), new Factory() { - public BaseInjection create() { - return xmlSupport.createInjection(xmlAttributeMarker); - } - })); - } - if (javaSupport != null) { - final Element javaMethodMarker = new Element("MethodParameterInjection"); - myInjections.get(LanguageInjectionSupport.JAVA_SUPPORT_ID).addAll(readExternal(element.getChild(PARAMETER_INJECTION_NAME), new Factory() { - public BaseInjection create() { - return javaSupport.createInjection(javaMethodMarker); - } - })); - } - } - private static boolean readBoolean(Element element, String key, boolean defValue) { final String value = JDOMExternalizerUtil.readField(element, key); if (value == null) return defValue; @@ -361,20 +331,6 @@ public class Configuration implements PersistentStateComponent, Modific return element; } - @SuppressWarnings({"unchecked"}) - private static List readExternal(Element element, Factory factory) { - final List injections = new ArrayList(); - if (element != null) { - final List list = element.getChildren(ENTRY_NAME); - for (Element entry : list) { - final T o = factory.create(); - o.loadState(entry); - injections.add(o); - } - } - return injections; - } - public static Configuration getInstance() { return ServiceManager.getService(Configuration.class); } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java index 6ba500af8a10..f7b40b637f5e 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java @@ -26,6 +26,7 @@ import com.intellij.openapi.ui.DialogBuilder; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Factory; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiLanguageInjectionHost; @@ -36,6 +37,7 @@ import org.intellij.plugins.intelliLang.Configuration; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; import org.intellij.plugins.intelliLang.inject.config.ui.BaseInjectionPanel; import org.jdom.Element; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -45,10 +47,21 @@ import javax.swing.*; */ public abstract class AbstractLanguageInjectionSupport extends LanguageInjectionSupport { - public boolean useDefaultInjector(final PsiElement host) { + @Override + public boolean isApplicableTo(PsiLanguageInjectionHost host) { + return useDefaultInjector(host); // todo temporary plugin compatibility fix. TBR + } + + public boolean useDefaultInjector(final PsiLanguageInjectionHost host) { return false; } + @Nullable + @Override + public BaseInjection findInjectionComment(@NotNull PsiElement host, @Nullable Ref commentRef) { + return InjectorUtils.findCommentInjection(host, "comment", commentRef); + } + public boolean addInjectionInPlace(final Language language, final PsiLanguageInjectionHost psiElement) { return false; } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/CommentLanguageInjector.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/CommentLanguageInjector.java index 1bbc1e40b1f2..30d8943a4fac 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/CommentLanguageInjector.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/CommentLanguageInjector.java @@ -1,15 +1,15 @@ 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.Ref; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.Trinity; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLanguageInjectionHost; +import com.intellij.util.ArrayUtil; +import org.intellij.plugins.intelliLang.Configuration; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -18,29 +18,53 @@ import java.util.List; */ public class CommentLanguageInjector implements MultiHostInjector { + private final LanguageInjectionSupport[] mySupports; + private final LanguageInjectionSupport myInjectorSupport = new AbstractLanguageInjectionSupport() { + @NotNull + @Override + public String getId() { + return "comment"; + } + + @Override + public boolean isApplicableTo(PsiLanguageInjectionHost host) { + return true; + } + + @NotNull + @Override + public Class[] getPatternClasses() { + return ArrayUtil.EMPTY_CLASS_ARRAY; + } + }; + + + /** @noinspection UnusedParameters*/ + public CommentLanguageInjector(Configuration configuration) { + List supports = new ArrayList(InjectorUtils.getActiveInjectionSupports()); + supports.add(myInjectorSupport); + mySupports = ArrayUtil.toObjectArray(supports, LanguageInjectionSupport.class); + } + @NotNull public List> elementsToInjectIn() { return Collections.singletonList(PsiLanguageInjectionHost.class); } public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull final PsiElement context) { + if (!(context instanceof PsiLanguageInjectionHost) || !((PsiLanguageInjectionHost)context).isValidHost()) return; PsiLanguageInjectionHost host = (PsiLanguageInjectionHost)context; - if (!host.isValidHost()) return; - if (context.getClass().getSimpleName().startsWith("XmlAttribute")) return; // no injection in XML attributes, they cannot be commented - ElementManipulator manipulator = ElementManipulators.getManipulator(host); - if (manipulator == null) return; - TextRange rangeInElement = manipulator.getRangeInElement(host); - if (rangeInElement.isEmpty()) return; - PsiElement anchor = rangeInElement.getStartOffset() == 0 ? context.getParent() : context; // handle XmlText - BaseInjection injection = InjectorUtils.findCommentInjection(anchor, "comment", Ref.create()); - //BaseInjection injection = InjectorUtils.findCommentInjection(context, "comment", Ref.create()); - 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, rangeInElement); - InjectorUtils.registerInjection(language, Collections.singletonList(info), context.getContainingFile(), registrar); + + boolean applicableFound = false; + for (LanguageInjectionSupport support : mySupports) { + if (!support.isApplicableTo(host)) continue; + if (support == myInjectorSupport && applicableFound) continue; + applicableFound = true; + + BaseInjection injection = support.findInjectionComment(host, null); + if (injection == null) continue; + if (!InjectorUtils.registerInjectionSimple(host, injection, support, registrar)) continue; + return; } } } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/DefaultLanguageInjector.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/DefaultLanguageInjector.java index 1847cd26e274..f95bea6947f2 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/DefaultLanguageInjector.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/DefaultLanguageInjector.java @@ -16,11 +16,8 @@ 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.PsiElement; import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.util.ArrayUtil; @@ -28,7 +25,6 @@ import org.intellij.plugins.intelliLang.Configuration; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -47,30 +43,18 @@ public final class DefaultLanguageInjector implements MultiHostInjector { return Collections.singletonList(PsiLanguageInjectionHost.class); } - public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull final PsiElement host) { + public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull final PsiElement context) { + if (!(context instanceof PsiLanguageInjectionHost) || !((PsiLanguageInjectionHost)context).isValidHost()) return; + PsiLanguageInjectionHost host = (PsiLanguageInjectionHost)context; + for (LanguageInjectionSupport support : mySupports) { + if (!support.isApplicableTo(host)) continue; if (!support.useDefaultInjector(host)) continue; + for (BaseInjection injection : myInjectionConfiguration.getInjections(support.getId())) { - if (injection.acceptsPsiElement(host)) { - final Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId()); - if (language == null) continue; - - final InjectedLanguage injectedLanguage = - InjectedLanguage.create(injection.getInjectedLanguageId(), injection.getPrefix(), injection.getSuffix(), false); - - List ranges = injection.getInjectedArea(host); - final List> list = - new ArrayList>(ranges.size()); - for (TextRange range : ranges) { - list.add(Trinity.create((PsiLanguageInjectionHost)host, injectedLanguage, range)); - } - //if (host.getChildren().length > 0) { - // host.putUserData(LanguageInjectionSupport.HAS_UNPARSABLE_FRAGMENTS, Boolean.TRUE); - //} - InjectorUtils.registerInjection(language, list, host.getContainingFile(), registrar); - InjectorUtils.registerSupport(support, true, registrar); - break; - } + if (!injection.acceptsPsiElement(host)) continue; + if (!InjectorUtils.registerInjectionSimple(host, injection, support, registrar)) continue; + return; } } } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java index 90fa8291b03b..070cb2d36e25 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java @@ -128,10 +128,10 @@ public class InjectLanguageAction implements IntentionAction { try { Language language = injectable.toLanguage(); for (LanguageInjectionSupport support : InjectorUtils.getActiveInjectionSupports()) { - if (support.addInjectionInPlace(language, host)) { - ((PsiModificationTrackerImpl)PsiManager.getInstance(project).getModificationTracker()).incCounter(); - return; - } + if (!support.isApplicableTo(host)) continue; + if (!support.addInjectionInPlace(language, host)) continue; + ((PsiModificationTrackerImpl)PsiManager.getInstance(project).getModificationTracker()).incCounter(); + return; } if (TemporaryPlacesRegistry.getInstance(project).getLanguageInjectionSupport().addInjectionInPlace(language, host)) { HintManager.getInstance().showInformationHint(editor, StringUtil.escapeXml(language.getDisplayName()) + " was temporarily injected"); 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 5615e7a396bc..01a76297235d 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectorUtils.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectorUtils.java @@ -16,10 +16,8 @@ package org.intellij.plugins.intelliLang.inject; -import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil; import com.intellij.lang.Language; import com.intellij.lang.injection.MultiHostRegistrar; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; @@ -59,6 +57,32 @@ public class InjectorUtils { } + public static boolean registerInjectionSimple(@NotNull PsiLanguageInjectionHost host, + @NotNull BaseInjection injection, + @Nullable LanguageInjectionSupport support, + @NotNull MultiHostRegistrar registrar) { + Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId()); + if (language == null) return false; + + InjectedLanguage injectedLanguage = + InjectedLanguage.create(injection.getInjectedLanguageId(), injection.getPrefix(), injection.getSuffix(), false); + + List ranges = injection.getInjectedArea(host); + List> list = ContainerUtil.newArrayListWithExpectedSize(ranges.size()); + + for (TextRange range : ranges) { + list.add(Trinity.create(host, injectedLanguage, range)); + } + //if (host.getChildren().length > 0) { + // host.putUserData(LanguageInjectionSupport.HAS_UNPARSABLE_FRAGMENTS, Boolean.TRUE); + //} + registerInjection(language, list, host.getContainingFile(), registrar); + if (support != null) { + registerSupport(support, true, registrar); + } + return !ranges.isEmpty(); + } + 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? @@ -196,12 +220,12 @@ public class InjectorUtils { return true; } - public static BaseInjection findCommentInjection(PsiElement context, final String supportId, final Ref causeRef) { + public static BaseInjection findCommentInjection(PsiElement context, final String supportId, final Ref causeRef) { return findNearestComment(context, new NullableFunction() { @Nullable @Override public BaseInjection fun(PsiComment comment) { - causeRef.set(comment); + if (causeRef != null) causeRef.set(comment); String text = ElementManipulators.getValueText(comment).trim(); return detectInjectionFromText(supportId, text); } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionSupport.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionSupport.java index edcd194f7683..7630fe9e68f0 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionSupport.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionSupport.java @@ -22,6 +22,7 @@ import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Factory; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.ui.SimpleColoredText; @@ -31,6 +32,7 @@ import org.intellij.plugins.intelliLang.inject.config.BaseInjection; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author Gregory.Shrago @@ -44,9 +46,6 @@ public abstract class LanguageInjectionSupport { public static Key INJECTOR_SUPPORT = Key.create("INJECTOR_SUPPORT"); public static Key SETTINGS_EDITOR = Key.create("SETTINGS_EDITOR"); - @NonNls public static final String XML_SUPPORT_ID = "xml"; - @NonNls public static final String JAVA_SUPPORT_ID = "java"; - @NonNls @NotNull public abstract String getId(); @@ -54,7 +53,12 @@ public abstract class LanguageInjectionSupport { @NotNull public abstract Class[] getPatternClasses(); - public abstract boolean useDefaultInjector(final PsiElement host); + public abstract boolean isApplicableTo(PsiLanguageInjectionHost host); + + public abstract boolean useDefaultInjector(PsiLanguageInjectionHost host); + + @Nullable + public abstract BaseInjection findInjectionComment(@NotNull PsiElement host, @Nullable Ref commentRef); public abstract boolean addInjectionInPlace(final Language language, final PsiLanguageInjectionHost psiElement); diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesInjector.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesInjector.java index b725eaa8eb43..5139768499e1 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesInjector.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesInjector.java @@ -47,18 +47,20 @@ public class TemporaryPlacesInjector implements MultiHostInjector { } public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull final PsiElement context) { + if (!(context instanceof PsiLanguageInjectionHost) || !((PsiLanguageInjectionHost)context).isValidHost()) return; PsiLanguageInjectionHost host = (PsiLanguageInjectionHost)context; + PsiFile containingFile = context.getContainingFile(); InjectedLanguage injectedLanguage = myRegistry.getLanguageFor(host, containingFile); Language language = injectedLanguage != null ? injectedLanguage.getLanguage() : null; - if (language != null) { - final ElementManipulator manipulator = ElementManipulators.getManipulator(host); - if (manipulator == null) return; - List> trinities = - Collections.singletonList(Trinity.create(host, injectedLanguage, manipulator.getRangeInElement(host))); - InjectorUtils.registerInjection(language, trinities, containingFile, registrar); - InjectorUtils.registerSupport(myRegistry.getLanguageInjectionSupport(), false, registrar); - } + if (language == null) return; + + final ElementManipulator manipulator = ElementManipulators.getManipulator(host); + if (manipulator == null) return; + List> trinities = + Collections.singletonList(Trinity.create(host, injectedLanguage, manipulator.getRangeInElement(host))); + InjectorUtils.registerInjection(language, trinities, containingFile, registrar); + InjectorUtils.registerSupport(myRegistry.getLanguageInjectionSupport(), false, registrar); } } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesRegistry.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesRegistry.java index eaf14241183e..56d1e9863320 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesRegistry.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesRegistry.java @@ -50,6 +50,11 @@ public class TemporaryPlacesRegistry { return "temp"; } + @Override + public boolean isApplicableTo(PsiLanguageInjectionHost host) { + return true; + } + @NotNull @Override public Class[] getPatternClasses() { diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java index 71021f5eaa8a..0662837d0574 100644 --- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java +++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java @@ -23,7 +23,7 @@ import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.psi.xml.XmlElement; import com.intellij.psi.xml.XmlTag; -import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport; +import org.intellij.plugins.intelliLang.inject.xml.XmlLanguageInjectionSupport; import org.intellij.plugins.intelliLang.util.StringMatcher; import org.jaxen.JaxenException; import org.jaxen.XPath; @@ -60,7 +60,7 @@ public class AbstractTagInjection extends BaseInjection { private boolean myApplyToSubTagTexts; public AbstractTagInjection() { - super(LanguageInjectionSupport.XML_SUPPORT_ID); + super(XmlLanguageInjectionSupport.XML_SUPPORT_ID); } @NotNull diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java index 8ab26e303bde..89ea02a4d029 100644 --- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java +++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java @@ -24,15 +24,13 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogBuilder; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Factory; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.patterns.*; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.xml.XmlAttribute; -import com.intellij.psi.xml.XmlAttributeValue; -import com.intellij.psi.xml.XmlTag; -import com.intellij.psi.xml.XmlText; +import com.intellij.psi.xml.*; import com.intellij.util.Consumer; import com.intellij.util.PlatformIcons; import com.intellij.util.containers.ContainerUtil; @@ -48,6 +46,7 @@ import org.intellij.plugins.intelliLang.inject.config.ui.XmlTagPanel; import org.intellij.plugins.intelliLang.inject.config.ui.configurables.XmlAttributeInjectionConfigurable; import org.intellij.plugins.intelliLang.inject.config.ui.configurables.XmlTagInjectionConfigurable; import org.jdom.Element; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -60,6 +59,8 @@ import java.util.Collections; */ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSupport { + @NonNls public static final String XML_SUPPORT_ID = "xml"; + private static boolean isMine(final PsiLanguageInjectionHost host) { if (host instanceof XmlAttributeValue) { final PsiElement p = host.getParent(); @@ -85,8 +86,16 @@ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSuppor return new Class[] {XmlPatterns.class}; } - public boolean useDefaultInjector(final PsiElement host) { - return false; + @Override + public boolean isApplicableTo(PsiLanguageInjectionHost host) { + return host instanceof XmlElement; + } + + @Nullable + @Override + public BaseInjection findInjectionComment(@NotNull PsiElement host, @Nullable Ref commentRef) { + if (host instanceof XmlAttributeValue) return null; + return InjectorUtils.findCommentInjection(host instanceof XmlText ? host.getParent() : host, getId(), commentRef); } @Override diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java index a05a24426dc9..f8026edb4f11 100644 --- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java +++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java @@ -63,7 +63,7 @@ public final class XmlLanguageInjector implements MultiHostInjector { public XmlLanguageInjector(Configuration configuration) { myConfiguration = configuration; - mySupport = InjectorUtils.findNotNullInjectionSupport(LanguageInjectionSupport.XML_SUPPORT_ID); + mySupport = InjectorUtils.findNotNullInjectionSupport(XmlLanguageInjectionSupport.XML_SUPPORT_ID); } @NotNull @@ -104,7 +104,7 @@ public final class XmlLanguageInjector implements MultiHostInjector { if (place instanceof XmlTag) { final XmlTag xmlTag = (XmlTag)place; - List injections = myConfiguration.getInjections(LanguageInjectionSupport.XML_SUPPORT_ID); + List injections = myConfiguration.getInjections(XmlLanguageInjectionSupport.XML_SUPPORT_ID); //noinspection ForLoopReplaceableByForEach for (int i = 0, injectionsSize = injections.size(); i < injectionsSize; i++) { final BaseInjection injection = injections.get(i); @@ -168,7 +168,7 @@ public final class XmlLanguageInjector implements MultiHostInjector { return; } - List injections = myConfiguration.getInjections(LanguageInjectionSupport.XML_SUPPORT_ID); + List injections = myConfiguration.getInjections(XmlLanguageInjectionSupport.XML_SUPPORT_ID); //noinspection ForLoopReplaceableByForEach for (int i = 0, size = injections.size(); i < size; i++) { BaseInjection injection = injections.get(i); @@ -236,7 +236,7 @@ public final class XmlLanguageInjector implements MultiHostInjector { Trinity> index = myXmlIndex; if (index == null || myConfiguration.getModificationCount() != index.first.longValue()) { final Map, BaseInjection> map = new THashMap, BaseInjection>(); - for (BaseInjection injection : myConfiguration.getInjections(LanguageInjectionSupport.XML_SUPPORT_ID)) { + for (BaseInjection injection : myConfiguration.getInjections(XmlLanguageInjectionSupport.XML_SUPPORT_ID)) { for (InjectionPlace place : injection.getInjectionPlaces()) { if (!place.isEnabled() || place.getElementPattern() == null) continue; map.put(place.getElementPattern(), injection); diff --git a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationInjector.java b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationInjector.java index b83f706e9796..9125490442ee 100644 --- a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationInjector.java +++ b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationInjector.java @@ -15,16 +15,14 @@ */ package org.intellij.plugins.intelliLang.inject.groovy; -import com.intellij.lang.Language; import com.intellij.lang.injection.MultiHostInjector; import com.intellij.lang.injection.MultiHostRegistrar; 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.*; import org.intellij.plugins.intelliLang.Configuration; -import org.intellij.plugins.intelliLang.inject.InjectedLanguage; import org.intellij.plugins.intelliLang.inject.InjectorUtils; +import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; import org.intellij.plugins.intelliLang.util.AnnotationUtilEx; import org.intellij.plugins.intelliLang.util.PsiUtilEx; @@ -94,23 +92,14 @@ public class GrConcatenationInjector implements MultiHostInjector { final PsiAnnotation[] annotations = getAnnotationFrom(annotationOwner, pair, true, true); if (annotations.length > 0) { - final String id = AnnotationUtilEx.calcAnnotationValue(annotations, "value"); - final String prefix = AnnotationUtilEx.calcAnnotationValue(annotations, "prefix"); - final String suffix = AnnotationUtilEx.calcAnnotationValue(annotations, "suffix"); - final BaseInjection injection = new BaseInjection(GroovyLanguageInjectionSupport.GROOVY_SUPPORT_ID); - if (prefix != null) injection.setPrefix(prefix); - if (suffix != null) injection.setSuffix(suffix); - if (id != null) injection.setInjectedLanguageId(id); + BaseInjection injection = new BaseInjection(GroovyLanguageInjectionSupport.GROOVY_SUPPORT_ID); - //todo suffixes & prefixes are not supported - final Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId()); + injection.setPrefix(StringUtil.notNullize(AnnotationUtilEx.calcAnnotationValue(annotations, "prefix"))); + injection.setSuffix(StringUtil.notNullize(AnnotationUtilEx.calcAnnotationValue(annotations, "suffix"))); + injection.setInjectedLanguageId(StringUtil.notNullize(AnnotationUtilEx.calcAnnotationValue(annotations, "value"))); - Trinity info = Trinity.create( - host, - InjectedLanguage.create(injection.getInjectedLanguageId(), prefix, suffix, true), - ElementManipulators.getManipulator(host).getRangeInElement(host) - ); - InjectorUtils.registerInjection(language, Collections.singletonList(info), host.getContainingFile(), registrar); + LanguageInjectionSupport support = InjectorUtils.findInjectionSupport(GroovyLanguageInjectionSupport.GROOVY_SUPPORT_ID); + InjectorUtils.registerInjectionSimple(host, injection, support, registrar); } } diff --git a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GroovyLanguageInjectionSupport.java b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GroovyLanguageInjectionSupport.java index 452bca159bd8..564677a2936f 100644 --- a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GroovyLanguageInjectionSupport.java +++ b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GroovyLanguageInjectionSupport.java @@ -62,10 +62,15 @@ public class GroovyLanguageInjectionSupport extends AbstractLanguageInjectionSup return new Class[] {GroovyPatterns.class}; } - public boolean useDefaultInjector(final PsiElement host) { + @Override + public boolean isApplicableTo(PsiLanguageInjectionHost host) { return host instanceof GroovyPsiElement; } + public boolean useDefaultInjector(PsiLanguageInjectionHost host) { + return true; + } + @Override public String getHelpId() { return "reference.settings.language.injection.groovy";