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