PsiReferenceProviderBean per language

This commit is contained in:
Dmitry Avdeev
2011-05-12 16:03:10 +04:00
parent 60ea556c14
commit 123e3e04ba
2 changed files with 49 additions and 34 deletions
@@ -16,6 +16,7 @@
package com.intellij.psi;
import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
@@ -23,6 +24,7 @@ import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.ElementPatternBean;
import com.intellij.patterns.StandardPatterns;
import com.intellij.util.KeyedLazyInstance;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.annotations.AbstractCollection;
@@ -31,13 +33,19 @@ import com.intellij.util.xmlb.annotations.Property;
import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* Registers a {@link PsiReferenceProvider} in plugin.xml
*/
public class PsiReferenceProviderBean extends AbstractExtensionPointBean {
public class PsiReferenceProviderBean extends AbstractExtensionPointBean implements KeyedLazyInstance<PsiReferenceProviderBean> {
public static final ExtensionPointName<PsiReferenceProviderBean> EP_NAME =
new ExtensionPointName<PsiReferenceProviderBean>("com.intellij.psi.referenceProvider");
@Attribute("language")
public String language = Language.ANY.getID();
@Attribute("providerClass")
public String className;
@@ -74,8 +82,9 @@ public class PsiReferenceProviderBean extends AbstractExtensionPointBean {
@Nullable
public ElementPattern<PsiElement> createElementPattern() {
if (patterns.length > 1) {
return StandardPatterns.or(ContainerUtil.mapNotNull(patterns,
PATTERN_NULLABLE_FUNCTION).toArray(new ElementPattern[0]));
List<ElementPattern<? extends PsiElement>> list = ContainerUtil.mapNotNull(patterns, PATTERN_NULLABLE_FUNCTION);
//noinspection unchecked
return StandardPatterns.or(list.toArray(new ElementPattern[list.size()]));
}
else if (patterns.length == 1) {
return patterns[0].compilePattern();
@@ -85,4 +94,14 @@ public class PsiReferenceProviderBean extends AbstractExtensionPointBean {
return null;
}
}
@Override
public String getKey() {
return language;
}
@Override
public PsiReferenceProviderBean getInstance() {
return this;
}
}
@@ -44,7 +44,8 @@ import java.util.Map;
*/
public class ReferenceProvidersRegistry {
private static final LanguageExtension<PsiReferenceContributor> EXTENSION = new LanguageExtension<PsiReferenceContributor>(PsiReferenceContributor.EP_NAME.getName());
private static final LanguageExtension<PsiReferenceContributor> CONTRIBUTOR_EXTENSION = new LanguageExtension<PsiReferenceContributor>(PsiReferenceContributor.EP_NAME.getName());
private static final LanguageExtension<PsiReferenceProviderBean> REFERENCE_PROVIDER_EXTENSION = new LanguageExtension<PsiReferenceProviderBean>(PsiReferenceProviderBean.EP_NAME.getName());
private static final Comparator<Trinity<PsiReferenceProvider, ProcessingContext, Double>> PRIORITY_COMPARATOR =
new Comparator<Trinity<PsiReferenceProvider, ProcessingContext, Double>>() {
@@ -66,10 +67,33 @@ public class ReferenceProvidersRegistry {
@Override
protected PsiReferenceRegistrarImpl create(Language language) {
PsiReferenceRegistrarImpl registrar = new PsiReferenceRegistrarImpl();
List<PsiReferenceContributor> contributors = EXTENSION.allForLanguage(language);
for (PsiReferenceContributor contributor : contributors) {
for (PsiReferenceContributor contributor : CONTRIBUTOR_EXTENSION.allForLanguage(language)) {
contributor.registerReferenceProviders(registrar);
}
List<PsiReferenceProviderBean> referenceProviderBeans = REFERENCE_PROVIDER_EXTENSION.allForLanguage(language);
for (final PsiReferenceProviderBean providerBean : referenceProviderBeans) {
final ElementPattern<PsiElement> pattern = providerBean.createElementPattern();
if (pattern != null) {
registrar.registerReferenceProvider(pattern, new PsiReferenceProvider() {
PsiReferenceProvider myProvider;
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
if (myProvider == null) {
myProvider = providerBean.instantiate();
if (myProvider == null) {
myProvider = NULL_REFERENCE_PROVIDER;
}
}
return myProvider.getReferencesByElement(element, context);
}
});
}
}
return registrar;
}
};
@@ -78,34 +102,6 @@ public class ReferenceProvidersRegistry {
return ServiceManager.getService(ReferenceProvidersRegistry.class);
}
public ReferenceProvidersRegistry() {
PsiReferenceRegistrarImpl registrar = getRegistrar(Language.ANY);
for (final PsiReferenceProviderBean providerBean : PsiReferenceProviderBean.EP_NAME.getExtensions()) {
final ElementPattern<PsiElement> pattern = providerBean.createElementPattern();
if (pattern != null) {
registrar.registerReferenceProvider(pattern, new PsiReferenceProvider() {
PsiReferenceProvider myProvider;
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
if (myProvider == null) {
myProvider = providerBean.instantiate();
if (myProvider == null) {
myProvider = NULL_REFERENCE_PROVIDER;
}
}
return myProvider.getReferencesByElement(element, context);
}
});
}
}
}
public PsiReferenceRegistrarImpl getRegistrar(Language language) {
return myRegistrars.get(language);
}