mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Extensible comment injector API
This commit is contained in:
+2
-2
@@ -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<String, MethodInfo> myParameterMap = new THashMap<String, MethodInfo>();
|
||||
|
||||
public MethodParameterInjection() {
|
||||
super(LanguageInjectionSupport.JAVA_SUPPORT_ID);
|
||||
super(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+9
-7
@@ -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<Collection<String>>() {
|
||||
public Result<Collection<String>> compute() {
|
||||
final Map<ElementPattern<?>, BaseInjection> map = new THashMap<ElementPattern<?>, 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<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> 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<PsiComment> causeRef = Ref.create();
|
||||
Ref<PsiElement> 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);
|
||||
|
||||
+15
-5
@@ -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<BaseInjection> originalInjections = new ArrayList<BaseInjection>(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<BaseInjection, Pair<PsiMethod, Integer>> injectionsMap,
|
||||
final ArrayList<PsiElement> annotations) {
|
||||
new ConcatenationInjector.InjectionProcessor(configuration, host) {
|
||||
new ConcatenationInjector.InjectionProcessor(configuration, support, host) {
|
||||
|
||||
@Override
|
||||
protected boolean processCommentInjectionInner(PsiVariable owner, PsiElement comment, BaseInjection injection) {
|
||||
|
||||
@@ -186,14 +186,10 @@ public class Configuration implements PersistentStateComponent<Element>, 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<Element>, 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<Element>, 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<BaseInjection>() {
|
||||
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<BaseInjection>() {
|
||||
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<BaseInjection>() {
|
||||
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<Element>, Modific
|
||||
return element;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private static <T extends BaseInjection> List<T> readExternal(Element element, Factory<T> factory) {
|
||||
final List<T> injections = new ArrayList<T>();
|
||||
if (element != null) {
|
||||
final List<Element> 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);
|
||||
}
|
||||
|
||||
+14
-1
@@ -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<PsiElement> commentRef) {
|
||||
return InjectorUtils.findCommentInjection(host, "comment", commentRef);
|
||||
}
|
||||
|
||||
public boolean addInjectionInPlace(final Language language, final PsiLanguageInjectionHost psiElement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+45
-21
@@ -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<LanguageInjectionSupport> supports = new ArrayList<LanguageInjectionSupport>(InjectorUtils.getActiveInjectionSupports());
|
||||
supports.add(myInjectorSupport);
|
||||
mySupports = ArrayUtil.toObjectArray(supports, LanguageInjectionSupport.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<? extends Class<? extends PsiElement>> 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<PsiLanguageInjectionHost> 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.<PsiComment>create());
|
||||
//BaseInjection injection = InjectorUtils.findCommentInjection(context, "comment", Ref.<PsiComment>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<PsiLanguageInjectionHost, InjectedLanguage, TextRange> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-25
@@ -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<TextRange> ranges = injection.getInjectedArea(host);
|
||||
final List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> list =
|
||||
new ArrayList<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -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");
|
||||
|
||||
@@ -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<TextRange> ranges = injection.getInjectedArea(host);
|
||||
List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> 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<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?
|
||||
@@ -196,12 +220,12 @@ public class InjectorUtils {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static BaseInjection findCommentInjection(PsiElement context, final String supportId, final Ref<PsiComment> causeRef) {
|
||||
public static BaseInjection findCommentInjection(PsiElement context, final String supportId, final Ref<PsiElement> causeRef) {
|
||||
return findNearestComment(context, new NullableFunction<PsiComment, BaseInjection>() {
|
||||
@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);
|
||||
}
|
||||
|
||||
+8
-4
@@ -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<LanguageInjectionSupport> INJECTOR_SUPPORT = Key.create("INJECTOR_SUPPORT");
|
||||
public static Key<LanguageInjectionSupport> 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<PsiElement> commentRef);
|
||||
|
||||
public abstract boolean addInjectionInPlace(final Language language, final PsiLanguageInjectionHost psiElement);
|
||||
|
||||
|
||||
+10
-8
@@ -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<PsiLanguageInjectionHost> manipulator = ElementManipulators.getManipulator(host);
|
||||
if (manipulator == null) return;
|
||||
List<Trinity<PsiLanguageInjectionHost, InjectedLanguage,TextRange>> 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<PsiLanguageInjectionHost> manipulator = ElementManipulators.getManipulator(host);
|
||||
if (manipulator == null) return;
|
||||
List<Trinity<PsiLanguageInjectionHost, InjectedLanguage,TextRange>> trinities =
|
||||
Collections.singletonList(Trinity.create(host, injectedLanguage, manipulator.getRangeInElement(host)));
|
||||
InjectorUtils.registerInjection(language, trinities, containingFile, registrar);
|
||||
InjectorUtils.registerSupport(myRegistry.getLanguageInjectionSupport(), false, registrar);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
@@ -50,6 +50,11 @@ public class TemporaryPlacesRegistry {
|
||||
return "temp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicableTo(PsiLanguageInjectionHost host) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Class[] getPatternClasses() {
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+15
-6
@@ -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<PsiElement> commentRef) {
|
||||
if (host instanceof XmlAttributeValue) return null;
|
||||
return InjectorUtils.findCommentInjection(host instanceof XmlText ? host.getParent() : host, getId(), commentRef);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-4
@@ -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<BaseInjection> injections = myConfiguration.getInjections(LanguageInjectionSupport.XML_SUPPORT_ID);
|
||||
List<BaseInjection> 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<BaseInjection> injections = myConfiguration.getInjections(LanguageInjectionSupport.XML_SUPPORT_ID);
|
||||
List<BaseInjection> 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<Long, Pattern, Collection<String>> index = myXmlIndex;
|
||||
if (index == null || myConfiguration.getModificationCount() != index.first.longValue()) {
|
||||
final Map<ElementPattern<?>, BaseInjection> map = new THashMap<ElementPattern<?>, 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);
|
||||
|
||||
+8
-19
@@ -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<PsiLanguageInjectionHost, InjectedLanguage, TextRange> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user