diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java index ea449e8ba1be..cff59c10fddf 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java @@ -32,10 +32,7 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.patterns.StandardPatterns; @@ -93,7 +90,7 @@ public class CompletionLookupArranger extends LookupArranger { myLocation = new CompletionLocation(parameters); } - private MultiMap groupItemsBySorter(List source) { + private MultiMap groupItemsBySorter(Iterable source) { MultiMap inputBySorter = MultiMap.createLinked(); for (LookupElement element : source) { inputBySorter.putValue(obtainSorter(element), element); @@ -106,28 +103,30 @@ public class CompletionLookupArranger extends LookupArranger { return myProcess.getSorter(element); } + @NotNull @Override - public Map getRelevanceStrings() { - final LinkedHashMap map = new LinkedHashMap(); - for (LookupElement item : myItems) { - map.put(item, new StringBuilder()); - } - final MultiMap inputBySorter = groupItemsBySorter(new ArrayList(map.keySet())); - - if (inputBySorter.size() > 1) { - for (LookupElement element : map.keySet()) { - map.get(element).append(obtainSorter(element)).append(": "); - } - } - + public Map>> getRelevanceObjects(@NotNull Iterable items, + boolean hideSingleValued) { + final LinkedHashMap>> map = ContainerUtil.newLinkedHashMap(); + final MultiMap inputBySorter = groupItemsBySorter(items); + int sorterNumber = 0; for (CompletionSorterImpl sorter : inputBySorter.keySet()) { - final LinkedHashMap subMap = new LinkedHashMap(); - for (LookupElement element : inputBySorter.get(sorter)) { - subMap.put(element, map.get(element)); + sorterNumber++; + Collection thisSorterItems = inputBySorter.get(sorter); + for (LookupElement element : thisSorterItems) { + map.put(element, ContainerUtil.newArrayList(new Pair("frozen", myFrozenItems.contains(element)), + new Pair("sorter", sorterNumber))); } + ProcessingContext context = createContext(false); Classifier classifier = myClassifiers.get(sorter); - if (classifier != null) { - classifier.describeItems(subMap, createContext(false)); + while (classifier != null) { + List> pairs = classifier.getSortingWeights(thisSorterItems, context); + if (!hideSingleValued || !haveSameWeights(pairs)) { + for (Pair pair : pairs) { + map.get(pair.first).add(Pair.create(classifier.getPresentableName(), pair.second)); + } + } + classifier = classifier.getNext(); } } @@ -135,6 +134,18 @@ public class CompletionLookupArranger extends LookupArranger { } + private static boolean haveSameWeights(List> pairs) { + if (pairs.isEmpty()) return true; + + for (int i = 1; i < pairs.size(); i++) { + if (!Comparing.equal(pairs.get(i).second, pairs.get(0).second)) { + return false; + } + } + + return true; + } + @Override public void addElement(Lookup lookup, LookupElement element, LookupElementPresentation presentation) { StatisticsWeigher.clearBaseStatisticsInfo(element); @@ -570,12 +581,19 @@ public class CompletionLookupArranger extends LookupArranger { private final LookupImpl myLookup; private AlphaClassifier(LookupImpl lookup) { - super(null); + super(null, "alpha"); myLookup = lookup; } + @NotNull @Override - public Iterable classify(Iterable source, ProcessingContext context) { + public List> getSortingWeights(@NotNull Iterable items, @NotNull ProcessingContext context) { + return Collections.emptyList(); + } + + @NotNull + @Override + public Iterable classify(@NotNull Iterable source, @NotNull ProcessingContext context) { return sortByPresentation(source, myLookup); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/StatisticsComparable.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/StatisticsComparable.java new file mode 100644 index 000000000000..ba72751ee357 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/StatisticsComparable.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.completion; + +import com.intellij.psi.statistics.StatisticsInfo; +import org.jetbrains.annotations.NotNull; + +/** + * @author peter + */ +public class StatisticsComparable implements Comparable { + private final int myScalar; + private final StatisticsInfo myStatisticsInfo; + + public StatisticsComparable(int scalar, @NotNull StatisticsInfo statisticsInfo) { + myScalar = scalar; + myStatisticsInfo = statisticsInfo; + } + + public int getScalar() { + return myScalar; + } + + @NotNull + public StatisticsInfo getStatisticsInfo() { + return myStatisticsInfo; + } + + @Override + public String toString() { + return String.valueOf(myScalar); + } + + @Override + public int compareTo(StatisticsComparable o) { + return myScalar < o.myScalar ? -1 : myScalar == o.myScalar ? 0 : 1; + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/StatisticsWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/StatisticsWeigher.java index 176827ce4070..f6ee7eeb9cb9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/StatisticsWeigher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/StatisticsWeigher.java @@ -22,8 +22,10 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Pair; import com.intellij.psi.statistics.StatisticsInfo; import com.intellij.psi.statistics.StatisticsManager; +import com.intellij.util.Function; import com.intellij.util.ProcessingContext; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; @@ -49,19 +51,19 @@ public class StatisticsWeigher extends CompletionWeigher { public static class LookupStatisticsWeigher extends Classifier { private final CompletionLocation myLocation; - private final Map myWeights = new IdentityHashMap(); - @SuppressWarnings("unchecked") private final Set myNoStats = new THashSet(TObjectHashingStrategy.IDENTITY); + private final Map myWeights = ContainerUtil.newIdentityHashMap(); + private final Set myNoStats = ContainerUtil.newIdentityTroveSet(); private int myPrefixChanges; public LookupStatisticsWeigher(CompletionLocation location, Classifier next) { - super(next); + super(next, "stats"); myLocation = location; } @Override - public void addElement(LookupElement element, ProcessingContext context) { + public void addElement(@NotNull LookupElement element, @NotNull ProcessingContext context) { StatisticsInfo baseInfo = getBaseStatisticsInfo(element, myLocation); - myWeights.put(element, weigh(element, baseInfo, context.get(CompletionLookupArranger.WEIGHING_CONTEXT))); + myWeights.put(element, new StatisticsComparable(weigh(element, baseInfo, context.get(CompletionLookupArranger.WEIGHING_CONTEXT)), baseInfo)); if (baseInfo == StatisticsInfo.EMPTY) { myNoStats.add(element); } @@ -76,8 +78,9 @@ public class StatisticsWeigher extends CompletionWeigher { } } + @NotNull @Override - public Iterable classify(Iterable source, final ProcessingContext context) { + public Iterable classify(@NotNull Iterable source, @NotNull final ProcessingContext context) { checkPrefixChanged(context); final Collection> byWeight = buildMapByWeight(source, context).descendingMap().values(); @@ -122,7 +125,7 @@ public class StatisticsWeigher extends CompletionWeigher { private TreeMap> buildMapByWeight(Iterable source, ProcessingContext context) { TreeMap> map = new TreeMap>(); for (LookupElement element : source) { - final int weight = getWeight(element, context.get(CompletionLookupArranger.WEIGHING_CONTEXT)); + final int weight = getWeight(element, context.get(CompletionLookupArranger.WEIGHING_CONTEXT)).getScalar(); List list = map.get(weight); if (list == null) { map.put(weight, list = new SmartList()); @@ -132,10 +135,11 @@ public class StatisticsWeigher extends CompletionWeigher { return map; } - private int getWeight(LookupElement t, WeighingContext context) { - Integer w = myWeights.get(t); + private StatisticsComparable getWeight(LookupElement t, WeighingContext context) { + StatisticsComparable w = myWeights.get(t); if (w == null) { - myWeights.put(t, w = weigh(t, getBaseStatisticsInfo(t, myLocation), context)); + StatisticsInfo info = getBaseStatisticsInfo(t, myLocation); + myWeights.put(t, w = new StatisticsComparable(weigh(t, info, context), info)); } return w; } @@ -151,21 +155,20 @@ public class StatisticsWeigher extends CompletionWeigher { return minRecency == Integer.MAX_VALUE ? useCount : 100 - minRecency; } + @NotNull @Override - public void describeItems(LinkedHashMap map, ProcessingContext context) { + public List> getSortingWeights(@NotNull Iterable items, @NotNull final ProcessingContext context) { checkPrefixChanged(context); - for (LookupElement element : map.keySet()) { - StringBuilder builder = map.get(element); - if (builder.length() > 0) { - builder.append(", "); + return ContainerUtil.map(items, new Function>() { + @Override + public Pair fun(LookupElement lookupElement) { + return new Pair(lookupElement, getWeight(lookupElement, context.get(CompletionLookupArranger.WEIGHING_CONTEXT))); } - builder.append("stats=").append(getWeight(element, context.get(CompletionLookupArranger.WEIGHING_CONTEXT))); - } - super.describeItems(map, context); + }); } @Override - public void removeElement(LookupElement element, ProcessingContext context) { + public void removeElement(@NotNull LookupElement element, @NotNull ProcessingContext context) { myWeights.remove(element); myNoStats.remove(element); super.removeElement(element, context); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java index 9e7a9cb2e9a9..efc4401f2d9b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java @@ -19,6 +19,8 @@ import com.intellij.codeInsight.completion.CompletionUtil; import com.intellij.codeInsight.lookup.Classifier; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Pair; +import com.intellij.util.Function; import com.intellij.util.ProcessingContext; import com.intellij.util.containers.*; import gnu.trove.THashSet; @@ -39,20 +41,18 @@ public class LiftShorterItemsClassifier extends Classifier { private final MultiMap myElements = createMultiMap(false); private final MultiMap myToLift = createMultiMap(true); private final MultiMap myReversedToLift = createMultiMap(true); - private final String myName; private final LiftingCondition myCondition; private final boolean myLiftBefore; private int myCount = 0; public LiftShorterItemsClassifier(String name, Classifier next, LiftingCondition condition, boolean liftBefore) { - super(next); - myName = name; + super(next, name); myCondition = condition; myLiftBefore = liftBefore; } @Override - public void addElement(LookupElement added, ProcessingContext context) { + public void addElement(@NotNull LookupElement added, @NotNull ProcessingContext context) { myCount++; for (String string : CompletionUtil.iterateLookupStrings(added)) { @@ -96,8 +96,9 @@ public class LiftShorterItemsClassifier extends Classifier { } } + @NotNull @Override - public Iterable classify(Iterable source, ProcessingContext context) { + public Iterable classify(@NotNull Iterable source, @NotNull ProcessingContext context) { return liftShorterElements(source, null, context); } @@ -113,25 +114,21 @@ public class LiftShorterItemsClassifier extends Classifier { return new LiftingIterable(srcSet, context, source, lifted); } + @NotNull @Override - public void describeItems(LinkedHashMap map, ProcessingContext context) { + public List> getSortingWeights(@NotNull Iterable items, @NotNull ProcessingContext context) { final THashSet lifted = newIdentityTroveSet(); - liftShorterElements(new ArrayList(map.keySet()), lifted, context); - if (!lifted.isEmpty()) { - for (LookupElement element : map.keySet()) { - final StringBuilder builder = map.get(element); - if (builder.length() > 0) { - builder.append(", "); - } - - builder.append(myName).append("=").append(lifted.contains(element)); + liftShorterElements(ContainerUtil.newArrayList(items), lifted, context); + return ContainerUtil.map(items, new Function>() { + @Override + public Pair fun(LookupElement element) { + return new Pair(element, lifted.contains(element)); } - } - super.describeItems(map, context); + }); } @Override - public void removeElement(LookupElement element, ProcessingContext context) { + public void removeElement(@NotNull LookupElement element, @NotNull ProcessingContext context) { for (String s : CompletionUtil.iterateLookupStrings(element)) { myElements.remove(s, element); if (myElements.get(s).isEmpty()) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java index dba7c55964f3..5597f1483440 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java @@ -17,13 +17,15 @@ package com.intellij.codeInsight.lookup; import com.intellij.codeInsight.completion.CompletionLookupArranger; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.psi.ForceableComparable; import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.IdentityHashMap; -import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; /** @@ -52,13 +54,14 @@ public class CachingComparingClassifier extends ComparingClassifier classify(Iterable source, ProcessingContext context) { + public Iterable classify(@NotNull Iterable source, @NotNull ProcessingContext context) { if (!myWeigher.isPrefixDependent() && myPrimitive) { return myNext.classify(source, context); } @@ -75,14 +78,15 @@ public class CachingComparingClassifier extends ComparingClassifier map, ProcessingContext context) { + public List> getSortingWeights(@NotNull Iterable items, @NotNull ProcessingContext context) { checkPrefixChanged(context); - super.describeItems(map, context); + return super.getSortingWeights(items, context); } @Override - public void addElement(LookupElement t, ProcessingContext context) { + public void addElement(@NotNull LookupElement t, @NotNull ProcessingContext context) { Comparable weight = myWeigher.weigh(t, context.get(CompletionLookupArranger.WEIGHING_CONTEXT)); if (weight instanceof ForceableComparable) { ((ForceableComparable)weight).force(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/Classifier.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/Classifier.java index 42ced4a0c60f..5f33e16bf184 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/Classifier.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/Classifier.java @@ -15,37 +15,55 @@ */ package com.intellij.codeInsight.lookup; +import com.intellij.openapi.util.Pair; import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.LinkedHashMap; +import java.util.List; /** * @author peter */ public abstract class Classifier { protected final Classifier myNext; + private final String myName; - protected Classifier(Classifier next) { + protected Classifier(@Nullable Classifier next, String name) { myNext = next; + myName = name; } - public void addElement(T t, ProcessingContext context) { + public void addElement(@NotNull T t, @NotNull ProcessingContext context) { if (myNext != null) { myNext.addElement(t, context); } } - public abstract Iterable classify(Iterable source, ProcessingContext context); + @NotNull + public abstract Iterable classify(@NotNull Iterable source, @NotNull ProcessingContext context); - public void describeItems(LinkedHashMap map, ProcessingContext context) { - if (myNext != null) { - myNext.describeItems(map, context); - } + /** + * @return a mapping from the given items to objects (e.g. Comparable instances) used to sort the items in {@link #classify(Iterable, ProcessingContext)}. + * May return an empty list if there are no suitable objects available. + * Used for diagnostics and statistic collection. + */ + @NotNull + public abstract List> getSortingWeights(@NotNull Iterable items, @NotNull ProcessingContext context); + + @Nullable + public final Classifier getNext() { + return myNext; } - public void removeElement(T element, ProcessingContext context) { + public void removeElement(@NotNull T element, @NotNull ProcessingContext context) { if (myNext != null) { myNext.removeElement(element, context); } } + + @NotNull + public final String getPresentableName() { + return myName; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java index d399fac02f3a..96faa2fd8c31 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java @@ -15,11 +15,13 @@ */ package com.intellij.codeInsight.lookup; -import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.Pair; +import com.intellij.util.Function; import com.intellij.util.ProcessingContext; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.FlatteningIterator; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -28,24 +30,19 @@ import java.util.*; * @author peter */ public abstract class ComparingClassifier extends Classifier { - protected final String myName; private final boolean myNegated; - public ComparingClassifier(Classifier next, String name) { - this(next, name, false); - } - protected ComparingClassifier(Classifier next, String name, boolean negated) { - super(next); - myName = name; + super(next, name); myNegated = negated; } @Nullable public abstract Comparable getWeight(T t, ProcessingContext context); + @NotNull @Override - public Iterable classify(final Iterable source, final ProcessingContext context) { + public Iterable classify(@NotNull final Iterable source, @NotNull final ProcessingContext context) { List nulls = null; TreeMap> map = new TreeMap>(); for (T t : source) { @@ -79,21 +76,14 @@ public abstract class ComparingClassifier extends Classifier { }; } + @NotNull @Override - public void describeItems(LinkedHashMap map, ProcessingContext context) { - Map weights = new IdentityHashMap(); - for (T t : map.keySet()) { - weights.put(t, String.valueOf(getWeight(t, context))); - } - if (new HashSet(weights.values()).size() > 1 || ApplicationManager.getApplication().isUnitTestMode()) { - for (T t : map.keySet()) { - final StringBuilder builder = map.get(t); - if (builder.length() > 0) { - builder.append(", "); - } - builder.append(myName).append("=").append(weights.get(t)); + public List> getSortingWeights(@NotNull Iterable items, @NotNull final ProcessingContext context) { + return ContainerUtil.map(items, new Function>() { + @Override + public Pair fun(T t) { + return new Pair(t, getWeight(t, context)); } - } - super.describeItems(map, context); + }); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupArranger.java index b58ac2ce3a65..aea154223bac 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupArranger.java @@ -122,7 +122,15 @@ public abstract class LookupArranger { return myMatchingItems; } - public Map getRelevanceStrings() { + /** + * @param items the items to give relevance weight for + * @param hideSingleValued whether criteria that gave same values for all items should be skipped + * @return for each item, an (ordered) map of criteria used for lookup relevance sorting + * along with the objects representing the weights in these criteria + */ + @NotNull + public Map>> getRelevanceObjects(@NotNull Iterable items, + boolean hideSingleValued) { return Collections.emptyMap(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index bc16f354e5eb..ea0f8a4853e5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -67,10 +67,8 @@ import javax.swing.event.ListSelectionListener; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; -import java.util.Collection; -import java.util.HashMap; +import java.util.*; import java.util.List; -import java.util.Map; public class LookupImpl extends LightweightHint implements LookupEx, Disposable, WeighingContext { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.lookup.impl.LookupImpl"); @@ -1153,9 +1151,10 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable, return true; } - public Map getRelevanceStrings() { + @NotNull + public Map>> getRelevanceObjects(@NotNull Iterable items, boolean hideSingleValued) { synchronized (myList) { - return myPresentableArranger.getRelevanceStrings(); + return myPresentableArranger.getRelevanceObjects(items, hideSingleValued); } } diff --git a/platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java b/platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java index 40dce539f4ff..49e355c0a586 100644 --- a/platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java +++ b/platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java @@ -27,10 +27,12 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import java.awt.datatransfer.StringSelection; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -59,7 +61,7 @@ public class DumpLookupElementWeights extends AnAction implements DumbAware { if (selected != null) { sb += "\nprefix: " + lookup.itemPattern(selected); } - sb += "\nweights:\n" + StringUtil.join(getLookupElementWeights(lookup), "\n"); + sb += "\nweights:\n" + StringUtil.join(getLookupElementWeights(lookup, true), "\n"); System.out.println(sb); LOG.info(sb); try { @@ -67,15 +69,18 @@ public class DumpLookupElementWeights extends AnAction implements DumbAware { } catch (Exception ignore){} } - public static List getLookupElementWeights(LookupImpl lookup) { - final Map strings = lookup.getRelevanceStrings(); - List sb = new ArrayList(); - for (LookupElement item : lookup.getItems()) { - StringBuilder builder = strings.get(item); - String weight = builder == null ? "null" : builder.toString(); - final String s = item.getLookupString() + "\t" + weight; - sb.add(s); - } - return sb; + public static List getLookupElementWeights(LookupImpl lookup, boolean hideSingleValued) { + final Map>> weights = lookup.getRelevanceObjects(lookup.getItems(), hideSingleValued); + return ContainerUtil.map(weights.entrySet(), new Function>>, String>() { + @Override + public String fun(Map.Entry>> entry) { + return entry.getKey().getLookupString() + "\t" + StringUtil.join(entry.getValue(), new Function, String>() { + @Override + public String fun(Pair pair) { + return pair.first + "=" + pair.second; + } + }, ", "); + } + }); } } \ No newline at end of file diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index dd52c9fc66e4..f32e275c7337 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -1893,10 +1893,10 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig Assert.assertNotNull(strings); final List actual = strings.subList(0, Math.min(expected.length, strings.size())); if (!actual.equals(Arrays.asList(expected))) { - UsefulTestCase.assertOrderedEquals(DumpLookupElementWeights.getLookupElementWeights(lookup), expected); + UsefulTestCase.assertOrderedEquals(DumpLookupElementWeights.getLookupElementWeights(lookup, false), expected); } if (selected != list.getSelectedIndex()) { - System.out.println(DumpLookupElementWeights.getLookupElementWeights(lookup)); + System.out.println(DumpLookupElementWeights.getLookupElementWeights(lookup, false)); } Assert.assertEquals(selected, list.getSelectedIndex()); }