diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java index b25dcc015862..145e182e7272 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java @@ -67,6 +67,7 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection @SuppressWarnings("WeakerAccess") public boolean REPORT_NOT_ANNOTATED_GETTER = true; @SuppressWarnings("WeakerAccess") public boolean IGNORE_EXTERNAL_SUPER_NOTNULL; @SuppressWarnings("WeakerAccess") public boolean REPORT_NOTNULL_PARAMETERS_OVERRIDES_NOT_ANNOTATED; + @SuppressWarnings("WeakerAccess") public boolean REPORT_NULLABILITY_ANNOTATION_ON_LOCALS = true; /** * @deprecated the field remains to minimize changes to users' inspection profiles. */ @@ -92,6 +93,7 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection if ("IGNORE_EXTERNAL_SUPER_NOTNULL".equals(name) && "false".equals(value) || "REPORT_NOTNULL_PARAMETERS_OVERRIDES_NOT_ANNOTATED".equals(name) && "false".equals(value) || "REQUIRE_NOTNULL_FIELDS_INITIALIZED".equals(name) && "true".equals(value) || + "REPORT_NULLABILITY_ANNOTATION_ON_LOCALS".equals(name) && "true".equals(value) || "REPORT_NULLS_PASSED_TO_NOT_NULL_PARAMETER".equals(name) && "true".equals(value)) { node.removeContent(child); } @@ -338,6 +340,7 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection } private void checkIllegalLocalAnnotation(@NotNull PsiAnnotation annotation, @Nullable PsiElement owner) { + if (!REPORT_NULLABILITY_ANNOTATION_ON_LOCALS) return; if (owner instanceof PsiLocalVariable || owner instanceof PsiParameter parameter && parameter.getDeclarationScope() instanceof PsiCatchSection) { diff --git a/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java b/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java index 13f9fa5f7530..399641b8cf72 100644 --- a/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java @@ -44,6 +44,7 @@ public class NullableStuffInspection extends NullableStuffInspectionBase { checkbox("REPORT_NOTNULL_PARAMETERS_OVERRIDES_NOT_ANNOTATED", JavaBundle.message("inspection.nullable.problems.notnull.overrides.option")), checkbox("REPORT_NOT_ANNOTATED_GETTER", JavaBundle.message("inspection.nullable.problems.not.annotated.getters.for.annotated.fields")), checkbox("REPORT_NULLS_PASSED_TO_NOT_NULL_PARAMETER", JavaBundle.message("inspection.nullable.problems.notnull.parameters.with.null.literal.option")), + checkbox("REPORT_NULLABILITY_ANNOTATION_ON_LOCALS", JavaBundle.message("inspection.nullable.problems.nullability.on.locals")), JavaInspectionControls.button(JavaInspectionButtons.ButtonKind.NULLABILITY_ANNOTATIONS) ); } diff --git a/java/java-tests/testData/inspection/nullableProblems/DisableOnLocals2.java b/java/java-tests/testData/inspection/nullableProblems/DisableOnLocals2.java new file mode 100644 index 000000000000..4ab966359e3c --- /dev/null +++ b/java/java-tests/testData/inspection/nullableProblems/DisableOnLocals2.java @@ -0,0 +1,16 @@ +import org.jspecify.annotations.Nullable; + +import java.util.List; + +class Demo { + public void demo() { + @Nullable String str; + + @Nullable List<@Nullable String> list; + + @Nullable Boolean[] array1 = new Boolean[]{true, false, null}; + Boolean @Nullable [] array2 = null; + Boolean @Nullable [] [] array3 = null; + Boolean [] @Nullable [] array4 = null; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/NullableStuffInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/NullableStuffInspectionTest.java index 033cf1df20af..329ba71c895f 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/NullableStuffInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/NullableStuffInspectionTest.java @@ -427,6 +427,12 @@ public class NullableStuffInspectionTest extends LightJavaCodeInsightFixtureTest doTest(); } + public void testDisableOnLocals2() { + myInspection.REPORT_NULLABILITY_ANNOTATION_ON_LOCALS = false; + setupTypeUseAnnotations("org.jspecify.annotations", myFixture); + doTest(); + } + public void testOverriddenWithNullMarked() { myInspection.REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; addJSpecifyNullMarked(myFixture); diff --git a/java/openapi/resources/messages/JavaBundle.properties b/java/openapi/resources/messages/JavaBundle.properties index 601620b23ab2..82492dc2328d 100644 --- a/java/openapi/resources/messages/JavaBundle.properties +++ b/java/openapi/resources/messages/JavaBundle.properties @@ -553,6 +553,7 @@ inspection.nullable.problems.method.overrides.option=Report non-&annotated param inspection.nullable.problems.not.annotated.getters.for.annotated.fields=Report non-annotated &setter parameters or getters of annotated fields inspection.nullable.problems.notnull.overrides.option=Report @NotNull ¶meters overriding non-annotated inspection.nullable.problems.notnull.parameters.with.null.literal.option=Report @NotNull parameters with null-literal argument usages +inspection.nullable.problems.nullability.on.locals=Report nullability annotations on local variables when they are non-applicable inspection.optional.get.without.is.present.message={0}.#ref() without ''isPresent()'' check inspection.optional.get.without.is.present.method.reference.message=#ref without 'isPresent()' check inspection.overflowing.loop.index.inspection.description=Loop executes zero or billions of times