PreferMostUsedWeigher should return null "helper" methods (ex.: Objects.requireNonNull)

This commit is contained in:
Dmitry Batkovich
2017-04-10 15:16:55 +03:00
parent 9cab9c6e99
commit 0d5d90577d
3 changed files with 102 additions and 4 deletions
@@ -20,9 +20,8 @@ import com.intellij.codeInsight.lookup.LookupElementWeigher;
import com.intellij.compiler.CompilerReferenceService;
import com.intellij.patterns.PsiMethodPattern;
import com.intellij.patterns.StandardPatterns;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMember;
import com.intellij.psi.*;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,7 +29,7 @@ import org.jetbrains.annotations.Nullable;
import static com.intellij.patterns.PsiJavaPatterns.psiMethod;
class PreferMostUsedWeigher extends LookupElementWeigher {
static final PsiMethodPattern OBJECT_METHOD_PATTERN = psiMethod().withName(
private static final PsiMethodPattern OBJECT_METHOD_PATTERN = psiMethod().withName(
StandardPatterns.string().oneOf("hashCode", "equals", "finalize", "wait", "notify", "notifyAll", "getClass", "clone", "toString")).
inClass(CommonClassNames.JAVA_LANG_OBJECT);
@@ -61,8 +60,35 @@ class PreferMostUsedWeigher extends LookupElementWeigher {
if (OBJECT_METHOD_PATTERN.accepts(psi)) {
return null;
}
if (looksLikeHelperMethod(psi)) {
return null;
}
final Integer occurrenceCount = myCompilerReferenceService.getCompileTimeOccurrenceCount(psi, myConstructorSuggestion);
return occurrenceCount == null ? null : - occurrenceCount;
}
}
//Objects.requireNonNull is an example
private static boolean looksLikeHelperMethod(@NotNull PsiElement element) {
if (!(element instanceof PsiMethod)) return false;
PsiMethod method = (PsiMethod)element;
if (method.isConstructor()) return false;
if (isRawDeepTypeEqualToObject(method.getReturnType())) return true;
PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length == 0) return false;
for (PsiParameter parameter : parameters) {
PsiType paramType = parameter.getType();
if (!isRawDeepTypeEqualToObject(paramType)) {
return false;
}
}
return true;
}
private static boolean isRawDeepTypeEqualToObject(@Nullable PsiType type) {
if (type == null) return false;
PsiType rawType = TypeConversionUtil.erasure(type.getDeepComponentType());
if (rawType == null) return false;
return rawType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT);
}
}
@@ -0,0 +1,61 @@
class Foo {
public static void someMethod1() {
}
public static void someMethod2(String string) {
}
void m() {
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
nonNull("");
someMethod1();
someMethod1();
someMethod1();
someMethod2("");
someMethod2("");
someMethod2("");
someMethod2("");
someMethod2("");
<caret>
}
public static <T> T nonNull(T t) {
assert t != null;
return t;
}
}
@@ -72,6 +72,10 @@ public class CompilerReferenceDataInCompletionTest extends CompilerReferencesTes
doTestConstructorCompletionOrdering(new String[] {"Foo.java"}, "List l = new ", "AbstractList", "ArrayList");
}
public void testHelperMethodIsNotAffected() {
doTestStaticMemberCompletionOrdering(new String[] {"Foo.java"}, "someMethod2(1)", "someMethod1(0)", "m(0)", "nonNull(1)");
}
private void doTestConstructorCompletionOrdering(@NotNull String[] files,
@NotNull String phraseToComplete,
String... expectedOrder) {
@@ -82,6 +86,13 @@ public class CompilerReferenceDataInCompletionTest extends CompilerReferencesTes
doTestCompletion(files, "foo.", expectedOrder, m -> "Foo".equals(m.getContainingClass().getName()));
}
private void doTestStaticMemberCompletionOrdering(@NotNull String[] files, String... expectedOrder) {
doTestCompletion(files, "", expectedOrder, (PsiMember m) -> {
PsiClass aClass = m.getContainingClass();
return aClass != null && "Foo".equals(aClass.getName());
});
}
private void doTestCompletion(@NotNull String[] files,
@NotNull String phraseToComplete,
@NotNull String[] expectedOrder,