internal API for easier completion statistic collection

This commit is contained in:
peter
2015-11-09 11:32:14 +01:00
parent bb9e1acf69
commit ace83aa6df
11 changed files with 213 additions and 120 deletions
@@ -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<CompletionSorterImpl, LookupElement> groupItemsBySorter(List<LookupElement> source) {
private MultiMap<CompletionSorterImpl, LookupElement> groupItemsBySorter(Iterable<LookupElement> source) {
MultiMap<CompletionSorterImpl, LookupElement> 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<LookupElement, StringBuilder> getRelevanceStrings() {
final LinkedHashMap<LookupElement,StringBuilder> map = new LinkedHashMap<LookupElement, StringBuilder>();
for (LookupElement item : myItems) {
map.put(item, new StringBuilder());
}
final MultiMap<CompletionSorterImpl, LookupElement> inputBySorter = groupItemsBySorter(new ArrayList<LookupElement>(map.keySet()));
if (inputBySorter.size() > 1) {
for (LookupElement element : map.keySet()) {
map.get(element).append(obtainSorter(element)).append(": ");
}
}
public Map<LookupElement, List<Pair<String, Object>>> getRelevanceObjects(@NotNull Iterable<LookupElement> items,
boolean hideSingleValued) {
final LinkedHashMap<LookupElement, List<Pair<String, Object>>> map = ContainerUtil.newLinkedHashMap();
final MultiMap<CompletionSorterImpl, LookupElement> inputBySorter = groupItemsBySorter(items);
int sorterNumber = 0;
for (CompletionSorterImpl sorter : inputBySorter.keySet()) {
final LinkedHashMap<LookupElement, StringBuilder> subMap = new LinkedHashMap<LookupElement, StringBuilder>();
for (LookupElement element : inputBySorter.get(sorter)) {
subMap.put(element, map.get(element));
sorterNumber++;
Collection<LookupElement> thisSorterItems = inputBySorter.get(sorter);
for (LookupElement element : thisSorterItems) {
map.put(element, ContainerUtil.newArrayList(new Pair<String, Object>("frozen", myFrozenItems.contains(element)),
new Pair<String, Object>("sorter", sorterNumber)));
}
ProcessingContext context = createContext(false);
Classifier<LookupElement> classifier = myClassifiers.get(sorter);
if (classifier != null) {
classifier.describeItems(subMap, createContext(false));
while (classifier != null) {
List<Pair<LookupElement, Object>> pairs = classifier.getSortingWeights(thisSorterItems, context);
if (!hideSingleValued || !haveSameWeights(pairs)) {
for (Pair<LookupElement, Object> 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<Pair<LookupElement, Object>> 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<LookupElement> classify(Iterable<LookupElement> source, ProcessingContext context) {
public List<Pair<LookupElement, Object>> getSortingWeights(@NotNull Iterable<LookupElement> items, @NotNull ProcessingContext context) {
return Collections.emptyList();
}
@NotNull
@Override
public Iterable<LookupElement> classify(@NotNull Iterable<LookupElement> source, @NotNull ProcessingContext context) {
return sortByPresentation(source, myLookup);
}
@@ -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<StatisticsComparable> {
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;
}
}
@@ -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<LookupElement> {
private final CompletionLocation myLocation;
private final Map<LookupElement, Integer> myWeights = new IdentityHashMap<LookupElement, Integer>();
@SuppressWarnings("unchecked") private final Set<LookupElement> myNoStats = new THashSet<LookupElement>(TObjectHashingStrategy.IDENTITY);
private final Map<LookupElement, StatisticsComparable> myWeights = ContainerUtil.newIdentityHashMap();
private final Set<LookupElement> myNoStats = ContainerUtil.newIdentityTroveSet();
private int myPrefixChanges;
public LookupStatisticsWeigher(CompletionLocation location, Classifier<LookupElement> 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<LookupElement> classify(Iterable<LookupElement> source, final ProcessingContext context) {
public Iterable<LookupElement> classify(@NotNull Iterable<LookupElement> source, @NotNull final ProcessingContext context) {
checkPrefixChanged(context);
final Collection<List<LookupElement>> byWeight = buildMapByWeight(source, context).descendingMap().values();
@@ -122,7 +125,7 @@ public class StatisticsWeigher extends CompletionWeigher {
private TreeMap<Integer, List<LookupElement>> buildMapByWeight(Iterable<LookupElement> source, ProcessingContext context) {
TreeMap<Integer, List<LookupElement>> map = new TreeMap<Integer, List<LookupElement>>();
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<LookupElement> list = map.get(weight);
if (list == null) {
map.put(weight, list = new SmartList<LookupElement>());
@@ -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<LookupElement, StringBuilder> map, ProcessingContext context) {
public List<Pair<LookupElement, Object>> getSortingWeights(@NotNull Iterable<LookupElement> 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<LookupElement, Pair<LookupElement, Object>>() {
@Override
public Pair<LookupElement, Object> fun(LookupElement lookupElement) {
return new Pair<LookupElement, Object>(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);
@@ -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<LookupElement> {
private final MultiMap<String, LookupElement> myElements = createMultiMap(false);
private final MultiMap<LookupElement, LookupElement> myToLift = createMultiMap(true);
private final MultiMap<LookupElement, LookupElement> myReversedToLift = createMultiMap(true);
private final String myName;
private final LiftingCondition myCondition;
private final boolean myLiftBefore;
private int myCount = 0;
public LiftShorterItemsClassifier(String name, Classifier<LookupElement> 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<LookupElement> {
}
}
@NotNull
@Override
public Iterable<LookupElement> classify(Iterable<LookupElement> source, ProcessingContext context) {
public Iterable<LookupElement> classify(@NotNull Iterable<LookupElement> source, @NotNull ProcessingContext context) {
return liftShorterElements(source, null, context);
}
@@ -113,25 +114,21 @@ public class LiftShorterItemsClassifier extends Classifier<LookupElement> {
return new LiftingIterable(srcSet, context, source, lifted);
}
@NotNull
@Override
public void describeItems(LinkedHashMap<LookupElement, StringBuilder> map, ProcessingContext context) {
public List<Pair<LookupElement, Object>> getSortingWeights(@NotNull Iterable<LookupElement> items, @NotNull ProcessingContext context) {
final THashSet<LookupElement> lifted = newIdentityTroveSet();
liftShorterElements(new ArrayList<LookupElement>(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<LookupElement, Pair<LookupElement, Object>>() {
@Override
public Pair<LookupElement, Object> fun(LookupElement element) {
return new Pair<LookupElement, Object>(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()) {
@@ -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<LookupElemen
}
@Override
public void removeElement(LookupElement element, ProcessingContext context) {
public void removeElement(@NotNull LookupElement element, @NotNull ProcessingContext context) {
myWeights.remove(element);
super.removeElement(element, context);
}
@NotNull
@Override
public Iterable<LookupElement> classify(Iterable<LookupElement> source, ProcessingContext context) {
public Iterable<LookupElement> classify(@NotNull Iterable<LookupElement> source, @NotNull ProcessingContext context) {
if (!myWeigher.isPrefixDependent() && myPrimitive) {
return myNext.classify(source, context);
}
@@ -75,14 +78,15 @@ public class CachingComparingClassifier extends ComparingClassifier<LookupElemen
}
}
@NotNull
@Override
public void describeItems(LinkedHashMap<LookupElement, StringBuilder> map, ProcessingContext context) {
public List<Pair<LookupElement, Object>> getSortingWeights(@NotNull Iterable<LookupElement> 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();
@@ -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<T> {
protected final Classifier<T> myNext;
private final String myName;
protected Classifier(Classifier<T> next) {
protected Classifier(@Nullable Classifier<T> 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<T> classify(Iterable<T> source, ProcessingContext context);
@NotNull
public abstract Iterable<T> classify(@NotNull Iterable<T> source, @NotNull ProcessingContext context);
public void describeItems(LinkedHashMap<T, StringBuilder> 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<Pair<T, Object>> getSortingWeights(@NotNull Iterable<T> items, @NotNull ProcessingContext context);
@Nullable
public final Classifier<T> 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;
}
}
@@ -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<T> extends Classifier<T> {
protected final String myName;
private final boolean myNegated;
public ComparingClassifier(Classifier<T> next, String name) {
this(next, name, false);
}
protected ComparingClassifier(Classifier<T> 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<T> classify(final Iterable<T> source, final ProcessingContext context) {
public Iterable<T> classify(@NotNull final Iterable<T> source, @NotNull final ProcessingContext context) {
List<T> nulls = null;
TreeMap<Comparable, List<T>> map = new TreeMap<Comparable, List<T>>();
for (T t : source) {
@@ -79,21 +76,14 @@ public abstract class ComparingClassifier<T> extends Classifier<T> {
};
}
@NotNull
@Override
public void describeItems(LinkedHashMap<T, StringBuilder> map, ProcessingContext context) {
Map<T, String> weights = new IdentityHashMap<T, String>();
for (T t : map.keySet()) {
weights.put(t, String.valueOf(getWeight(t, context)));
}
if (new HashSet<String>(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<Pair<T, Object>> getSortingWeights(@NotNull Iterable<T> items, @NotNull final ProcessingContext context) {
return ContainerUtil.map(items, new Function<T, Pair<T, Object>>() {
@Override
public Pair<T, Object> fun(T t) {
return new Pair<T, Object>(t, getWeight(t, context));
}
}
super.describeItems(map, context);
});
}
}
@@ -122,7 +122,15 @@ public abstract class LookupArranger {
return myMatchingItems;
}
public Map<LookupElement,StringBuilder> 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<LookupElement, List<Pair<String, Object>>> getRelevanceObjects(@NotNull Iterable<LookupElement> items,
boolean hideSingleValued) {
return Collections.emptyMap();
}
@@ -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<LookupElement,StringBuilder> getRelevanceStrings() {
@NotNull
public Map<LookupElement, List<Pair<String, Object>>> getRelevanceObjects(@NotNull Iterable<LookupElement> items, boolean hideSingleValued) {
synchronized (myList) {
return myPresentableArranger.getRelevanceStrings();
return myPresentableArranger.getRelevanceObjects(items, hideSingleValued);
}
}
@@ -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<String> getLookupElementWeights(LookupImpl lookup) {
final Map<LookupElement,StringBuilder> strings = lookup.getRelevanceStrings();
List<String> sb = new ArrayList<String>();
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<String> getLookupElementWeights(LookupImpl lookup, boolean hideSingleValued) {
final Map<LookupElement, List<Pair<String, Object>>> weights = lookup.getRelevanceObjects(lookup.getItems(), hideSingleValued);
return ContainerUtil.map(weights.entrySet(), new Function<Map.Entry<LookupElement, List<Pair<String, Object>>>, String>() {
@Override
public String fun(Map.Entry<LookupElement, List<Pair<String, Object>>> entry) {
return entry.getKey().getLookupString() + "\t" + StringUtil.join(entry.getValue(), new Function<Pair<String, Object>, String>() {
@Override
public String fun(Pair<String, Object> pair) {
return pair.first + "=" + pair.second;
}
}, ", ");
}
});
}
}
@@ -1893,10 +1893,10 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
Assert.assertNotNull(strings);
final List<String> 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());
}