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 2f6d86610dbd..0d37834b83ac 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java @@ -25,10 +25,7 @@ import com.intellij.codeInsight.template.impl.LiveTemplateLookupElement; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Condition; -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.patterns.StandardPatterns; import com.intellij.util.ProcessingContext; @@ -66,6 +63,7 @@ public class CompletionLookupArranger extends LookupArranger { private final CompletionProgressIndicator myProcess; @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) private final Map> myClassifiers = new LinkedHashMap<>(); + private final Key mySorterKey = Key.create("SORTER_KEY"); private final CompletionFinalSorter myFinalSorter = CompletionFinalSorter.newSorter(); private int myPrefixChanges; @@ -89,7 +87,8 @@ public class CompletionLookupArranger extends LookupArranger { @NotNull private CompletionSorterImpl obtainSorter(LookupElement element) { - return myProcess.getSorter(element); + //noinspection ConstantConditions + return element.getUserData(mySorterKey); } @NotNull @@ -132,6 +131,10 @@ public class CompletionLookupArranger extends LookupArranger { return result; } + void associateSorter(LookupElement element, CompletionSorterImpl sorter) { + element.putUserData(mySorterKey, sorter); + } + private static boolean haveSameWeights(List> pairs) { if (pairs.isEmpty()) return true; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 180147cd2228..16b762d86261 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -82,7 +82,6 @@ import java.util.List; import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; /** @@ -97,6 +96,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement private final Caret myCaret; private final CompletionParameters myParameters; private final CodeCompletionHandlerBase myHandler; + private final CompletionLookupArranger myArranger; private OffsetsInFile myHostOffsets; private final LookupImpl myLookup; private final MergingUpdateQueue myQueue; @@ -128,8 +128,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement private volatile int myCount; private volatile boolean myHasPsiElements; private boolean myLookupUpdated; - private final ConcurrentMap myItemSorters = - ContainerUtil.createConcurrentWeakMap(ContainerUtil.identityStrategy()); private final PropertyChangeListener myLookupManagerListener; private final Queue myAdvertiserChanges = new ConcurrentLinkedQueue<>(); private final List myDelayedMiddleMatches = ContainerUtil.newArrayList(); @@ -155,7 +153,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement myAdvertiserChanges.offer(() -> myLookup.getAdvertiser().clearAdvertisements()); - myLookup.setArranger(new CompletionLookupArranger(parameters, this)); + myArranger = new CompletionLookupArranger(parameters, this); + myLookup.setArranger(myArranger); myLookup.addLookupListener(myLookupListener); myLookup.setCalculating(true); @@ -291,11 +290,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } } - @NotNull - CompletionSorterImpl getSorter(LookupElement element) { - return myItemSorters.get(element); - } - @Override public void dispose() { } @@ -451,7 +445,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement addDelayedMiddleMatches(); } - myItemSorters.put(lookupElement, (CompletionSorterImpl)item.getSorter()); + myArranger.associateSorter(lookupElement, (CompletionSorterImpl)item.getSorter()); if (item.isStartMatch() || allowMiddleMatches) { addItemToLookup(item); } else { 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 46b9d49100dc..0300c708b177 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupArranger.java @@ -19,10 +19,9 @@ package com.intellij.codeInsight.lookup; import com.intellij.codeInsight.completion.PrefixMatcher; import com.intellij.codeInsight.completion.impl.CompletionServiceImpl; import com.intellij.codeInsight.lookup.impl.LookupImpl; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.hash.EqualityPolicy; -import com.intellij.util.containers.hash.LinkedHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -36,7 +35,7 @@ public abstract class LookupArranger implements WeighingContext { private final List myMatchingItems = new ArrayList<>(); private final List myExactPrefixItems = new ArrayList<>(); private final List myInexactPrefixItems = new ArrayList<>(); - private final Map myMatchers = ContainerUtil.createConcurrentWeakMap(ContainerUtil.identityStrategy()); + private final Key myMatcherKey = Key.create("LookupArrangerMatcher"); private String myAdditionalPrefix = ""; public void addElement(LookupElement item, LookupElementPresentation presentation) { @@ -58,7 +57,7 @@ public abstract class LookupArranger implements WeighingContext { } public void registerMatcher(@NotNull LookupElement item, @NotNull PrefixMatcher matcher) { - myMatchers.put(item, matcher); + item.putUserData(myMatcherKey, matcher); } @NotNull @@ -70,7 +69,7 @@ public abstract class LookupArranger implements WeighingContext { @NotNull public PrefixMatcher itemMatcher(@NotNull LookupElement item) { - PrefixMatcher matcher = myMatchers.get(item); + PrefixMatcher matcher = item.getUserData(myMatcherKey); if (matcher == null) { throw new AssertionError("Item not in lookup: item=" + item + "; lookup items=" + myItems); } @@ -89,20 +88,17 @@ public abstract class LookupArranger implements WeighingContext { } public final void prefixReplaced(Lookup lookup, String newPrefix) { - //noinspection unchecked - Map newMatchers = new LinkedHashMap(EqualityPolicy.IDENTITY); - for (LookupElement item : myItems) { + ArrayList itemCopy = ContainerUtil.newArrayList(myItems); + myItems.clear(); + for (LookupElement item : itemCopy) { if (item.isValid()) { PrefixMatcher matcher = itemMatcher(item).cloneWithPrefix(newPrefix); if (matcher.prefixMatches(item)) { - newMatchers.put(item, matcher); + item.putUserData(myMatcherKey, matcher); + myItems.add(item); } } } - myMatchers.clear(); - myMatchers.putAll(newMatchers); - myItems.clear(); - myItems.addAll(newMatchers.keySet()); prefixChanged(lookup); } 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 beb8c4c5c38c..693766b8e212 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 @@ -42,10 +42,7 @@ import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.psi.PsiDocumentManager; @@ -79,6 +76,7 @@ import java.util.Map; public class LookupImpl extends LightweightHint implements LookupEx, Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.lookup.impl.LookupImpl"); + private static final Key CUSTOM_FONT_KEY = Key.create("CustomLookupElementFont"); private final LookupOffsets myOffsets; private final Project myProject; @@ -123,8 +121,6 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable private boolean myChangeGuard; private volatile LookupArranger myArranger; private LookupArranger myPresentableArranger; - private final Map myCustomFonts = ContainerUtil.createConcurrentWeakMap(10, 0.75f, Runtime.getRuntime().availableProcessors(), - ContainerUtil.identityStrategy()); private boolean myStartCompletionWhenNothingMatches; boolean myResizePending; private boolean myFinishing; @@ -273,15 +269,15 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable private void updateLookupWidth(LookupElement item, LookupElementPresentation presentation) { final Font customFont = myCellRenderer.getFontAbleToDisplay(presentation); if (customFont != null) { - myCustomFonts.put(item, customFont); + item.putUserData(CUSTOM_FONT_KEY, customFont); } int maxWidth = myCellRenderer.updateMaximumWidth(presentation, item); myLookupTextWidth = Math.max(maxWidth, myLookupTextWidth); } @Nullable - public Font getCustomFont(LookupElement item, boolean bold) { - Font font = myCustomFonts.get(item); + Font getCustomFont(LookupElement item, boolean bold) { + Font font = item.getUserData(CUSTOM_FONT_KEY); return font == null ? null : bold ? font.deriveFont(Font.BOLD) : font; }