java completion: supply same-named classes in batches for more deterministic sorting and preselection (IDEA-229266)

GitOrigin-RevId: 44c3e4a0f9a150082b1f3210b25f5b4c79f64e7f
This commit is contained in:
Peter Gromov
2020-06-17 08:01:17 +03:00
committed by intellij-monorepo-bot
parent aae6226e1b
commit 480104b91d
4 changed files with 42 additions and 13 deletions
@@ -527,11 +527,7 @@ public class JavaCompletionContributor extends CompletionContributor {
}
if (parameters.getInvocationCount() >= 2) {
JavaClassNameCompletionContributor.addAllClasses(parameters, parameters.getInvocationCount() <= 2, result.getPrefixMatcher(), element -> {
if (!session.alreadyProcessed(element)) {
result.addElement(JavaCompletionUtil.highlightIfNeeded(null, element, element.getObject(), parameters.getPosition()));
}
});
JavaNoVariantsDelegator.suggestNonImportedClasses(parameters, result, session);
}
else {
advertiseSecondCompletion(parameters.getPosition().getProject(), result);
@@ -32,9 +32,7 @@ import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.*;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
@@ -196,18 +194,25 @@ public class JavaNoVariantsDelegator extends CompletionContributor {
return allClasses;
}
private static void suggestNonImportedClasses(CompletionParameters parameters, CompletionResultSet result, @Nullable JavaCompletionSession session) {
JavaClassNameCompletionContributor.addAllClasses(parameters, true, result.getPrefixMatcher(), element -> {
static void suggestNonImportedClasses(CompletionParameters parameters, CompletionResultSet result, @Nullable JavaCompletionSession session) {
List<LookupElement> sameNamedBatch = new ArrayList<>();
JavaClassNameCompletionContributor.addAllClasses(parameters, parameters.getInvocationCount() <= 2, result.getPrefixMatcher(), element -> {
if (session != null && session.alreadyProcessed(element)) {
return;
}
JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
if (classElement != null) {
if (classElement != null && parameters.getInvocationCount() < 2) {
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
}
result.addElement(element);
element = JavaCompletionUtil.highlightIfNeeded(null, element, element.getObject(), parameters.getPosition());
if (!sameNamedBatch.isEmpty() && !element.getLookupString().equals(sameNamedBatch.get(0).getLookupString())) {
result.addAllElements(sameNamedBatch);
sameNamedBatch.clear();
}
sameNamedBatch.add(element);
});
result.addAllElements(sameNamedBatch);
}
public static class ResultTracker implements Consumer<CompletionResult> {
@@ -5,6 +5,7 @@ import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.codeInsight.completion.LightFixtureCompletionTestCase;
import com.intellij.codeInsight.completion.StatisticsUpdate;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupEx;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
import com.intellij.ide.ui.UISettings;
import com.intellij.psi.statistics.StatisticsManager;
@@ -76,7 +77,7 @@ public abstract class CompletionSortingTestCase extends LightFixtureCompletionTe
lookup.resort(true);
}
protected static void imitateItemSelection(final LookupImpl lookup, final int index) {
protected static void imitateItemSelection(LookupEx lookup, final int index) {
final LookupElement item = lookup.getItems().get(index);
lookup.setCurrentItem(item);
StatisticsUpdate.collectStatisticChanges(item);
@@ -40,6 +40,8 @@ import com.intellij.psi.NavigatablePsiElement
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiMethod
import com.intellij.psi.statistics.StatisticsManager
import com.intellij.psi.statistics.impl.StatisticsManagerImpl
import com.intellij.psi.util.InheritanceUtil
import com.intellij.testFramework.TestModeFlags
import com.intellij.testFramework.fixtures.CodeInsightTestUtil
@@ -1809,4 +1811,29 @@ ita<caret>
assert firstItems.each { InheritanceUtil.isInheritor(it.object as PsiClass, List.name) }
}
void "test prefer previously selected despite many namesakes"() {
((StatisticsManagerImpl)StatisticsManager.getInstance()).enableStatistics(myFixture.getTestRootDisposable())
def count = 400
def toSelect = 390
for (i in 0..<count) {
myFixture.addClass("package p$i; public class MyClass {}")
}
myFixture.configureByText "a.java", "class C extends <caret>"
type 'MyCla'
myFixture.assertPreferredCompletionItems 0, Collections.nCopies(count, 'MyClass') as String[]
edt {
assert LookupElementPresentation.renderElement(myFixture.lookup.items[toSelect]).tailText == " p$toSelect"
CompletionSortingTestCase.imitateItemSelection(myFixture.lookup, toSelect)
myFixture.lookup.hideLookup(true)
}
type 's'
myFixture.assertPreferredCompletionItems 0, Collections.nCopies(count, 'MyClass') as String[]
edt {
assert LookupElementPresentation.renderElement(myFixture.lookup.items[0]).tailText == " p$toSelect"
}
}
}