From 0bae70149a34e8e21c2f32c8967c1f4c8e7c8106 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 18 Aug 2015 19:49:14 +0200 Subject: [PATCH] IDEA-143937 Bogus warning by 'Constant conditions & exceptions' inspection within lambda expressions, due to JSR 305 @TypeQualifierDefault annotation --- .../codeInsight/AnnotationTargetUtil.java | 11 ++++++++ ...ambdaParametersWithDefaultNullability.java | 26 +++++++++++++++++++ .../ParametersAreNonnullByDefault.java | 11 ++++++++ .../DataFlowInspection8Test.java | 7 +++++ 4 files changed, 55 insertions(+) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/LambdaParametersWithDefaultNullability.java diff --git a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java index c1a747fb3b03..79df7a9d64b5 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java @@ -85,6 +85,17 @@ public class AnnotationTargetUtil { return FIELD_TARGETS; } if (element instanceof PsiParameter) { + // PARAMETER applies only to formal parameters (methods & lambdas) and catch parameters + // see https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.6.4.1 + PsiElement scope = element.getParent(); + if (scope instanceof PsiForeachStatement) { + return LOCAL_VARIABLE_TARGETS; + } + if (scope instanceof PsiParameterList && scope.getParent() instanceof PsiLambdaExpression && + ((PsiParameter)element).getTypeElement() == null) { + return TargetType.EMPTY_ARRAY; + } + return PARAMETER_TARGETS; } if (element instanceof PsiLocalVariable) { diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/LambdaParametersWithDefaultNullability.java b/java/java-tests/testData/inspection/dataFlow/fixture/LambdaParametersWithDefaultNullability.java new file mode 100644 index 000000000000..e25d5ff501d7 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/LambdaParametersWithDefaultNullability.java @@ -0,0 +1,26 @@ +import javax.annotation.*; + +@ParametersAreNonnullByDefault +class Test { + void foo() { + Intf i1 = (o) -> { + if (o == null) { + System.out.println(); + } + }; + Intf i2 = (Object o) -> { + if (o == null) { + System.out.println(); + } + }; + Intf i3 = (@Nullable Object o) -> { + if (o == null) { + System.out.println(); + } + }; + } +} + +interface Intf { + void foo(Object o); +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ParametersAreNonnullByDefault.java b/java/java-tests/testData/inspection/dataFlow/fixture/ParametersAreNonnullByDefault.java index 7dc2e51effe4..4c06b23c8f8b 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/ParametersAreNonnullByDefault.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ParametersAreNonnullByDefault.java @@ -14,6 +14,17 @@ class Some { } +@javax.annotation.ParametersAreNonnullByDefault +class CheckLoop { + void foo(Iterable it) { + for (String s : it) { + if (s == null) { // it's not ElementType.PARAMETER, no warning here + System.out.println(); + } + } + } +} + @javax.annotation.ParametersAreNonnullByDefault class NotNullClass { static void foo(String s) {} diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspection8Test.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspection8Test.java index 90f864e137d2..27319dfd6fe3 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspection8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspection8Test.java @@ -98,4 +98,11 @@ public class DataFlowInspection8Test extends LightCodeInsightFixtureTestCase { public void testOptionalOfNullable() { doTest(); } + public void testLambdaParametersWithDefaultNullability() { + DataFlowInspectionTest.addJavaxNullabilityAnnotations(myFixture); + DataFlowInspectionTest.addJavaxDefaultNullabilityAnnotations(myFixture); + + doTest(); + } + }