move completion suggestions before lambda only when they really match specific expected type (IDEA-183592)

This commit is contained in:
peter
2017-12-12 17:55:37 +01:00
parent 206db0b7b9
commit beb4f6dba7
3 changed files with 20 additions and 2 deletions

View File

@@ -255,7 +255,15 @@ public class PreferByKindWeigher extends LookupElementWeigher {
private boolean isExpectedTypeItem(@NotNull LookupElement item) {
TypedLookupItem typed = item.as(TypedLookupItem.CLASS_CONDITION_KEY);
PsiType itemType = typed == null ? null : typed.getType();
return itemType != null && Arrays.stream(myExpectedTypes).anyMatch(info -> info.getType().isAssignableFrom(itemType));
return itemType != null &&
Arrays.stream(myExpectedTypes)
.map(ExpectedTypeInfo::getType)
.anyMatch(type -> !isTooGeneric(type) && type.isAssignableFrom(itemType));
}
private static boolean isTooGeneric(PsiType type) {
PsiType erasure = TypeConversionUtil.erasure(type);
return erasure == null || erasure.equalsToText(CommonClassNames.JAVA_LANG_OBJECT);
}
@NotNull
@@ -278,7 +286,7 @@ public class PreferByKindWeigher extends LookupElementWeigher {
if (myCompletionType == CompletionType.SMART) {
boolean inReturn = psiElement().withParents(PsiReferenceExpression.class, PsiReturnStatement.class).accepts(myPosition);
return inReturn ? ThreeState.YES : ThreeState.UNSURE;
} else if (Arrays.stream(myExpectedTypes).anyMatch(info -> PsiType.BOOLEAN.isConvertibleFrom(info.getDefaultType())) &&
} else if (Arrays.stream(myExpectedTypes).anyMatch(info -> PsiType.BOOLEAN.isAssignableFrom(info.getDefaultType())) &&
PsiTreeUtil.getParentOfType(myPosition, PsiIfStatement.class, true, PsiStatement.class, PsiMember.class) == null) {
return ThreeState.YES;
}

View File

@@ -0,0 +1,5 @@
class Foo {
void foo(java.util.stream.Stream<Foo> s, int local, StringBuilder local2) {
s.reduce(<caret>)
}
}

View File

@@ -310,6 +310,11 @@ class Test88 {
myFixture.assertPreferredCompletionItems 0, '() -> ', 'AbstractMethodError::new'
}
void testPreferLambdaToTooGenericLocalVariables() {
configureByTestName()
myFixture.assertPreferredCompletionItems 0, '(foo, foo2) -> '
}
private checkResultByFileName() {
checkResultByFile(getTestName(false) + "_after.java")
}