From 906dfbdffa35cc724e6a9945f02e9c0af4e36f55 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Wed, 5 May 2021 18:02:15 +0700 Subject: [PATCH] [java-dfa] Do not suggest 'Nullable' annotation if SUGGEST_NULLABLE_ANNOTATIONS is turned off and NotNull is inferred GitOrigin-RevId: f1b30c8502b8b596d82ad8fea7b9a7aaceef6b80 --- .../dataFlow/DataFlowInspectionBase.java | 7 ++++--- .../fixture/InferenceNullityMismatch.java | 16 ++++++++++++++++ .../codeInspection/DataFlowInspectionTest.java | 1 + 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/InferenceNullityMismatch.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java index 5cde970e0fd0..6b2cbf0171e1 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java @@ -994,9 +994,10 @@ public abstract class DataFlowInspectionBase extends AbstractBaseJavaLocalInspec PsiAnnotation anno = info == null ? null : info.getAnnotation(); Nullability nullability = info == null ? Nullability.UNKNOWN : info.getNullability(); if (nullability == Nullability.NULLABLE) { - if (!AnnotationUtil.isInferredAnnotation(anno)) return; - if (DfaPsiUtil.getTypeNullability(method.getReturnType()) == Nullability.NULLABLE) return; + if (!info.isInferred() || DfaPsiUtil.getTypeNullability(method.getReturnType()) == Nullability.NULLABLE) return; } + // In rare cases, inference may produce different result (e.g. if nullable method overrides non-null method) + if (nullability == Nullability.NOT_NULL && info.isInferred()) return; if (nullability != Nullability.NOT_NULL && (!SUGGEST_NULLABLE_ANNOTATIONS || block.getParent() instanceof PsiLambdaExpression)) return; @@ -1013,7 +1014,7 @@ public abstract class DataFlowInspectionBase extends AbstractBaseJavaLocalInspec boolean exactlyNull = isNullLiteralExpression(expr) || expressions.get(expr) == ConstantResult.NULL; if (!REPORT_UNSOUND_WARNINGS && !exactlyNull) continue; - if (nullability == Nullability.NOT_NULL && !info.isInferred()) { + if (nullability == Nullability.NOT_NULL) { String presentable = NullableStuffInspectionBase.getPresentableAnnoName(anno); final String text = exactlyNull ? JavaAnalysisBundle.message("dataflow.message.return.null.from.notnull", presentable) diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/InferenceNullityMismatch.java b/java/java-tests/testData/inspection/dataFlow/fixture/InferenceNullityMismatch.java new file mode 100644 index 000000000000..05ebea976d90 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/InferenceNullityMismatch.java @@ -0,0 +1,16 @@ +import org.jetbrains.annotations.*; + +public class InferenceNullityMismatch { + static String getData(Super obj) { + if (!(obj instanceof Sub)) { + throw new IllegalArgumentException(); + } + return obj.calculate(); + } +} +class Super { + native @NotNull String calculate(); +} +class Sub extends Super { + native @Nullable String calculate(); +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java index 447b830a1459..2f4706aaaab2 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -700,4 +700,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testCastInCatch() { doTest(); } public void testInitArrayInConstructor() { doTest(); } public void testGetterNullityAfterCheck() { doTest(); } + public void testInferenceNullityMismatch() { doTestWith(insp -> insp.SUGGEST_NULLABLE_ANNOTATIONS = false); } }