@@ -66,23 +66,26 @@ object JavaNullInterop {
6666 nullifyExceptReturnType(tp)
6767 else
6868 // Otherwise, nullify everything
69- nullifyType(tp)
69+ nullifyType(tp, explicitlyNullable = hasNullableAnnot(sym) )
7070 }
7171
7272 private def hasNotNullAnnot (sym : Symbol )(using Context ): Boolean =
7373 ctx.definitions.NotNullAnnots .exists(nna => sym.unforcedAnnotation(nna).isDefined)
7474
75+ private def hasNullableAnnot (sym : Symbol )(using Context ): Boolean =
76+ ctx.definitions.NullableAnnots .exists(nna => sym.unforcedAnnotation(nna).isDefined)
77+
7578 /** If tp is a MethodType, the parameters and the inside of return type are nullified,
7679 * but the result return type is not nullable.
7780 * If tp is a type of a field, the inside of the type is nullified,
7881 * but the result type is not nullable.
7982 */
8083 private def nullifyExceptReturnType (tp : Type )(using Context ): Type =
81- new JavaNullMap (outermostLevelAlreadyNullable = true )(tp)
84+ new JavaNullMap (outermostLevelAlreadyNullable = true , explicitlyNullable = false )(tp)
8285
8386 /** Nullifies a Java type by adding `| Null` in the relevant places. */
84- private def nullifyType (tp : Type )(using Context ): Type =
85- new JavaNullMap (outermostLevelAlreadyNullable = false )(tp)
87+ private def nullifyType (tp : Type , explicitlyNullable : Boolean = false )(using Context ): Type =
88+ new JavaNullMap (outermostLevelAlreadyNullable = false , explicitlyNullable )(tp)
8689
8790 /** A type map that implements the nullification function on types. Given a Java-sourced type, this adds `| Null`
8891 * in the right places to make the nulls explicit in Scala.
@@ -95,8 +98,17 @@ object JavaNullInterop {
9598 * This is useful for e.g. constructors, and also so that `A & B` is nullified
9699 * to `(A & B) | Null`, instead of `(A | Null & B | Null) | Null`.
97100 */
98- private class JavaNullMap (var outermostLevelAlreadyNullable : Boolean )(using Context ) extends TypeMap {
99- def nullify (tp : Type ): Type = if ctx.flexibleTypes then FlexibleType (tp) else OrNull (tp)
101+ private class JavaNullMap (var outermostLevelAlreadyNullable : Boolean , explicitlyNullable : Boolean )(using Context ) extends TypeMap {
102+ def nullify (tp : Type ): Type =
103+ if ctx.flexibleTypes then {
104+ if explicitlyNullable then {
105+ OrNull (tp)
106+ } else {
107+ FlexibleType (tp)
108+ }
109+ } else {
110+ OrNull (tp)
111+ }
100112
101113 /** Should we nullify `tp` at the outermost level? */
102114 def needsNull (tp : Type ): Boolean =
0 commit comments