From c4c8c053a137529f44a09b7d2f0da5367fa3eae7 Mon Sep 17 00:00:00 2001 From: Mitya Lyubarskiy Date: Wed, 15 Apr 2020 07:29:53 -0700 Subject: [PATCH] [nullsafe] Treat not annotated synthetic fields as StrictNonnull Reviewed By: artempyanykh Differential Revision: D21040264 fbshipit-source-id: 3557c5f60 --- infer/src/nullsafe/AnnotatedField.ml | 22 ++++++++++++++------- infer/src/nullsafe/AnnotatedNullability.ml | 3 +++ infer/src/nullsafe/AnnotatedNullability.mli | 3 +++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/infer/src/nullsafe/AnnotatedField.ml b/infer/src/nullsafe/AnnotatedField.ml index e8aed9794..de9a9099d 100644 --- a/infer/src/nullsafe/AnnotatedField.ml +++ b/infer/src/nullsafe/AnnotatedField.ml @@ -36,6 +36,8 @@ let is_enum_value tenv ~class_typ (field_info : Struct.field_info) = false +let is_synthetic field_name = String.contains field_name '$' + let get tenv field_name class_typ = let open IOption.Let_syntax in let lookup = Tenv.lookup tenv in @@ -59,13 +61,19 @@ let get tenv field_name class_typ = ~is_third_party field_typ annotations in let corrected_nullability = - if Nullability.is_nonnullish (AnnotatedNullability.get_nullability nullability) && is_enum_value - then - (* Enum values are the special case - they can not be null. So we can strengten nullability. - Note that if it is nullable, we do NOT change nullability: in this case this is probably - not an enum value, but just a static field annotated as nullable. - *) - AnnotatedNullability.StrictNonnull EnumValue + if Nullability.is_nonnullish (AnnotatedNullability.get_nullability nullability) then + if + is_enum_value + (* Enum values are the special case - they can not be null. So we can strengten nullability. + Note that if it is nullable, we do NOT change nullability: in this case this is probably + not an enum value, but just a static field annotated as nullable. + *) + then AnnotatedNullability.StrictNonnull EnumValue + else if is_synthetic (Fieldname.get_field_name field_name) then + (* This field is artifact of codegen and is not visible to the user. + Surfacing it as non-strict is non-actionable for the user *) + AnnotatedNullability.StrictNonnull SyntheticField + else nullability else nullability in let annotated_type = AnnotatedType.{nullability= corrected_nullability; typ= field_typ} in diff --git a/infer/src/nullsafe/AnnotatedNullability.ml b/infer/src/nullsafe/AnnotatedNullability.ml index dbb88622f..f51a50c32 100644 --- a/infer/src/nullsafe/AnnotatedNullability.ml +++ b/infer/src/nullsafe/AnnotatedNullability.ml @@ -39,6 +39,7 @@ and strict_nonnull_origin = | StrictMode | PrimitiveType | EnumValue + | SyntheticField [@@deriving compare] let get_nullability = function @@ -83,6 +84,8 @@ let pp fmt t = "primitive" | EnumValue -> "enum" + | SyntheticField -> + "synthetic_field" in match t with | Nullable origin -> diff --git a/infer/src/nullsafe/AnnotatedNullability.mli b/infer/src/nullsafe/AnnotatedNullability.mli index b5f42681a..fb95e9efe 100644 --- a/infer/src/nullsafe/AnnotatedNullability.mli +++ b/infer/src/nullsafe/AnnotatedNullability.mli @@ -61,6 +61,9 @@ and strict_nonnull_origin = | PrimitiveType (** Primitive types are non-nullable by language design *) | EnumValue (** Java enum value are statically initialized with non-nulls according to language semantics *) + | SyntheticField + (** Fake field that is not part of user codebase, but rather artifact of codegen/annotation + processor *) [@@deriving compare] val get_nullability : t -> Nullability.t