IDEA-172671 Support configurable injection into FreeMarker macro calls

This commit is contained in:
peter
2018-01-09 22:31:11 +01:00
parent a1db9f789c
commit 42a5a44925
6 changed files with 45 additions and 16 deletions
@@ -58,6 +58,7 @@ import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.io.IOException;
import java.io.InputStream;
@@ -557,6 +558,17 @@ public class Configuration extends SimpleModificationTracker implements Persiste
return changed;
}
@TestOnly
public void withInjections(List<? extends BaseInjection> injections, Runnable runnable) {
replaceInjections(injections, ContainerUtil.emptyList(), true);
try {
runnable.run();
}
finally {
replaceInjections(ContainerUtil.emptyList(), injections, true);
}
}
public static class AdvancedConfiguration {
// runtime pattern validation instrumentation
@NotNull private InstrumentationType myInstrumentationType = InstrumentationType.ASSERT;
@@ -57,9 +57,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.*;
import java.util.List;
public class InjectLanguageAction implements IntentionAction, LowPriorityAction {
@@ -116,9 +114,14 @@ public class InjectLanguageAction implements IntentionAction, LowPriorityAction
@NotNull PsiFile file) {
if (editor instanceof EditorWindow) return null;
int offset = editor.getCaretModel().getOffset();
PsiLanguageInjectionHost host = PsiTreeUtil.getParentOfType(file.findElementAt(offset), PsiLanguageInjectionHost.class, false);
if (host == null) return null;
return host.isValidHost()? host : null;
FileViewProvider vp = file.getViewProvider();
for (Language language : vp.getLanguages()) {
PsiLanguageInjectionHost host = PsiTreeUtil.getParentOfType(vp.findElementAt(offset, language), PsiLanguageInjectionHost.class, false);
if (host != null && host.isValidHost()) {
return host;
}
}
return null;
}
public void invoke(@NotNull Project project,
@@ -15,6 +15,7 @@
*/
package org.intellij.plugins.intelliLang.inject.config;
import com.intellij.lang.Language;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
@@ -33,6 +34,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.intellij.lang.annotations.RegExp;
import org.intellij.plugins.intelliLang.inject.InjectedLanguage;
import org.intellij.plugins.intelliLang.inject.InjectorUtils;
import org.jdom.CDATA;
import org.jdom.Element;
@@ -70,6 +72,19 @@ public class BaseInjection implements Injection, PersistentStateComponent<Elemen
mySupportId = id;
}
public BaseInjection(@NotNull String supportId, @NotNull String injectedLanguageId, @NotNull String prefix, @NotNull String suffix, @NotNull InjectionPlace... places) {
mySupportId = supportId;
myInjectedLanguageId = injectedLanguageId;
myPrefix = prefix;
mySuffix = suffix;
myPlaces = places;
}
@Nullable
public Language getInjectedLanguage() {
return InjectedLanguage.findLanguageById(myInjectedLanguageId);
}
@NotNull
private InjectionPlace[] myPlaces = InjectionPlace.EMPTY_ARRAY;
@@ -223,7 +238,7 @@ public class BaseInjection implements Injection, PersistentStateComponent<Elemen
return this;
}
public void loadState(Element element) {
public void loadState(@NotNull Element element) {
final PatternCompiler<PsiElement> helper = getCompiler();
myDisplayName = StringUtil.notNullize(element.getChildText("display-name"));
myInjectedLanguageId = StringUtil.notNullize(element.getAttributeValue("language"));
@@ -19,7 +19,6 @@ package org.intellij.plugins.intelliLang.inject.config;
import com.intellij.patterns.ElementPattern;
import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayFactory;
import org.jetbrains.annotations.NotNull;
/**
* @author Gregory.Shrago
@@ -32,10 +31,10 @@ public class InjectionPlace {
public static final ArrayFactory<InjectionPlace> ARRAY_FACTORY = count -> count == 0 ? EMPTY_ARRAY : new InjectionPlace[count];
private final boolean myEnabled;
private final ElementPattern<PsiElement> myElementPattern;
private final ElementPattern<? extends PsiElement> myElementPattern;
public InjectionPlace(final ElementPattern<PsiElement> myElementPattern, final boolean enabled) {
public InjectionPlace(ElementPattern<? extends PsiElement> myElementPattern, boolean enabled) {
this.myElementPattern = myElementPattern;
myEnabled = enabled;
}
@@ -48,7 +47,7 @@ public class InjectionPlace {
return myElementPattern.toString();
}
public ElementPattern<PsiElement> getElementPattern() {
public ElementPattern<? extends PsiElement> getElementPattern() {
return myElementPattern;
}
@@ -118,7 +118,7 @@ public class BaseInjectionPanel extends AbstractInjectionPanel<BaseInjection> {
places.add(new InjectionPlace(myHelper.compileElementPattern(text), enabled));
}
for (InjectionPlace place : places) {
ElementPattern<PsiElement> pattern = place.getElementPattern();
ElementPattern<? extends PsiElement> pattern = place.getElementPattern();
if (pattern instanceof PatternCompilerImpl.LazyPresentablePattern) {
try {
((PatternCompilerImpl.LazyPresentablePattern)pattern).compile();
@@ -183,9 +183,9 @@ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSuppor
AbstractTagInjection result;
final InjectionPlace place = injection.getInjectionPlaces()[0];
final ElementPattern<PsiElement> rootPattern = place.getElementPattern();
final ElementPatternCondition<PsiElement> rootCondition = rootPattern.getCondition();
final Class<PsiElement> elementClass = rootCondition.getInitialCondition().getAcceptedClass();
final ElementPattern<? extends PsiElement> rootPattern = place.getElementPattern();
final ElementPatternCondition<? extends PsiElement> rootCondition = rootPattern.getCondition();
final Class<? extends PsiElement> elementClass = rootCondition.getInitialCondition().getAcceptedClass();
if (XmlAttribute.class.equals(elementClass)) {
result = new XmlAttributeInjection().copyFrom(injection);
}
@@ -194,7 +194,7 @@ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSuppor
}
else return null;
result.setInjectionPlaces(InjectionPlace.EMPTY_ARRAY);
for (PatternCondition<? super PsiElement> condition : rootCondition.getConditions()) {
for (PatternCondition<?> condition : rootCondition.getConditions()) {
final String value = extractValue(condition);
if ("withLocalName".equals(condition.getDebugMethodName())) {
if (value == null) return null;