From 5b3f88ca2c114fc240cb9e29b3d0bddd9ca7d5a0 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Thu, 22 Jan 2026 13:41:51 +0100 Subject: [PATCH] IDEA-382900 [java-dfa] False positive null check inspection for Optional Space-RevId: 1e8a9a958d359c00479687ccac4877b19a039cd8 GitOrigin-RevId: d4987256123b7a71c42f882138fec18b2ec34d91 --- .../dataFlow/fixture/OptionalInference.java | 53 +++++++++++++++++++ .../daemon/inlays/AnnotationHintsTest.kt | 4 +- .../DataFlowInspection21Test.java | 4 ++ java/jdkAnnotations/java/util/annotations.xml | 7 +++ 4 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/OptionalInference.java diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/OptionalInference.java b/java/java-tests/testData/inspection/dataFlow/fixture/OptionalInference.java new file mode 100644 index 000000000000..bfdbbc8109a2 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/OptionalInference.java @@ -0,0 +1,53 @@ +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +class NullTest { + + enum StatusEnum { + + OK(1, "OK"), ERROR(2, "ERROR"); + + final Integer code; + + final String msg; + + StatusEnum(Integer code, String msg) { + this.code = code; + this.msg = msg; + } + } + + public static StatusEnum getInstance(Integer code) { + return Arrays.stream(StatusEnum.values()) + .filter(it -> Objects.equals(it.code, code)) + .findFirst() + .orElse(null); + } + + public void test2() { + StatusEnum instance = getInstance(11); + if (instance == null) { + System.out.println("Instance not found"); + return; + } + System.out.println(instance); + } + + static String getString(List list) { + return list.stream() + .findFirst() + .orElseGet(() -> null); + } + + void testOrElseGet() { + if (getString(List.of()) == null) { + return; + } + } + + static void main() { + new NullTest().test2(); + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/inlays/AnnotationHintsTest.kt b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/inlays/AnnotationHintsTest.kt index 75835ad1c252..33d91fcfcd45 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/inlays/AnnotationHintsTest.kt +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/inlays/AnnotationHintsTest.kt @@ -229,11 +229,11 @@ public final class Optional*/T> { return this.isEmpty() ? Stream.empty() : Stream.of(this.value); } - /*<# @Contract(value = "!null -> !null", pure = true) #>*//*<# @Flow(sourceIsContainer = true) #>*/public T orElse(/*<# @Flow(targetIsContainer = true) #>*//*<# @Nullable #>*/T other) { + /*<# @Contract(value = "!null -> !null", pure = true) #>*//*<# @Flow(sourceIsContainer = true) #>*/public /*<# @Nullable #>*/T orElse(/*<# @Flow(targetIsContainer = true) #>*//*<# @Nullable #>*/T other) { return (T)(this.value != null ? this.value : other); } - public T orElseGet(Supplier supplier) { + public /*<# @UnknownNullability #>*/T orElseGet(Supplier*/T> supplier) { return (T)(this.value != null ? this.value : supplier.get()); } diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection21Test.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection21Test.java index 2ee0476294bc..5ee592ebd4e0 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection21Test.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection21Test.java @@ -254,4 +254,8 @@ public class DataFlowInspection21Test extends DataFlowInspectionTestCase { setupTypeUseAnnotations("org.jspecify.annotations", myFixture); doTest(); } + + public void testOptionalInference() { + doTestWith((dfi, cvi) -> dfi.SUGGEST_NULLABLE_ANNOTATIONS = false); + } } \ No newline at end of file diff --git a/java/jdkAnnotations/java/util/annotations.xml b/java/jdkAnnotations/java/util/annotations.xml index c82ab384cbff..139242e74152 100644 --- a/java/jdkAnnotations/java/util/annotations.xml +++ b/java/jdkAnnotations/java/util/annotations.xml @@ -4433,6 +4433,7 @@ + @@ -4447,6 +4448,12 @@ + + + + + +