From 724e2c37e5d32107339cf7278f93c94a2e40f7a3 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 20 Nov 2017 16:21:24 +0100 Subject: [PATCH] IDEA-182417 Smart cast completion fails on a specific declarations --- .../completion/JavaCompletionUtil.java | 19 ++++++++++--------- .../CastWhenMethodComesFromDfaSuperType.java | 13 +++++++++++++ ...WhenMethodComesFromDfaSuperType_after.java | 13 +++++++++++++ .../completion/NormalCompletionDfaTest.groovy | 1 + 4 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normal/CastWhenMethodComesFromDfaSuperType.java create mode 100644 java/java-tests/testData/codeInsight/completion/normal/CastWhenMethodComesFromDfaSuperType_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index e861f4f4bdd0..9b801761672c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -404,7 +404,7 @@ public class JavaCompletionUtil { } } - return containsMember(castType, o) && !containsMember(plainQualifier, o); + return containsMember(castType, o, true) && !containsMember(plainQualifier, o, true); } return false; } @@ -469,7 +469,7 @@ public class JavaCompletionUtil { } }), -1); } - if (containsMember(qualifierType, object) && !qualifierType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) { + if (containsMember(qualifierType, object, false) && !qualifierType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) { LookupElementDecorator bold = LookupElementDecorator.withRenderer(item, new LookupElementRenderer>() { @Override public void renderElement(LookupElementDecorator element, LookupElementPresentation presentation) { @@ -495,9 +495,11 @@ public class JavaCompletionUtil { return false; } - @Contract("null, _ -> false") - public static boolean containsMember(@Nullable PsiType qualifierType, @NotNull Object object) { - if (qualifierType instanceof PsiArrayType && object instanceof PsiMember) { //length and clone() + @Contract("null, _, _ -> false") + private static boolean containsMember(@Nullable PsiType qualifierType, @NotNull Object object, boolean checkBases) { + if (!(object instanceof PsiMember)) return false; + + if (qualifierType instanceof PsiArrayType) { //length and clone() PsiFile file = ((PsiMember)object).getContainingFile(); if (file == null || file.getVirtualFile() == null) { //yes, they're a bit dummy return true; @@ -506,12 +508,11 @@ public class JavaCompletionUtil { else if (qualifierType instanceof PsiClassType) { PsiClass qualifierClass = ((PsiClassType)qualifierType).resolve(); if (qualifierClass == null) return false; - if (object instanceof PsiMethod && qualifierClass.findMethodBySignature((PsiMethod)object, false) != null) { + if (object instanceof PsiMethod && qualifierClass.findMethodBySignature((PsiMethod)object, checkBases) != null) { return true; } - if (object instanceof PsiMember) { - return qualifierClass.equals(((PsiMember)object).getContainingClass()); - } + PsiClass memberClass = ((PsiMember)object).getContainingClass(); + return checkBases ? InheritanceUtil.isInheritorOrSelf(qualifierClass, memberClass, true) : qualifierClass.equals(memberClass); } return false; } diff --git a/java/java-tests/testData/codeInsight/completion/normal/CastWhenMethodComesFromDfaSuperType.java b/java/java-tests/testData/codeInsight/completion/normal/CastWhenMethodComesFromDfaSuperType.java new file mode 100644 index 000000000000..a91dd5c1cd7a --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/CastWhenMethodComesFromDfaSuperType.java @@ -0,0 +1,13 @@ +interface E { } + +interface Named { + String getName(); +} +interface MyNamed extends Named {} + +class X { + void foo(E e) { + if (e instanceof MyNamed && e.getn) + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/CastWhenMethodComesFromDfaSuperType_after.java b/java/java-tests/testData/codeInsight/completion/normal/CastWhenMethodComesFromDfaSuperType_after.java new file mode 100644 index 000000000000..972621df4da8 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/CastWhenMethodComesFromDfaSuperType_after.java @@ -0,0 +1,13 @@ +interface E { } + +interface Named { + String getName(); +} +interface MyNamed extends Named {} + +class X { + void foo(E e) { + if (e instanceof MyNamed && ((MyNamed) e).getName()) + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionDfaTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionDfaTest.groovy index a8e4b273bd2c..f0be991724f8 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionDfaTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionDfaTest.groovy @@ -54,6 +54,7 @@ class NormalCompletionDfaTest extends LightFixtureCompletionTestCase { void testStreamDfa() { doTest() } void testOptionalDfa() { doTest() } void testFieldWithCastingCaret() { doTest() } + void testCastWhenMethodComesFromDfaSuperType() { doTest() } void testCastTwice() { configureByTestName()