mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
dev-time pattern injection
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
package com.intellij.patterns.compiler;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Gregory.Shrago
|
||||
@@ -25,5 +27,19 @@ public abstract class PatternCompilerFactory {
|
||||
return ServiceManager.getService(PatternCompilerFactory.class);
|
||||
}
|
||||
|
||||
public abstract <T> PatternCompiler<T> getPatternCompiler(Class[] patternClasses);
|
||||
/**
|
||||
* Retrieves pattern classes registered via com.intellij.patterns.patternClass extension.
|
||||
* @param alias or null
|
||||
* @return pattern classes
|
||||
*/
|
||||
@NotNull
|
||||
public abstract Class[] getPatternClasses(@Nullable final String alias);
|
||||
|
||||
@NotNull
|
||||
public abstract <T> PatternCompiler<T> getPatternCompiler(@NotNull Class[] patternClasses);
|
||||
|
||||
@NotNull
|
||||
public <T> PatternCompiler<T> getPatternCompiler(@Nullable final String alias) {
|
||||
return getPatternCompiler(getPatternClasses(alias));
|
||||
}
|
||||
}
|
||||
|
||||
+40
-2
@@ -15,13 +15,51 @@
|
||||
*/
|
||||
package com.intellij.patterns.compiler;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Gregory.Shrago
|
||||
*/
|
||||
public class PatternCompilerFactoryImpl extends PatternCompilerFactory {
|
||||
public static final ExtensionPointName<PatternClassBean> PATTERN_CLASS_EP =
|
||||
new ExtensionPointName<PatternClassBean>("com.intellij.patterns.patternClass");
|
||||
|
||||
|
||||
private final Map<String, Class[]> myClasses = new FactoryMap<String, Class[]>() {
|
||||
@Override
|
||||
protected Class[] create(String key) {
|
||||
final ArrayList<Class> result = new ArrayList<Class>(1);
|
||||
final List<String> typeList = key == null? null : Arrays.asList(key.split(",|\\s"));
|
||||
for (PatternClassBean bean : PATTERN_CLASS_EP.getExtensions()) {
|
||||
if (typeList == null || typeList.contains(bean.getAlias())) result.add(bean.getPatternClass());
|
||||
}
|
||||
return result.isEmpty()? ArrayUtil.EMPTY_CLASS_ARRAY : result.toArray(new Class[result.size()]);
|
||||
}
|
||||
};
|
||||
private final Map<Class[], PatternCompiler> myCompilers = new FactoryMap<Class[], PatternCompiler>() {
|
||||
@Override
|
||||
protected PatternCompiler create(Class[] key) {
|
||||
return new PatternCompilerImpl(key);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> PatternCompiler<T> getPatternCompiler(Class[] patternClasses) {
|
||||
return new PatternCompilerImpl<T>(patternClasses);
|
||||
public Class[] getPatternClasses(String alias) {
|
||||
return myClasses.get(alias);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> PatternCompiler<T> getPatternCompiler(@NotNull Class[] patternClasses) {
|
||||
return myCompilers.get(patternClasses);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,31 +18,23 @@ package com.intellij.psi;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.CustomLoadingExtensionPointBean;
|
||||
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.StandardPatterns;
|
||||
import com.intellij.patterns.compiler.PatternCompiler;
|
||||
import com.intellij.patterns.compiler.PatternCompilerFactory;
|
||||
import com.intellij.util.xmlb.annotations.AbstractCollection;
|
||||
import com.intellij.util.xmlb.annotations.Property;
|
||||
import com.intellij.util.xmlb.annotations.Tag;
|
||||
import com.intellij.util.xmlb.annotations.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PsiReferenceProviderBean extends CustomLoadingExtensionPointBean {
|
||||
public class PsiReferenceProviderBean extends AbstractExtensionPointBean {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiReferenceProviderBean");
|
||||
@Tag("className")
|
||||
public String className;
|
||||
@Tag("description")
|
||||
public String description;
|
||||
|
||||
@Property(surroundWithTag = false)
|
||||
@AbstractCollection(surroundWithTag = false, elementTag = "patternClass", elementValueAttribute = "")
|
||||
public List<String> patternClasses = new ArrayList<String>();
|
||||
@Property(surroundWithTag = false)
|
||||
@AbstractCollection(surroundWithTag = false, elementTag = "pattern", elementValueAttribute = "")
|
||||
public List<String> patterns = new ArrayList<String>();
|
||||
@AbstractCollection(surroundWithTag = false)
|
||||
public Info[] patterns;
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
@@ -50,7 +42,7 @@ public class PsiReferenceProviderBean extends CustomLoadingExtensionPointBean {
|
||||
|
||||
public PsiReferenceProvider instantiate() {
|
||||
try {
|
||||
return (PsiReferenceProvider)instantiateExtension(className, ApplicationManager.getApplication().getPicoContainer());
|
||||
return (PsiReferenceProvider)instantiate(className, ApplicationManager.getApplication().getPicoContainer());
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
LOG.error(e);
|
||||
@@ -60,30 +52,28 @@ public class PsiReferenceProviderBean extends CustomLoadingExtensionPointBean {
|
||||
|
||||
@Nullable
|
||||
public ElementPattern<PsiElement> createElementPattern() {
|
||||
final ArrayList<Class> classes = new ArrayList<Class>();
|
||||
for (String patternClass : patternClasses) {
|
||||
try {
|
||||
classes.add(Class.forName(patternClass, true, getLoaderForClass()));
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
LOG.error(e);
|
||||
final PatternCompilerFactory factory = PatternCompilerFactory.getFactory();
|
||||
if (patterns.length > 1) {
|
||||
final ElementPattern[] result = new ElementPattern[this.patterns.length];
|
||||
for (int i = 0, len = this.patterns.length; i < len; i++) {
|
||||
result[i] = factory.getPatternCompiler(patterns[i].type).compileElementPattern(patterns[i].text);
|
||||
}
|
||||
return StandardPatterns.or(result);
|
||||
}
|
||||
final PatternCompiler<PsiElement> compiler =
|
||||
PatternCompilerFactory.getFactory().getPatternCompiler(classes.toArray(new Class[classes.size()]));
|
||||
if (patterns.size() > 1) {
|
||||
final ElementPattern[] patterns = new ElementPattern[this.patterns.size()];
|
||||
for (int i = 0, len = this.patterns.size(); i < len; i++) {
|
||||
patterns[i] = compiler.compileElementPattern(this.patterns.get(i));
|
||||
}
|
||||
return StandardPatterns.or(patterns);
|
||||
}
|
||||
else if (!patterns.isEmpty()) {
|
||||
return compiler.compileElementPattern(patterns.get(0));
|
||||
else if (patterns.length == 1) {
|
||||
return factory.<PsiElement>getPatternCompiler(patterns[0].type).compileElementPattern(patterns[0].text);
|
||||
}
|
||||
else {
|
||||
LOG.error("At least one pattern should be specified");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Tag("pattern")
|
||||
public static class Info {
|
||||
@Attribute("type")
|
||||
public String type;
|
||||
@Text
|
||||
public String text;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,18 +39,10 @@ public class PatternCompilerImpl<T> implements PatternCompiler<T> {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(PatternCompilerImpl.class.getName());
|
||||
|
||||
private final Class[] myPatternClasses;
|
||||
private Set<Method> myStaticMethods;
|
||||
|
||||
public PatternCompilerImpl(final Class[] patternClasses) {
|
||||
myPatternClasses = patternClasses;
|
||||
}
|
||||
|
||||
private Set<Method> getStaticMethods() {
|
||||
if (myStaticMethods == null) {
|
||||
myStaticMethods = getStaticMethods(myPatternClasses);
|
||||
}
|
||||
return myStaticMethods;
|
||||
myStaticMethods = getStaticMethods(patternClasses);
|
||||
}
|
||||
|
||||
protected void preInvoke(Object target, String methodName, Object[] arguments) {
|
||||
@@ -71,13 +63,12 @@ public class PatternCompilerImpl<T> implements PatternCompiler<T> {
|
||||
|
||||
@Override
|
||||
public ElementPattern<T> compileElementPattern(final String text) {
|
||||
final Set<Method> staticMethods = getStaticMethods();
|
||||
return processElementPatternText(text, new Function<Frame, Object>() {
|
||||
public Object fun(final Frame frame) {
|
||||
try {
|
||||
final Object[] args = frame.params.toArray();
|
||||
preInvoke(frame.target, frame.methodName, args);
|
||||
return invokeMethod(frame.target, frame.methodName, args, staticMethods);
|
||||
return invokeMethod(frame.target, frame.methodName, args, myStaticMethods);
|
||||
}
|
||||
catch (Throwable throwable) {
|
||||
throw new IllegalArgumentException(text, throwable);
|
||||
@@ -338,12 +329,11 @@ public class PatternCompilerImpl<T> implements PatternCompiler<T> {
|
||||
|
||||
@Override
|
||||
public String dumpContextDeclarations() {
|
||||
final Set<Method> methods = getStaticMethods();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final THashMap<Class, Collection<Class>> classes = new THashMap<Class, Collection<Class>>();
|
||||
final THashSet<Class> missingClasses = new THashSet<Class>();
|
||||
classes.put(Object.class, missingClasses);
|
||||
for (Method method : methods) {
|
||||
for (Method method : myStaticMethods) {
|
||||
for (Class<?> type = method.getReturnType(); type != null && ElementPattern.class.isAssignableFrom(type); type = type.getSuperclass()) {
|
||||
final Class<?> enclosingClass = type.getEnclosingClass();
|
||||
if (enclosingClass != null) {
|
||||
@@ -363,7 +353,7 @@ public class PatternCompilerImpl<T> implements PatternCompiler<T> {
|
||||
if (aClass == Object.class) continue;
|
||||
printClass(aClass, classes, sb);
|
||||
}
|
||||
for (Method method : methods) {
|
||||
for (Method method : myStaticMethods) {
|
||||
printMethodDeclaration(method, sb, classes);
|
||||
}
|
||||
for (Class aClass : missingClasses) {
|
||||
|
||||
@@ -259,6 +259,7 @@
|
||||
|
||||
<extensionPoint name="psi.referenceContributor" interface="com.intellij.psi.PsiReferenceContributor"/>
|
||||
<extensionPoint name="psi.referenceProvider" beanClass="com.intellij.psi.PsiReferenceProviderBean"/>
|
||||
<extensionPoint name="patterns.patternClass" beanClass="com.intellij.patterns.compiler.PatternClassBean"/>
|
||||
|
||||
<extensionPoint name="pom.declarationSearcher" interface="com.intellij.pom.PomDeclarationSearcher"/>
|
||||
|
||||
|
||||
@@ -267,6 +267,8 @@
|
||||
|
||||
<webBrowserUrlProvider implementation="com.intellij.ide.browsers.HtmlWebBrowserUrlProvider" id="static" order="last"/>
|
||||
|
||||
<patterns.patternClass className="com.intellij.patterns.XmlPatterns" alias="xml"/>
|
||||
|
||||
<lang.smartEnterProcessor language="XML" implementationClass="com.intellij.codeInsight.completion.XmlSmartEnterProcessor"/>
|
||||
<lang.smartEnterProcessor language="HTML" implementationClass="com.intellij.codeInsight.completion.XmlSmartEnterProcessor"/>
|
||||
<lang.smartEnterProcessor language="XHTML" implementationClass="com.intellij.codeInsight.completion.XmlSmartEnterProcessor"/>
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="LanguageInjectionConfiguration">
|
||||
<injection language="Groovy" injector-id="xml">
|
||||
<display-name>IntelliJ IDEA pattern</display-name>
|
||||
<place><![CDATA[xmlTag().withLocalName("place").withParent(xmlTag().withLocalName("injection").withParent(xmlTag().withLocalName("component")))]]></place>
|
||||
<place><![CDATA[xmlTag().withLocalName("pattern").inside(xmlTag().withLocalName("idea-plugin"))]]></place>
|
||||
</injection>
|
||||
<injection language="XPath" injector-id="xml">
|
||||
<display-name>JAXB attribute node</display-name>
|
||||
<place><![CDATA[xmlAttribute().withLocalName(string().equalTo("node")).inside(xmlTag().withLocalName(string().equalTo("bindings")).withNamespace(string().equalTo("http://java.sun.com/xml/ns/jaxb")))]]></place>
|
||||
|
||||
@@ -250,6 +250,8 @@
|
||||
<indexedRootsProvider implementation="org.jetbrains.plugins.groovy.dsl.StandardDslIndexedRootsProvider"/>
|
||||
<fileBasedIndex implementation="org.jetbrains.plugins.groovy.dsl.GroovyDslFileIndex"/>
|
||||
|
||||
<patterns.patternClass className="org.jetbrains.plugins.groovy.lang.psi.patterns.GroovyPatterns" alias="groovy"/>
|
||||
|
||||
<!-- control flow -->
|
||||
<intentionAction>
|
||||
<bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
|
||||
|
||||
+107
-16
@@ -15,26 +15,44 @@
|
||||
*/
|
||||
package org.intellij.plugins.intelliLang.inject.groovy;
|
||||
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.AtomicNotNullLazyValue;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.UserDataHolderEx;
|
||||
import com.intellij.patterns.compiler.PatternCompilerImpl;
|
||||
import com.intellij.patterns.compiler.PatternClassBean;
|
||||
import com.intellij.patterns.compiler.PatternCompilerFactory;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.FileContextUtil;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.TextOccurenceProcessor;
|
||||
import com.intellij.psi.search.UsageSearchContext;
|
||||
import com.intellij.psi.util.CachedValue;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.psi.xml.XmlText;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.intellij.plugins.intelliLang.inject.InjectorUtils;
|
||||
import org.intellij.plugins.intelliLang.inject.config.BaseInjection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Gregory.Shrago
|
||||
*/
|
||||
public class PatternEditorContextMembersProvider extends NonCodeMembersContributor {
|
||||
|
||||
public static final Key<AtomicNotNullLazyValue<PsiFile>> INJECTION_PARSED_CONTEXT = Key.create("INJECTION_PARSED_CONTEXT");
|
||||
public static final Key<CachedValue<List<PsiElement>>> INJECTION_PARSED_CONTEXT = Key.create("INJECTION_PARSED_CONTEXT");
|
||||
|
||||
@Override
|
||||
public void processDynamicElements(@NotNull PsiType qualifierType,
|
||||
@@ -43,22 +61,95 @@ public class PatternEditorContextMembersProvider extends NonCodeMembersContribut
|
||||
ResolveState state) {
|
||||
final PsiFile file = place.getContainingFile().getOriginalFile();
|
||||
final BaseInjection injection = file.getUserData(BaseInjection.INJECTION_KEY);
|
||||
if (injection == null) return;
|
||||
final PsiFile contextFile =
|
||||
((UserDataHolderEx)file).putUserDataIfAbsent(INJECTION_PARSED_CONTEXT, new AtomicNotNullLazyValue<PsiFile>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PsiFile compute() {
|
||||
return parseInjectionContext(injection, file.getProject());
|
||||
}
|
||||
}).getValue();
|
||||
for (PsiElement cur = contextFile.getFirstChild(); cur != null; cur = cur.getNextSibling()) {
|
||||
if (cur instanceof PsiNamedElement && !ResolveUtil.processElement(processor, (PsiNamedElement)cur)) return;
|
||||
final CachedValueProvider<List<PsiElement>> provider;
|
||||
if (injection == null) {
|
||||
provider = createDevProvider(file);
|
||||
}
|
||||
else {
|
||||
provider = createPatternProvider(injection, file);
|
||||
}
|
||||
if (provider == null) return;
|
||||
final List<PsiElement> roots =
|
||||
((UserDataHolderEx)file).putUserDataIfAbsent(INJECTION_PARSED_CONTEXT,
|
||||
CachedValuesManager.getManager(file.getProject()).createCachedValue(provider, false)).getValue();
|
||||
for (PsiElement root : roots) {
|
||||
for (PsiElement cur = root.getFirstChild(); cur != null; cur = cur.getNextSibling()) {
|
||||
if (cur instanceof PsiNamedElement && !ResolveUtil.processElement(processor, (PsiNamedElement)cur)) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiFile parseInjectionContext(@NotNull BaseInjection injection, Project project) {
|
||||
final String text = new PatternCompilerImpl(InjectorUtils.findInjectionSupport(injection.getSupportId()).getPatternClasses()).dumpContextDeclarations();
|
||||
private static CachedValueProvider<List<PsiElement>> createPatternProvider(final BaseInjection injection, final PsiFile file) {
|
||||
return new CachedValueProvider<List<PsiElement>>() {
|
||||
@Override
|
||||
public Result<List<PsiElement>> compute() {
|
||||
return new Result<List<PsiElement>>(Collections.<PsiElement>singletonList(
|
||||
getRootByClasses(InjectorUtils.findInjectionSupport(injection.getSupportId()).getPatternClasses(), file.getProject())),
|
||||
ArrayUtil.EMPTY_OBJECT_ARRAY);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static PsiFile getRootByClasses(Class[] classes, Project project) {
|
||||
final String text = PatternCompilerFactory.getFactory().getPatternCompiler(classes).dumpContextDeclarations();
|
||||
return PsiFileFactory.getInstance(project).createFileFromText("context.groovy", GroovyFileType.GROOVY_FILE_TYPE, text);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static CachedValueProvider<List<PsiElement>> createDevProvider(final PsiFile file) {
|
||||
final SmartPsiElementPointer pointer = file.getUserData(FileContextUtil.INJECTED_IN_ELEMENT);
|
||||
if (pointer == null) return null;
|
||||
final PsiElement element = pointer.getElement();
|
||||
if (!(element instanceof XmlText)) return null;
|
||||
final XmlTag tag = ((XmlText)element).getParentTag();
|
||||
final XmlTag parentTag = tag == null ? null : tag.getParentTag();
|
||||
final String parentTagName = parentTag == null ? null : parentTag.getName();
|
||||
final String name = tag == null ? null : tag.getName();
|
||||
if ("place".equals(name) && "injection".equals(parentTagName) && parentTag != null) {
|
||||
return new CachedValueProvider<List<PsiElement>>() {
|
||||
@Override
|
||||
public Result<List<PsiElement>> compute() {
|
||||
return new Result<List<PsiElement>>(getRootsByClassNames(file, parentTag.getAttributeValue("injector-id")), parentTag.getContainingFile());
|
||||
}
|
||||
};
|
||||
}
|
||||
else if ("pattern".equals(name) && parentTag != null) {
|
||||
return new CachedValueProvider<List<PsiElement>>() {
|
||||
@Override
|
||||
public Result<List<PsiElement>> compute() {
|
||||
return new Result<List<PsiElement>>(getRootsByClassNames(file, tag.getAttributeValue("type")), parentTag.getContainingFile());
|
||||
}
|
||||
};
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
|
||||
private static List<PsiElement> getRootsByClassNames(PsiFile file, String type) {
|
||||
final ArrayList<PsiElement> roots = new ArrayList<PsiElement>(1);
|
||||
|
||||
final Project project = file.getProject();
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
|
||||
final PsiClass beanClass = psiFacade.findClass(PatternClassBean.class.getName(), GlobalSearchScope.allScope(project));
|
||||
if (beanClass != null) {
|
||||
final GlobalSearchScope scope =
|
||||
GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), StdFileTypes.XML);
|
||||
beanClass.getManager().getSearchHelper().processElementsWithWord(new TextOccurenceProcessor() {
|
||||
@Override
|
||||
public boolean execute(PsiElement element, int offsetInElement) {
|
||||
final XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class);
|
||||
final String className = tag == null ? null : tag.getAttributeValue("className");
|
||||
if (className != null && tag.getLocalName().endsWith("patternClass")) {
|
||||
ContainerUtil.addIfNotNull(psiFacade.findClass(className, GlobalSearchScope.allScope(project)), roots);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}, scope, "patterns.patternClass", UsageSearchContext.IN_FOREIGN_LANGUAGES, true);
|
||||
}
|
||||
final Class[] classes = PatternCompilerFactory.getFactory().getPatternClasses(type);
|
||||
if (classes.length != 0) {
|
||||
roots.add(getRootByClasses(classes, project));
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -915,6 +915,8 @@
|
||||
<patternDialectProvider implementation="com.intellij.packageDependencies.ui.PackagePatternProvider" id="package" order="before file" />
|
||||
<scopeDescriptorProvider implementation="com.intellij.ide.util.scopeChooser.HierarchyScopeDescriptorProvider"/>
|
||||
|
||||
<patterns.patternClass className="com.intellij.patterns.PsiJavaPatterns" alias="java"/>
|
||||
|
||||
<customScopesProvider implementation="com.intellij.analysis.PackagesScopesProvider"/>
|
||||
|
||||
<highlightErrorFilter implementation="com.intellij.codeInsight.daemon.impl.analysis.JavadocErrorFilter"/>
|
||||
|
||||
@@ -63,5 +63,7 @@
|
||||
<pom.declarationSearcher implementation="com.intellij.util.xml.impl.DomDeclarationSearcher"/>
|
||||
<elementDescriptionProvider implementation="com.intellij.util.xml.impl.DefaultDomTargetDescriptionProvider" id="domDefault" order="last, before pomDefault"/>
|
||||
<iconProvider implementation="com.intellij.util.xml.impl.DefaultDomTargetIconProvider" id="domDefault" order="last"/>
|
||||
|
||||
<patterns.patternClass className="com.intellij.patterns.DomPatterns" alias="dom"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
Reference in New Issue
Block a user