Java: Remove duplicates from the completion list for argument of getMethod(). Simplified priority in the argument completion for getField() and getMethod() (IDEA-167250)

This commit is contained in:
Pavel Dolgov
2017-02-16 16:00:47 +03:00
parent 926b28246f
commit 0a85d2a207
6 changed files with 79 additions and 12 deletions

View File

@@ -18,18 +18,20 @@ package com.intellij.psi.impl.source.resolve.reference.impl;
import com.intellij.codeInsight.completion.InsertHandler;
import com.intellij.codeInsight.completion.InsertionContext;
import com.intellij.codeInsight.completion.JavaLookupElementBuilder;
import com.intellij.codeInsight.completion.PrioritizedLookupElement;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import static com.intellij.psi.impl.source.resolve.reference.impl.JavaReflectionReferenceUtil.*;
@@ -135,12 +137,21 @@ public class JavaLangClassMemberReference extends PsiReferenceBase<PsiLiteralExp
.map(method -> lookupMethod(method))
.toArray();
case METHOD:
return Arrays.stream(psiClass.getAllMethods())
.filter(method -> isRegularMethod(method) && isPotentiallyAccessible(method, psiClass))
case METHOD: {
final List<PsiMethod> methods = ContainerUtil.filter(
psiClass.getAllMethods(), method -> isRegularMethod(method) && isPotentiallyAccessible(method, psiClass));
final Set<PsiMethod> superMethods = new THashSet<>();
for (PsiMethod method : methods) {
ContainerUtil.addAll(superMethods, method.findSuperMethods());
}
return methods.stream()
.filter(method -> !superMethods.contains(method))
.sorted(Comparator.comparingInt((PsiMethod method) -> getMethodSortOrder(method)).thenComparing(PsiMethod::getName))
.map(method -> PrioritizedLookupElement.withPriority(lookupMethod(method), -getMethodSortOrder(method)))
.map(method -> withPriority(lookupMethod(method), -getMethodSortOrder(method)))
.toArray();
}
}
}
}

View File

@@ -180,6 +180,11 @@ class JavaReflectionReferenceUtil {
@NotNull
static LookupElement withPriority(LookupElement lookupElement, boolean hasPriority) {
return PrioritizedLookupElement.withPriority(lookupElement, hasPriority ? 1 : -1);
return hasPriority ? lookupElement : PrioritizedLookupElement.withPriority(lookupElement, -1);
}
@NotNull
static LookupElement withPriority(LookupElement lookupElement, int priority) {
return priority == 0 ? lookupElement : PrioritizedLookupElement.withPriority(lookupElement, priority);
}
}

View File

@@ -0,0 +1,23 @@
class Main {
void foo() {
Test.class.getMethod("<caret>");
}
}
class Test extends Parent {
public void method(){}
public void pMethod(C c){}
public void gpMethod(A a, B b){}
}
class Parent extends GrandParent {
public void pMethod(C c){}
}
class GrandParent {
public void gpMethod(A a, B b){}
}
class A {}
class B {}
class C {}

View File

@@ -0,0 +1,23 @@
class Main {
void foo() {
Test.class.getMethod("pMethod", C.class);
}
}
class Test extends Parent {
public void method(){}
public void pMethod(C c){}
public void gpMethod(A a, B b){}
}
class Parent extends GrandParent {
public void pMethod(C c){}
}
class GrandParent {
public void gpMethod(A a, B b){}
}
class A {}
class B {}
class C {}

View File

@@ -24,7 +24,9 @@ class JavaReflectionCompletionOverloadTest : LightFixtureCompletionTestCase() {
override fun getBasePath() = JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/completion/reflectionOverload/"
fun testOverloadMethods() = doTest(2, "method()", "method(C c)", "method(A a,B b)")
fun testOverloadMethods() = doTest(2,
"method()", "method(C c)", "method(A a,B b)",
"equals(java.lang.Object obj)")
fun testJavaLangObjectMethods() = doTest(6,
"method()",
@@ -37,15 +39,18 @@ class JavaReflectionCompletionOverloadTest : LightFixtureCompletionTestCase() {
"clone()", "equals(java.lang.Object obj)", "hashCode()",
"toString()", "finalize()", "getClass()",
"notify()", "notifyAll()",
"wait()", "wait(long timeout)", "wait(long timeout,int nanos)",
"registerNatives()")
"wait()", "wait(long timeout)", "wait(long timeout,int nanos)")
fun testOverriddenMethod() = doTest(2,
"gpMethod(A a,B b)", "method()", "pMethod(C c)",
"equals(java.lang.Object obj)")
private fun doTest(index: Int, vararg expected: String) {
configureByFile(getTestName(false) + ".java")
val lookupItems = lookup.items
val texts = lookupItemTexts(lookupItems, expected.size)
val texts = lookupFirstItemsTexts(lookupItems, expected.size)
assertOrderedEquals(texts, *expected)
if (index >= 0) selectItem(lookupItems[index])
myFixture.checkResultByFile(getTestName(false) + "_after.java")

View File

@@ -81,7 +81,7 @@ class JavaReflectionParametersCompletionTest : LightFixtureCompletionTestCase()
configureByFile(getTestName(false) + ".java")
val lookupItems = lookup.items
val texts = lookupItemTexts(lookupItems, expected.size)
val texts = lookupFirstItemsTexts(lookupItems, expected.size)
assertOrderedEquals(texts, *expected)
selectItem(lookupItems[index])
myFixture.checkResultByFile(getTestName(false) + "_after.java")
@@ -110,7 +110,7 @@ public class Construct {
}
}
fun lookupItemTexts(lookupItems: List<LookupElement?>, maxSize: Int): List<String> =
fun lookupFirstItemsTexts(lookupItems: List<LookupElement?>, maxSize: Int): List<String> =
lookupItems.subList(0, Math.min(lookupItems.size, maxSize)).map {
val obj = it?.`object`
when (obj) {