From ecab324ae0d7e6071650e446b948cc890ad8b498 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 13 Apr 2015 18:42:28 +0300 Subject: [PATCH] dfa: overriding @NotNull has precedence over super method @Nullable --- .../codeInsight/NullableNotNullManager.java | 16 +++++++----- .../fixture/NotNullOverridesNullable.java | 26 +++++++++++++++++++ .../DataFlowInspectionTest.java | 2 ++ .../DataFlowInspectionTestSuite.java | 2 ++ 4 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/NotNullOverridesNullable.java diff --git a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java index 6e74999a2875..d5cf095b9704 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java @@ -169,13 +169,16 @@ public abstract class NullableNotNullManager implements PersistentStateComponent @Nullable private PsiAnnotation findNullabilityAnnotationWithDefault(@NotNull PsiModifierListOwner owner, boolean checkBases, boolean nullable) { - PsiAnnotation annotation = findPlainNullabilityAnnotation(owner, checkBases, nullable); + PsiAnnotation annotation = findPlainNullabilityAnnotation(owner, checkBases); if (annotation != null) { + String qName = annotation.getQualifiedName(); + if (qName == null) return null; + + List contradictory = nullable ? getNotNulls() : getNullables(); + if (contradictory.contains(qName)) return null; + return annotation; } - if (findPlainNullabilityAnnotation(owner, checkBases, !nullable) != null) { - return null; - } PsiType type = getOwnerType(owner); if (type == null || TypeConversionUtil.isPrimitiveAndNotNull(type)) return null; @@ -192,8 +195,9 @@ public abstract class NullableNotNullManager implements PersistentStateComponent return findNullabilityDefaultInHierarchy(owner, nullable); } - private PsiAnnotation findPlainNullabilityAnnotation(@NotNull PsiModifierListOwner owner, boolean checkBases, boolean nullable) { - Set qNames = ContainerUtil.newHashSet(nullable ? getNullables() : getNotNulls()); + private PsiAnnotation findPlainNullabilityAnnotation(@NotNull PsiModifierListOwner owner, boolean checkBases) { + Set qNames = ContainerUtil.newHashSet(getNullables()); + qNames.addAll(getNotNulls()); return checkBases && owner instanceof PsiMethod ? AnnotationUtil.findAnnotationInHierarchy(owner, qNames) : AnnotationUtil.findAnnotation(owner, qNames); diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/NotNullOverridesNullable.java b/java/java-tests/testData/inspection/dataFlow/fixture/NotNullOverridesNullable.java new file mode 100644 index 000000000000..34bae955795e --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/NotNullOverridesNullable.java @@ -0,0 +1,26 @@ +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.Object; +import java.lang.Override; + +class Super { + @Nullable Object foo() { + return null; + } +} + +class Main extends Super { + @NotNull + @Override + Object foo() { + return 2; + } + + void bar(@NotNull Object o) {} + + void goo() { + bar(foo()); + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java index 16f34a8d7449..51dbce40c804 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java @@ -279,6 +279,8 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase { public void testSameComparisonTwice() { doTest(); } public void testRootThrowableCause() { doTest(); } + public void testNotNullOverridesNullable() { doTest(); } + public void testOverridingInferredNotNullMethod() { doTest(); } public void testUseInferredContracts() { doTest(); } public void testContractWithNoArgs() { doTest(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java index fd8147bc8355..674a0f8cbb50 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java @@ -37,6 +37,8 @@ public class DataFlowInspectionTestSuite { suite.addTestSuite(SliceBackwardTest.class); suite.addTestSuite(SmartTypeCompletionDfaTest.class); suite.addTestSuite(NormalCompletionDfaTest.class); + suite.addTestSuite(NullableStuffInspectionTest.class); + suite.addTestSuite(NullableStuffInspection14Test.class); return suite; } }