diff --git a/java/java-impl/src/com/intellij/codeInsight/annoPackages/JetBrainsAnnotationSupport.java b/java/java-impl/src/com/intellij/codeInsight/annoPackages/JetBrainsAnnotationSupport.java
index 709b4e325649..1d961d0fa9f6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/annoPackages/JetBrainsAnnotationSupport.java
+++ b/java/java-impl/src/com/intellij/codeInsight/annoPackages/JetBrainsAnnotationSupport.java
@@ -17,8 +17,10 @@ class JetBrainsAnnotationSupport implements AnnotationPackageSupport {
return Collections.singletonList(AnnotationUtil.NOT_NULL);
case NULLABLE:
return Collections.singletonList(AnnotationUtil.NULLABLE);
+ case UNKNOWN:
+ return Collections.singletonList(AnnotationUtil.UNKNOWN_NULLABILITY);
default:
- return Collections.emptyList();
+ throw new IllegalStateException("Unexpected value: " + nullability);
}
}
}
diff --git a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
index 2548e8396136..589e3ce3b619 100644
--- a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
+++ b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
@@ -21,6 +21,7 @@ import java.util.stream.Stream;
@ApiStatus.NonExtendable
public class AnnotationUtil {
public static final String NULLABLE = "org.jetbrains.annotations.Nullable";
+ public static final String UNKNOWN_NULLABILITY = "org.jetbrains.annotations.UnknownNullability";
public static final String NOT_NULL = "org.jetbrains.annotations.NotNull";
public static final String NON_NLS = "org.jetbrains.annotations.NonNls";
@@ -220,7 +221,7 @@ public class AnnotationUtil {
AnnotationAndOwner result = findAnnotationAndOwnerInHierarchy(listOwner, annotationNames, skipExternal);
return result == null ? null : result.annotation;
}
-
+
static final class AnnotationAndOwner {
final @NotNull PsiModifierListOwner owner;
final @NotNull PsiAnnotation annotation;
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/UnknownNullability.java b/java/java-tests/testData/inspection/dataFlow/fixture/UnknownNullability.java
new file mode 100644
index 000000000000..a7cf27bee070
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/UnknownNullability.java
@@ -0,0 +1,33 @@
+import org.jetbrains.annotations.*;
+
+class UnknownNullabilityTest {
+ static final String getString() {
+ return "foo";
+ }
+
+ static final @UnknownNullability String getString2() {
+ return "foo";
+ }
+
+ static final String getStringNullable() {
+ return Math.random() > 0.5 ? "foo" : null;
+ }
+
+ static final @UnknownNullability String getStringNullable2() {
+ return Math.random() > 0.5 ? "foo" : null;
+ }
+
+ void check() {
+ if (getString() == null) {}
+ if (getString2() == null) {}
+ if (getStringNullable() == null) {}
+ if (getStringNullable2() == null) {}
+ }
+
+ void deref() {
+ if (Math.random() > 0.5) getString().trim();
+ if (Math.random() > 0.5) getString2().trim();
+ if (Math.random() > 0.5) getStringNullable().trim();
+ if (Math.random() > 0.5) getStringNullable2().trim();
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java
index bba90e726bf2..95f0ecd5b438 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java
@@ -188,7 +188,7 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase {
public void testStreamInlining() { doTest(); }
public void testStreamCollectInlining() {
setupTypeUseAnnotations("foo", myFixture);
- doTest();
+ doTest();
}
public void testStreamCollectorInlining() { doTest(); }
public void testStreamToMapInlining() { doTest(); }
@@ -203,7 +203,7 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase {
public void testStreamAnyMatchIsNull() { doTest(); }
public void testStreamCustomSumMethod() { doTest(); }
public void testStreamReduceLogicalAnd() { doTest(); }
-
+
public void testMapGetWithValueNullability() { doTestWithCustomAnnotations(); }
public void testInferNestedForeachNullability() { doTestWithCustomAnnotations(); }
@@ -251,7 +251,7 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase {
doTest();
}
- public void testConflictsInInferredTypes() {
+ public void testConflictsInInferredTypes() {
setupAmbiguousAnnotations("foo", myFixture);
doTest();
}
@@ -330,4 +330,10 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase {
doTest();
}
public void testConstantInClosure() { doTest(); }
+ public void testUnknownNullability() {
+ myFixture.addClass("package org.jetbrains.annotations;\nimport java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "public @interface UnknownNullability { }");
+ doTestWith(insp -> insp.SUGGEST_NULLABLE_ANNOTATIONS = false);
+ }
}
\ No newline at end of file