mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
memory: remember there is no Double instance cache, so each boxed double is a new shiny Double
This commit is contained in:
@@ -87,7 +87,7 @@ public class ImageFileEditorState implements TransferableFileEditorState, Serial
|
||||
|
||||
o = options.get(ZOOM_FACTOR_OPTION);
|
||||
if (o != null) {
|
||||
zoomFactor = Double.valueOf(o);
|
||||
zoomFactor = Double.parseDouble(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-26
@@ -17,7 +17,6 @@
|
||||
package com.intellij.psi.impl.source.resolve.reference;
|
||||
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReferenceProvider;
|
||||
@@ -33,32 +32,37 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* @author maxim
|
||||
*/
|
||||
public abstract class NamedObjectProviderBinding<Provider> implements ProviderBinding<Provider> {
|
||||
private final ConcurrentMap<String, CopyOnWriteArrayList<Trinity<Provider, ElementPattern,Double>>> myNamesToProvidersMap = new ConcurrentHashMap<String, CopyOnWriteArrayList<Trinity<Provider, ElementPattern,Double>>>(5);
|
||||
private final ConcurrentMap<String, CopyOnWriteArrayList<Trinity<Provider, ElementPattern,Double>>> myNamesToProvidersMapInsensitive = new ConcurrentHashMap<String, CopyOnWriteArrayList<Trinity<Provider, ElementPattern,Double>>>(5);
|
||||
private final ConcurrentMap<String, List<ProviderInfo<Provider, ElementPattern>>> myNamesToProvidersMap = new ConcurrentHashMap<String, List<ProviderInfo<Provider,ElementPattern>>>(5);
|
||||
private final ConcurrentMap<String, List<ProviderInfo<Provider, ElementPattern>>> myNamesToProvidersMapInsensitive = new ConcurrentHashMap<String, List<ProviderInfo<Provider, ElementPattern>>>(5);
|
||||
|
||||
public void registerProvider(@NonNls String[] names, ElementPattern filter, boolean caseSensitive, Provider provider, final double priority) {
|
||||
final ConcurrentMap<String, CopyOnWriteArrayList<Trinity<Provider, ElementPattern,Double>>> map = caseSensitive ? myNamesToProvidersMap : myNamesToProvidersMapInsensitive;
|
||||
public void registerProvider(@NonNls @NotNull String[] names,
|
||||
@NotNull ElementPattern filter,
|
||||
boolean caseSensitive,
|
||||
@NotNull Provider provider,
|
||||
final double priority) {
|
||||
final ConcurrentMap<String, List<ProviderInfo<Provider, ElementPattern>>> map = caseSensitive ? myNamesToProvidersMap : myNamesToProvidersMapInsensitive;
|
||||
|
||||
for (final String attributeName : names) {
|
||||
CopyOnWriteArrayList<Trinity<Provider, ElementPattern,Double>> psiReferenceProviders = map.get(attributeName);
|
||||
List<ProviderInfo<Provider, ElementPattern>> psiReferenceProviders = map.get(attributeName);
|
||||
|
||||
if (psiReferenceProviders == null) {
|
||||
psiReferenceProviders = ConcurrencyUtil.cacheOrGet(map, caseSensitive ? attributeName : attributeName.toLowerCase(), ContainerUtil.<Trinity<Provider, ElementPattern, Double>>createEmptyCOWList());
|
||||
String key = caseSensitive ? attributeName : attributeName.toLowerCase();
|
||||
psiReferenceProviders = ConcurrencyUtil.cacheOrGet(map, key, ContainerUtil.<ProviderInfo<Provider,ElementPattern>>createEmptyCOWList());
|
||||
}
|
||||
|
||||
psiReferenceProviders.add(new Trinity<Provider, ElementPattern,Double>(provider, filter, priority));
|
||||
psiReferenceProviders.add(new ProviderInfo<Provider,ElementPattern>(provider, filter, priority));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAcceptableReferenceProviders(@NotNull PsiElement position, @NotNull List list,
|
||||
PsiReferenceService.Hints hints) {
|
||||
public void addAcceptableReferenceProviders(@NotNull PsiElement position,
|
||||
@NotNull List<ProviderInfo<Provider, ProcessingContext>> list,
|
||||
@NotNull PsiReferenceService.Hints hints) {
|
||||
String name = getName(position);
|
||||
if (name != null) {
|
||||
addMatchingProviders(position, myNamesToProvidersMap.get(name), list, hints);
|
||||
@@ -67,17 +71,17 @@ public abstract class NamedObjectProviderBinding<Provider> implements ProviderBi
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterProvider(final Provider provider) {
|
||||
for (final CopyOnWriteArrayList<Trinity<Provider, ElementPattern, Double>> list : myNamesToProvidersMap.values()) {
|
||||
for (final Trinity<Provider, ElementPattern, Double> trinity : new ArrayList<Trinity<Provider, ElementPattern, Double>>(list)) {
|
||||
if (trinity.first.equals(provider)) {
|
||||
public void unregisterProvider(@NotNull final Provider provider) {
|
||||
for (final List<ProviderInfo<Provider, ElementPattern>> list : myNamesToProvidersMap.values()) {
|
||||
for (final ProviderInfo<Provider, ElementPattern> trinity : new ArrayList<ProviderInfo<Provider,ElementPattern>>(list)) {
|
||||
if (trinity.provider.equals(provider)) {
|
||||
list.remove(trinity);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final CopyOnWriteArrayList<Trinity<Provider, ElementPattern, Double>> list : myNamesToProvidersMapInsensitive.values()) {
|
||||
for (final Trinity<Provider, ElementPattern, Double> trinity : new ArrayList<Trinity<Provider, ElementPattern, Double>>(list)) {
|
||||
if (trinity.first.equals(provider)) {
|
||||
for (final List<ProviderInfo<Provider, ElementPattern>> list : myNamesToProvidersMapInsensitive.values()) {
|
||||
for (final ProviderInfo<Provider, ElementPattern> trinity : new ArrayList<ProviderInfo<Provider,ElementPattern>>(list)) {
|
||||
if (trinity.provider.equals(provider)) {
|
||||
list.remove(trinity);
|
||||
}
|
||||
}
|
||||
@@ -85,15 +89,16 @@ public abstract class NamedObjectProviderBinding<Provider> implements ProviderBi
|
||||
}
|
||||
|
||||
@Nullable
|
||||
abstract protected String getName(final PsiElement position);
|
||||
protected abstract String getName(final PsiElement position);
|
||||
|
||||
private static <T> void addMatchingProviders(final PsiElement position, @Nullable final List<Trinity<T, ElementPattern, Double>> providerList,
|
||||
final List<Trinity<T, ProcessingContext, Double>> ret,
|
||||
PsiReferenceService.Hints hints) {
|
||||
private void addMatchingProviders(final PsiElement position,
|
||||
@Nullable final List<ProviderInfo<Provider, ElementPattern>> providerList,
|
||||
@NotNull List<ProviderInfo<Provider, ProcessingContext>> ret,
|
||||
PsiReferenceService.Hints hints) {
|
||||
if (providerList == null) return;
|
||||
|
||||
for(Trinity<T,ElementPattern,Double> trinity:providerList) {
|
||||
if (hints != PsiReferenceService.Hints.NO_HINTS && !((PsiReferenceProvider)trinity.first).acceptsHints(position, hints)) {
|
||||
for(ProviderInfo<Provider, ElementPattern> trinity:providerList) {
|
||||
if (hints != PsiReferenceService.Hints.NO_HINTS && !((PsiReferenceProvider)trinity.provider).acceptsHints(position, hints)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -103,12 +108,12 @@ public abstract class NamedObjectProviderBinding<Provider> implements ProviderBi
|
||||
}
|
||||
boolean suitable = false;
|
||||
try {
|
||||
suitable = trinity.second.accepts(position, context);
|
||||
suitable = trinity.processingContext.accepts(position, context);
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
if (suitable) {
|
||||
ret.add(Trinity.create(trinity.first, context, trinity.third));
|
||||
ret.add(new ProviderInfo<Provider,ProcessingContext>(trinity.provider, context, trinity.priority));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-3
@@ -18,6 +18,7 @@ package com.intellij.psi.impl.source.resolve.reference;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReferenceService;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
@@ -30,8 +31,20 @@ import java.util.List;
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public interface ProviderBinding<T> {
|
||||
void addAcceptableReferenceProviders(@NotNull PsiElement position, @NotNull List list,
|
||||
PsiReferenceService.Hints hints);
|
||||
class ProviderInfo<T, Context> {
|
||||
public final T provider;
|
||||
public final Context processingContext;
|
||||
public final double priority;
|
||||
|
||||
void unregisterProvider(final T provider);
|
||||
public ProviderInfo(@NotNull T provider, @NotNull Context processingContext, double priority) {
|
||||
this.provider = provider;
|
||||
this.processingContext = processingContext;
|
||||
this.priority = priority;
|
||||
}
|
||||
}
|
||||
void addAcceptableReferenceProviders(@NotNull PsiElement position,
|
||||
@NotNull List<ProviderInfo<T, ProcessingContext>> list,
|
||||
@NotNull PsiReferenceService.Hints hints);
|
||||
|
||||
void unregisterProvider(@NotNull T provider);
|
||||
}
|
||||
|
||||
+40
-39
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source.resolve.reference;
|
||||
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.patterns.*;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReferenceProvider;
|
||||
@@ -40,9 +39,8 @@ import java.util.concurrent.ConcurrentMap;
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
|
||||
|
||||
private final ConcurrentMap<Class, SimpleProviderBinding> myBindingsMap = new ConcurrentHashMap<Class, SimpleProviderBinding>();
|
||||
private final ConcurrentMap<Class, NamedObjectProviderBinding> myNamedBindingsMap = new ConcurrentHashMap<Class, NamedObjectProviderBinding>();
|
||||
private final ConcurrentMap<Class, SimpleProviderBinding<PsiReferenceProvider>> myBindingsMap = new ConcurrentHashMap<Class, SimpleProviderBinding<PsiReferenceProvider>>();
|
||||
private final ConcurrentMap<Class, NamedObjectProviderBinding<PsiReferenceProvider>> myNamedBindingsMap = new ConcurrentHashMap<Class, NamedObjectProviderBinding<PsiReferenceProvider>>();
|
||||
private final FactoryMap<Class, Class[]> myKnownSupers = new ConcurrentFactoryMap<Class, Class[]>() {
|
||||
@Override
|
||||
protected Class[] create(Class key) {
|
||||
@@ -71,7 +69,8 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
|
||||
@NotNull Class scope,
|
||||
@NotNull PsiReferenceProvider provider,
|
||||
double priority) {
|
||||
registerReferenceProvider(PlatformPatterns.psiElement(scope).and(new FilterPattern(elementFilter)), provider, priority);
|
||||
PsiElementPattern.Capture<PsiElement> capture = PlatformPatterns.psiElement(scope);
|
||||
registerReferenceProvider(capture.and(new FilterPattern(elementFilter)), provider, priority);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,36 +80,35 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
|
||||
myKnownSupers.clear(); // we should clear the cache
|
||||
final Class scope = pattern.getCondition().getInitialCondition().getAcceptedClass();
|
||||
final List<PatternCondition<? super T>> conditions = pattern.getCondition().getConditions();
|
||||
for (int i = 0, conditionsSize = conditions.size(); i < conditionsSize; i++) {
|
||||
PatternCondition<? super T> _condition = conditions.get(i);
|
||||
if (_condition instanceof PsiNamePatternCondition) {
|
||||
final PsiNamePatternCondition<?> nameCondition = (PsiNamePatternCondition)_condition;
|
||||
List<PatternCondition<? super String>> conditions1 = nameCondition.getNamePattern().getCondition().getConditions();
|
||||
for (int i1 = 0, conditions1Size = conditions1.size(); i1 < conditions1Size; i1++) {
|
||||
PatternCondition<? super String> condition = conditions1.get(i1);
|
||||
if (condition instanceof ValuePatternCondition) {
|
||||
final Collection<String> strings = ((ValuePatternCondition)condition).getValues();
|
||||
registerNamedReferenceProvider(ArrayUtil.toStringArray(strings), nameCondition, scope, true, provider, priority, pattern);
|
||||
return;
|
||||
}
|
||||
if (condition instanceof CaseInsensitiveValuePatternCondition) {
|
||||
final String[] strings = ((CaseInsensitiveValuePatternCondition)condition).getValues();
|
||||
registerNamedReferenceProvider(strings, nameCondition, scope, false, provider, priority, pattern);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
for (PatternCondition<? super T> _condition : conditions) {
|
||||
if (!(_condition instanceof PsiNamePatternCondition)) {
|
||||
continue;
|
||||
}
|
||||
final PsiNamePatternCondition<?> nameCondition = (PsiNamePatternCondition)_condition;
|
||||
List<PatternCondition<? super String>> conditions1 = nameCondition.getNamePattern().getCondition().getConditions();
|
||||
for (PatternCondition<? super String> condition1 : conditions1) {
|
||||
if (condition1 instanceof ValuePatternCondition) {
|
||||
final Collection<String> strings = ((ValuePatternCondition)condition1).getValues();
|
||||
registerNamedReferenceProvider(ArrayUtil.toStringArray(strings), nameCondition, scope, true, provider, priority, pattern);
|
||||
return;
|
||||
}
|
||||
if (condition1 instanceof CaseInsensitiveValuePatternCondition) {
|
||||
final String[] strings = ((CaseInsensitiveValuePatternCondition)condition1).getValues();
|
||||
registerNamedReferenceProvider(strings, nameCondition, scope, false, provider, priority, pattern);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
final SimpleProviderBinding providerBinding = myBindingsMap.get(scope);
|
||||
SimpleProviderBinding<PsiReferenceProvider> providerBinding = myBindingsMap.get(scope);
|
||||
if (providerBinding != null) {
|
||||
providerBinding.registerProvider(provider, pattern, priority);
|
||||
return;
|
||||
}
|
||||
|
||||
final SimpleProviderBinding binding = new SimpleProviderBinding();
|
||||
SimpleProviderBinding<PsiReferenceProvider> binding = new SimpleProviderBinding<PsiReferenceProvider>();
|
||||
binding.registerProvider(provider, pattern, priority);
|
||||
if (myBindingsMap.putIfAbsent(scope, binding) == null) break;
|
||||
}
|
||||
@@ -126,19 +124,22 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
|
||||
}
|
||||
|
||||
public void unregisterReferenceProvider(@NotNull Class scope, @NotNull PsiReferenceProvider provider) {
|
||||
final ProviderBinding providerBinding = myBindingsMap.get(scope);
|
||||
ProviderBinding<PsiReferenceProvider> providerBinding = myBindingsMap.get(scope);
|
||||
providerBinding.unregisterProvider(provider);
|
||||
}
|
||||
|
||||
|
||||
private void registerNamedReferenceProvider(final String[] names, final PsiNamePatternCondition<?> nameCondition,
|
||||
final Class scopeClass,
|
||||
private void registerNamedReferenceProvider(@NotNull String[] names,
|
||||
final PsiNamePatternCondition<?> nameCondition,
|
||||
@NotNull Class scopeClass,
|
||||
final boolean caseSensitive,
|
||||
final PsiReferenceProvider provider, final double priority, final ElementPattern pattern) {
|
||||
NamedObjectProviderBinding providerBinding = myNamedBindingsMap.get(scopeClass);
|
||||
@NotNull PsiReferenceProvider provider,
|
||||
final double priority,
|
||||
@NotNull ElementPattern pattern) {
|
||||
NamedObjectProviderBinding<PsiReferenceProvider> providerBinding = myNamedBindingsMap.get(scopeClass);
|
||||
|
||||
if (providerBinding == null) {
|
||||
providerBinding = ConcurrencyUtil.cacheOrGet(myNamedBindingsMap, scopeClass, new NamedObjectProviderBinding() {
|
||||
providerBinding = ConcurrencyUtil.cacheOrGet(myNamedBindingsMap, scopeClass, new NamedObjectProviderBinding<PsiReferenceProvider>() {
|
||||
@Override
|
||||
protected String getName(final PsiElement position) {
|
||||
return nameCondition.getPropertyValue(position);
|
||||
@@ -158,17 +159,17 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
List<Trinity<PsiReferenceProvider, ProcessingContext, Double>> getPairsByElement(@NotNull PsiElement element,
|
||||
@NotNull PsiReferenceService.Hints hints) {
|
||||
List<ProviderBinding.ProviderInfo<PsiReferenceProvider,ProcessingContext>> getPairsByElement(@NotNull PsiElement element,
|
||||
@NotNull PsiReferenceService.Hints hints) {
|
||||
final Class<? extends PsiElement> clazz = element.getClass();
|
||||
List<Trinity<PsiReferenceProvider, ProcessingContext, Double>> ret = null;
|
||||
List<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>> ret = null;
|
||||
|
||||
for (Class aClass : myKnownSupers.get(clazz)) {
|
||||
final SimpleProviderBinding simpleBinding = myBindingsMap.get(aClass);
|
||||
final NamedObjectProviderBinding namedBinding = myNamedBindingsMap.get(aClass);
|
||||
SimpleProviderBinding<PsiReferenceProvider> simpleBinding = myBindingsMap.get(aClass);
|
||||
NamedObjectProviderBinding<PsiReferenceProvider> namedBinding = myNamedBindingsMap.get(aClass);
|
||||
if (simpleBinding == null && namedBinding == null) continue;
|
||||
|
||||
if (ret == null) ret = new SmartList<Trinity<PsiReferenceProvider, ProcessingContext, Double>>();
|
||||
if (ret == null) ret = new SmartList<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>>();
|
||||
if (simpleBinding != null) {
|
||||
simpleBinding.addAcceptableReferenceProviders(element, ret, hints);
|
||||
}
|
||||
@@ -176,6 +177,6 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
|
||||
namedBinding.addAcceptableReferenceProviders(element, ret, hints);
|
||||
}
|
||||
}
|
||||
return ret == null ? Collections.<Trinity<PsiReferenceProvider, ProcessingContext, Double>>emptyList() : ret;
|
||||
return ret == null ? Collections.<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>>emptyList() : ret;
|
||||
}
|
||||
}
|
||||
|
||||
+20
-25
@@ -18,7 +18,7 @@ package com.intellij.psi.impl.source.resolve.reference;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageExtension;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
@@ -32,12 +32,12 @@ public class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegistry {
|
||||
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>>() {
|
||||
private static final Comparator<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>> PRIORITY_COMPARATOR =
|
||||
new Comparator<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>>() {
|
||||
@Override
|
||||
public int compare(final Trinity<PsiReferenceProvider, ProcessingContext, Double> o1,
|
||||
final Trinity<PsiReferenceProvider, ProcessingContext, Double> o2) {
|
||||
return o2.getThird().compareTo(o1.getThird());
|
||||
public int compare(ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext> o1,
|
||||
ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext> o2) {
|
||||
return Comparing.compare(o2.priority, o1.priority);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -85,11 +85,11 @@ public class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegistry {
|
||||
@Override
|
||||
protected PsiReference[] doGetReferencesFromProviders(PsiElement context,
|
||||
PsiReferenceService.Hints hints) {
|
||||
List<Trinity<PsiReferenceProvider, ProcessingContext, Double>> providersForContextLanguage;
|
||||
providersForContextLanguage = getRegistrar(context.getLanguage()).getPairsByElement(context, hints);
|
||||
List<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>> providersForContextLanguage =
|
||||
getRegistrar(context.getLanguage()).getPairsByElement(context, hints);
|
||||
|
||||
List<Trinity<PsiReferenceProvider, ProcessingContext, Double>> providersForAllLanguages;
|
||||
providersForAllLanguages = getRegistrar(Language.ANY).getPairsByElement(context, hints);
|
||||
List<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>> providersForAllLanguages =
|
||||
getRegistrar(Language.ANY).getPairsByElement(context, hints);
|
||||
|
||||
int providersCount = providersForContextLanguage.size() + providersForAllLanguages.size();
|
||||
|
||||
@@ -98,35 +98,30 @@ public class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegistry {
|
||||
}
|
||||
|
||||
if (providersCount == 1) {
|
||||
final Trinity<PsiReferenceProvider, ProcessingContext, Double> firstProvider =
|
||||
final ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext> firstProvider =
|
||||
(providersForAllLanguages.isEmpty() ? providersForContextLanguage : providersForAllLanguages).get(0);
|
||||
return firstProvider.getFirst().getReferencesByElement(context, firstProvider.getSecond());
|
||||
return firstProvider.provider.getReferencesByElement(context, firstProvider.processingContext);
|
||||
}
|
||||
|
||||
Trinity<PsiReferenceProvider, ProcessingContext, Double>[] providers = new Trinity[providersCount];
|
||||
|
||||
int i = 0;
|
||||
for (Trinity<PsiReferenceProvider, ProcessingContext, Double> provider : providersForContextLanguage) {
|
||||
providers[i++] = provider;
|
||||
}
|
||||
for (Trinity<PsiReferenceProvider, ProcessingContext, Double> provider : providersForAllLanguages) {
|
||||
providers[i++] = provider;
|
||||
}
|
||||
List<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>> list =
|
||||
ContainerUtil.concat(providersForContextLanguage, providersForAllLanguages);
|
||||
@SuppressWarnings("unchecked")
|
||||
ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>[] providers = list.toArray(new ProviderBinding.ProviderInfo[list.size()]);
|
||||
|
||||
Arrays.sort(providers, PRIORITY_COMPARATOR);
|
||||
|
||||
List<PsiReference> result = new ArrayList<PsiReference>();
|
||||
final double maxPriority = providers[0].getThird();
|
||||
final double maxPriority = providers[0].priority;
|
||||
next:
|
||||
for (Trinity<PsiReferenceProvider, ProcessingContext, Double> trinity : providers) {
|
||||
for (ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext> trinity : providers) {
|
||||
final PsiReference[] refs;
|
||||
try {
|
||||
refs = trinity.getFirst().getReferencesByElement(context, trinity.getSecond());
|
||||
refs = trinity.provider.getReferencesByElement(context, trinity.processingContext);
|
||||
}
|
||||
catch(IndexNotReadyException ex) {
|
||||
continue;
|
||||
}
|
||||
if (trinity.getThird().doubleValue() != maxPriority) {
|
||||
if (trinity.priority != maxPriority) {
|
||||
for (PsiReference ref : refs) {
|
||||
for (PsiReference reference : result) {
|
||||
if (ref != null && ReferenceRange.containsRangeInElement(reference, ref.getRangeInElement())) {
|
||||
|
||||
+12
-12
@@ -17,7 +17,6 @@
|
||||
package com.intellij.psi.impl.source.resolve.reference;
|
||||
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReferenceProvider;
|
||||
@@ -37,17 +36,18 @@ import java.util.List;
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class SimpleProviderBinding<Provider> implements ProviderBinding<Provider> {
|
||||
private final List<Trinity<Provider, ElementPattern, Double>> myProviderPairs = ContainerUtil.createEmptyCOWList();
|
||||
private final List<ProviderInfo<Provider, ElementPattern>> myProviderPairs = ContainerUtil.createEmptyCOWList();
|
||||
|
||||
public void registerProvider(Provider provider,ElementPattern pattern, double priority){
|
||||
myProviderPairs.add(Trinity.create(provider, pattern, priority));
|
||||
myProviderPairs.add(new ProviderInfo<Provider, ElementPattern>(provider, pattern, priority));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAcceptableReferenceProviders(@NotNull PsiElement position, @NotNull List list,
|
||||
PsiReferenceService.Hints hints) {
|
||||
for(Trinity<Provider,ElementPattern,Double> trinity:myProviderPairs) {
|
||||
if (hints != PsiReferenceService.Hints.NO_HINTS && !((PsiReferenceProvider)trinity.first).acceptsHints(position, hints)) {
|
||||
public void addAcceptableReferenceProviders(@NotNull PsiElement position,
|
||||
@NotNull List<ProviderInfo<Provider, ProcessingContext>> list,
|
||||
@NotNull PsiReferenceService.Hints hints) {
|
||||
for(ProviderInfo<Provider, ElementPattern> trinity:myProviderPairs) {
|
||||
if (hints != PsiReferenceService.Hints.NO_HINTS && !((PsiReferenceProvider)trinity.provider).acceptsHints(position, hints)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -57,20 +57,20 @@ public class SimpleProviderBinding<Provider> implements ProviderBinding<Provider
|
||||
}
|
||||
boolean suitable = false;
|
||||
try {
|
||||
suitable = trinity.second.accepts(position, context);
|
||||
suitable = trinity.processingContext.accepts(position, context);
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
if (suitable) {
|
||||
list.add(Trinity.create(trinity.first, context, trinity.third));
|
||||
list.add(new ProviderInfo<Provider, ProcessingContext>(trinity.provider, context, trinity.priority));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterProvider(final Provider provider) {
|
||||
for (final Trinity<Provider, ElementPattern, Double> trinity : new ArrayList<Trinity<Provider, ElementPattern, Double>>(myProviderPairs)) {
|
||||
if (trinity.first.equals(provider)) {
|
||||
public void unregisterProvider(@NotNull final Provider provider) {
|
||||
for (final ProviderInfo<Provider, ElementPattern> trinity : new ArrayList<ProviderInfo<Provider, ElementPattern>>(myProviderPairs)) {
|
||||
if (trinity.provider.equals(provider)) {
|
||||
myProviderPairs.remove(trinity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
*/
|
||||
package git4idea.commands;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import gnu.trove.TObjectDoubleHashMap;
|
||||
import gnu.trove.TObjectDoubleProcedure;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -28,8 +29,8 @@ import java.util.regex.Pattern;
|
||||
public class GitStandardProgressAnalyzer implements GitProgressAnalyzer {
|
||||
|
||||
// progress of each operation is stored here. this is an overhead since operations go one by one,
|
||||
// but it looks simplier than storing current operation, checking that ther was no skipped, etc.
|
||||
private Map<Operation, Double> myOperationsProgress = new HashMap<Operation, Double>(4);
|
||||
// but it looks simpler than storing current operation, checking that ther was no skipped, etc.
|
||||
private TObjectDoubleHashMap<Operation> myOperationsProgress = new TObjectDoubleHashMap<Operation>(4);
|
||||
|
||||
/**
|
||||
* A long git command usually consists of the operations in this enum.
|
||||
@@ -96,11 +97,15 @@ public class GitStandardProgressAnalyzer implements GitProgressAnalyzer {
|
||||
}
|
||||
}
|
||||
// counting progress
|
||||
double totalProgress = 0;
|
||||
for (Map.Entry<Operation, Double> progressEntry : myOperationsProgress.entrySet()) {
|
||||
totalProgress += progressEntry.getKey().myFractionInTotal * progressEntry.getValue();
|
||||
}
|
||||
return totalProgress;
|
||||
final double[] totalProgress = new double[1];
|
||||
myOperationsProgress.forEachEntry(new TObjectDoubleProcedure<Operation>() {
|
||||
@Override
|
||||
public boolean execute(Operation operation, double progress) {
|
||||
totalProgress[0] += operation.myFractionInTotal * progress;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return totalProgress[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user