From 171a496759c840d27e07a646c505932fa5d8d492 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 15 Apr 2011 15:11:12 +0200 Subject: [PATCH 1/3] don't store current completion sorter in the lookup element as it gets rotten (WI-5925) --- .../completion/CompletionResultSet.java | 8 ++----- .../completion/CompletionLookupArranger.java | 8 +++---- .../CompletionProgressIndicator.java | 14 ++++++++++- .../impl/CompletionServiceImpl.java | 24 ++++++++++++------- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java index 8dc6a06991c9..3802d1bd7cc6 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java @@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull; public abstract class CompletionResultSet { private final PrefixMatcher myPrefixMatcher; private final Consumer myConsumer; - private final CompletionService myCompletionService = CompletionService.getCompletionService(); + protected final CompletionService myCompletionService = CompletionService.getCompletionService(); protected final CompletionContributor myContributor; private boolean myStopped; @@ -41,11 +41,7 @@ public abstract class CompletionResultSet { * If a given element matches the prefix, give it for further processing (which may eventually result in its appearing in the completion list) * @param element */ - public void addElement(@NotNull final LookupElement element) { - if (myCompletionService.prefixMatches(element, getPrefixMatcher())) { - myConsumer.consume(element); - } - } + public abstract void addElement(@NotNull final LookupElement element); public void addAllElements(@NotNull final Iterable elements) { for (LookupElement element : elements) { 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 be5f27255a0a..f140027481f2 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java @@ -23,7 +23,6 @@ import com.intellij.codeInsight.lookup.Lookup; import com.intellij.codeInsight.lookup.LookupArranger; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.impl.LookupImpl; -import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElement; import com.intellij.psi.WeighingService; import com.intellij.psi.statistics.StatisticsInfo; @@ -38,13 +37,14 @@ import org.jetbrains.annotations.NotNull; import java.util.*; public class CompletionLookupArranger extends LookupArranger { - public static final Key SORTER_KEY = Key.create("SORTER_KEY"); private static final String SELECTED = "selected"; static final String IGNORED = "ignored"; private final CompletionLocation myLocation; private final Map mySortingWeights = new THashMap(TObjectHashingStrategy.IDENTITY); + private final CompletionProgressIndicator myProcess; - public CompletionLookupArranger(final CompletionParameters parameters) { + public CompletionLookupArranger(final CompletionParameters parameters, CompletionProgressIndicator process) { + myProcess = process; myLocation = new CompletionLocation(parameters); } @@ -150,7 +150,7 @@ public class CompletionLookupArranger extends LookupArranger { @NotNull private CompletionSorterImpl obtainSorter(LookupElement element) { - return element.getUserData(SORTER_KEY); + return myProcess.getSorter(element); } @Override 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 056d4a99ae1b..4b058324d323 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.completion.impl.CompletionServiceImpl; +import com.intellij.codeInsight.completion.impl.CompletionSorterImpl; import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler; import com.intellij.codeInsight.hint.EditorHintListener; import com.intellij.codeInsight.hint.HintManager; @@ -62,6 +63,7 @@ import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.Collections; import java.util.List; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -103,6 +105,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } }; private volatile int myCount; + private final ConcurrentHashMap myItemSorters = new ConcurrentHashMap(); public CompletionProgressIndicator(final Editor editor, CompletionParameters parameters, CodeCompletionHandlerBase handler, Semaphore freezeSemaphore, final OffsetMap offsetMap, LookupImpl lookup, boolean hasModifiers) { @@ -113,7 +116,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement myOffsetMap = offsetMap; myLookup = lookup; - myLookup.setArranger(new CompletionLookupArranger(parameters)); + myLookup.setArranger(new CompletionLookupArranger(parameters, this)); myLookup.addLookupListener(myLookupListener); myLookup.setCalculating(true); @@ -187,6 +190,15 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } } + public void setItemSorter(LookupElement element, CompletionSorterImpl sorter) { + myItemSorters.putIfAbsent(element, sorter); + } + + @NotNull + public CompletionSorterImpl getSorter(LookupElement element) { + return myItemSorters.get(element); + } + private static int findReplacementOffset(int selectionEndOffset, PsiReference reference) { final List ranges = ReferenceRange.getAbsoluteRanges(reference); for (TextRange range : ranges) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java index 7cba8937de37..b9f853acff0f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java @@ -46,7 +46,7 @@ import java.util.ArrayList; public class CompletionServiceImpl extends CompletionService{ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.impl.CompletionServiceImpl"); private Throwable myTrace = null; - private CompletionProgressIndicator myCurrentCompletion; + private volatile CompletionProgressIndicator myCurrentCompletion; private static volatile CompletionPhase ourPhase = CompletionPhase.NoCompletion; private static String ourPhaseTrace; @@ -82,7 +82,11 @@ public class CompletionServiceImpl extends CompletionService{ final PsiElement position = parameters.getPosition(); final String prefix = CompletionData.findPrefixStatic(position, parameters.getOffset()); final String textBeforePosition = parameters.getPosition().getContainingFile().getText().substring(0, parameters.getOffset()); - return new CompletionResultSetImpl(consumer, textBeforePosition, new CamelHumpMatcher(prefix, true, parameters.relaxMatching()), contributor, parameters, defaultSorter(parameters), null); + CompletionProgressIndicator process = myCurrentCompletion; + LOG.assertTrue(process != null, "createResultSet may be invoked only during completion"); + CamelHumpMatcher matcher = new CamelHumpMatcher(prefix, true, parameters.relaxMatching()); + CompletionSorterImpl sorter = defaultSorter(parameters); + return new CompletionResultSetImpl(consumer, textBeforePosition, matcher, contributor,parameters, sorter, process, null); } @Override @@ -110,6 +114,7 @@ public class CompletionServiceImpl extends CompletionService{ private final String myTextBeforePosition; private final CompletionParameters myParameters; private final CompletionSorterImpl mySorter; + private final CompletionProgressIndicator myProcess; @Nullable private final CompletionResultSetImpl myOriginal; public CompletionResultSetImpl(final Consumer consumer, final String textBeforePosition, @@ -117,18 +122,21 @@ public class CompletionServiceImpl extends CompletionService{ CompletionContributor contributor, CompletionParameters parameters, @NotNull CompletionSorterImpl sorter, + @NotNull CompletionProgressIndicator process, CompletionResultSetImpl original) { super(prefixMatcher, consumer, contributor); myTextBeforePosition = textBeforePosition; myParameters = parameters; mySorter = sorter; + myProcess = process; myOriginal = original; } - @Override - public void addElement(@NotNull LookupElement element) { - element.putUserDataIfAbsent(CompletionLookupArranger.SORTER_KEY, mySorter); - super.addElement(element); + public void addElement(@NotNull final LookupElement element) { + if (myCompletionService.prefixMatches(element, getPrefixMatcher())) { + myProcess.setItemSorter(element, mySorter); + getConsumer().consume(element); + } } @NotNull @@ -142,7 +150,7 @@ public class CompletionServiceImpl extends CompletionService{ "\ninjected=" + (InjectedLanguageUtil.getTopLevelFile(positionFile) != positionFile) + "\nlang=" + positionFile.getLanguage()); } - return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, matcher, myContributor, myParameters, mySorter, this); + return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, matcher, myContributor, myParameters, mySorter, myProcess, this); } @Override @@ -162,7 +170,7 @@ public class CompletionServiceImpl extends CompletionService{ @NotNull @Override public CompletionResultSet withRelevanceSorter(@NotNull CompletionSorter sorter) { - return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, this); + return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, myProcess, this); } @NotNull From 5a1edc83df2b4842cdc06845d595dde850e97d34 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 15 Apr 2011 15:21:25 +0200 Subject: [PATCH 2/3] less parseMembers() invocations --- .../classParsing/ClassFileReader.java | 56 +++++++------------ .../intellij/compiler/impl/CompileDriver.java | 2 +- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassFileReader.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassFileReader.java index c8c4bae7334e..9d92c03e0781 100644 --- a/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassFileReader.java +++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassFileReader.java @@ -28,7 +28,6 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.cls.BytePointer; import com.intellij.util.cls.ClsFormatException; import com.intellij.util.cls.ClsUtil; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -54,7 +53,8 @@ public class ClassFileReader { private final SymbolTable mySymbolTable; private AnnotationConstantValue[] myRuntimeVisibleAnnotations; private AnnotationConstantValue[] myRuntimeInvisibleAnnotations; - @NonNls private static final String CONSTRUCTOR_NAME = ""; + private static final String CONSTRUCTOR_NAME = ""; + private boolean myParsingDone; public ClassFileReader(@NotNull File file, SymbolTable symbolTable, @Nullable final byte[] fileContent) { mySymbolTable = symbolTable; @@ -72,20 +72,19 @@ public class ClassFileReader { } public MethodInfo[] getMethods() throws ClsFormatException{ - if (myMethods == null) { - parseMembers(); - } + parseMembers(); return myMethods.toArray(new MethodInfo[myMethods.size()]); } public FieldInfo[] getFields() throws ClsFormatException{ - if (myFields == null) { - parseMembers(); - } + parseMembers(); return myFields.toArray(new FieldInfo[myFields.size()]); } private void parseMembers() throws ClsFormatException { + if (myParsingDone) { + return; + } initConstantPool(); myMethods = new ArrayList(); myFields = new ArrayList(); @@ -121,6 +120,7 @@ public class ClassFileReader { myGenericSignature = attributeTable.genericSignature; myRuntimeVisibleAnnotations = attributeTable.runtimeVisibleAnnotations; myRuntimeInvisibleAnnotations = attributeTable.runtimeInvisibleAnnotations; + myParsingDone = true; } private String getSymbol(final int id) throws ClsFormatException { @@ -253,43 +253,27 @@ public class ClassFileReader { public String getSourceFileName() throws ClsFormatException { - if (mySourceFileName == null) { - parseMembers(); - if (mySourceFileName == null) { - mySourceFileName = ""; - } - } - return mySourceFileName; + parseMembers(); + final String fName = mySourceFileName; + return fName != null? fName : ""; } public String getGenericSignature() throws ClsFormatException { - if (myGenericSignature == null) { - parseMembers(); - if (myGenericSignature == null) { - myGenericSignature = ""; - } - } - return myGenericSignature.length() == 0 ? null : myGenericSignature; + parseMembers(); + final String genericSignature = myGenericSignature; + return genericSignature != null && !genericSignature.isEmpty() ? genericSignature : null; } public AnnotationConstantValue[] getRuntimeVisibleAnnotations() throws ClsFormatException { - if (myRuntimeVisibleAnnotations == null) { - parseMembers(); - if (myRuntimeVisibleAnnotations == null) { - myRuntimeVisibleAnnotations = AnnotationConstantValue.EMPTY_ARRAY; - } - } - return myRuntimeVisibleAnnotations; + parseMembers(); + final AnnotationConstantValue[] annotations = myRuntimeVisibleAnnotations; + return annotations != null? annotations : AnnotationConstantValue.EMPTY_ARRAY; } public AnnotationConstantValue[] getRuntimeInvisibleAnnotations() throws ClsFormatException { - if (myRuntimeInvisibleAnnotations == null) { - parseMembers(); - if (myRuntimeInvisibleAnnotations == null) { - myRuntimeInvisibleAnnotations = AnnotationConstantValue.EMPTY_ARRAY; - } - } - return myRuntimeInvisibleAnnotations; + parseMembers(); + final AnnotationConstantValue[] annotations = myRuntimeInvisibleAnnotations; + return annotations != null? annotations : AnnotationConstantValue.EMPTY_ARRAY; } private boolean isInterface(){ diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index e884f85dbfd8..b4321a5b9322 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -190,7 +190,7 @@ public class CompileDriver { } scope = addAdditionalRoots(scope, ALL_EXCEPT_SOURCE_PROCESSING); - final CompilerTask task = new CompilerTask(myProject, true, "", true); + final CompilerTask task = new CompilerTask(myProject, true, "Classes up-to-date check", true); final CompileContextImpl compileContext = new CompileContextImpl(myProject, task, scope, createDependencyCache(), true, false); checkCachesVersion(compileContext, ((PersistentFS)ManagingFS.getInstance()).getCreationTimestamp()); From bc6f186a388d43665d49f5933ec065ed7ec8d5db Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 15 Apr 2011 17:17:45 +0400 Subject: [PATCH 3/3] +setToString() --- .../editors/JBComboBoxTableCellEditorComponent.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/ui/components/editors/JBComboBoxTableCellEditorComponent.java b/platform/platform-api/src/com/intellij/ui/components/editors/JBComboBoxTableCellEditorComponent.java index 5ba558f748fc..63eb44056db5 100644 --- a/platform/platform-api/src/com/intellij/ui/components/editors/JBComboBoxTableCellEditorComponent.java +++ b/platform/platform-api/src/com/intellij/ui/components/editors/JBComboBoxTableCellEditorComponent.java @@ -16,9 +16,11 @@ package com.intellij.ui.components.editors; import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBList; +import com.intellij.util.Function; import com.intellij.util.Icons; import com.intellij.util.ui.EmptyIcon; @@ -40,13 +42,14 @@ public class JBComboBoxTableCellEditorComponent extends JBLabel { private final JBList myList = new JBList(); private Object[] myOptions = {}; private Object myValue; + private Function myToString = StringUtil.createToStringFunction(Object.class); private ListCellRenderer myRenderer = new DefaultListCellRenderer() { public Icon myEmptyIcon; @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - final JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + final JLabel label = (JLabel)super.getListCellRendererComponent(list, myToString.fun(value), index, isSelected, cellHasFocus); if (value == myValue) { label.setIcon(getIcon(isSelected)); } else { @@ -135,4 +138,8 @@ public class JBComboBoxTableCellEditorComponent extends JBLabel { public void setDefaultValue(Object value) { myValue = value; } + + public void setToString(Function toString) { + myToString = toString; + } }