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 @@ + + + + + +