IDEA-202262 Wrong cursor position, when IDEA autocompletes List.of(), Set.of() and other Java 9 factory methods for Collections

This commit is contained in:
peter
2019-01-03 12:40:08 +01:00
parent ecf4579ce5
commit 7486e9b9ef
4 changed files with 59 additions and 0 deletions
@@ -64,6 +64,7 @@ public class JavaCompletionSorting {
ContainerUtil.addIfNotNull(afterProximity, PreferMostUsedWeigher.create(position));
afterProximity.add(new PreferContainingSameWords(expectedTypes));
afterProximity.add(new PreferShorter(expectedTypes));
afterProximity.add(new DispreferTechnicalOverloads(position));
CompletionSorter sorter = CompletionSorter.defaultSorter(parameters, result.getPrefixMatcher());
if (!smart && afterNew) {
@@ -608,6 +609,42 @@ public class JavaCompletionSorting {
}
}
/**
* Sometimes there's core vararg method and a couple of overloads of fixed arity to avoid runtime invocation costs of varargs.
* We prefer the vararg method then.
*/
private static class DispreferTechnicalOverloads extends LookupElementWeigher {
private final PsiElement myPlace;
DispreferTechnicalOverloads(PsiElement place) {
super("technicalOverloads");
myPlace = place;
}
@NotNull
@Override
public Comparable weigh(@NotNull LookupElement element) {
Object object = element.getObject();
if (object instanceof PsiMethod && element.getUserData(JavaCompletionUtil.FORCE_SHOW_SIGNATURE_ATTR) == null) {
PsiMethod method = (PsiMethod)object;
PsiClass containingClass = method.getContainingClass();
if (!method.isVarArgs() &&
containingClass != null &&
ContainerUtil.exists(containingClass.findMethodsByName(method.getName(), false), m -> isPurelyVarargOverload(method, m))) {
return true;
}
}
return false;
}
private boolean isPurelyVarargOverload(PsiMethod original, PsiMethod candidate) {
return candidate.hasModifierProperty(PsiModifier.STATIC) == original.hasModifierProperty(PsiModifier.STATIC) &&
candidate.isVarArgs() &&
candidate.getParameterList().getParametersCount() == 1 &&
PsiResolveHelper.SERVICE.getInstance(candidate.getProject()).isAccessible(candidate, myPlace, null);
}
}
private static class LiftShorterClasses extends ClassifierFactory<LookupElement> {
final ProjectFileIndex fileIndex;
private final PsiElement myPosition;
@@ -0,0 +1,10 @@
class C {
void method() {}
void method(String s) {}
void method(String... s) {}
void method1(String... s) {}
{
me<caret>
}
}
@@ -0,0 +1,10 @@
class C {
void method() {}
void method(String s) {}
void method(String... s) {}
void method1(String... s) {}
{
method(<caret>);
}
}
@@ -1892,4 +1892,6 @@ class Abc {
void testNoSuggestionsAfterEnumConstant() { doAntiTest() }
void testPutCaretInsideParensInFixedPlusVarargOverloads() { doTest('\n') }
}