diff --git a/infer/src/nullsafe/AnnotatedField.ml b/infer/src/nullsafe/AnnotatedField.ml new file mode 100644 index 000000000..214824d43 --- /dev/null +++ b/infer/src/nullsafe/AnnotatedField.ml @@ -0,0 +1,24 @@ +(* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) + +open! IStd + +(* TODO(T54088319) get rid of annotation_deprecated: + Introduce "field flags" and move all other usages to this dedicated datatype + *) +type t = {annotation_deprecated: Annot.Item.t; annotated_type: AnnotatedType.t} + +let get tenv fn typ = + let lookup = Tenv.lookup tenv in + let type_and_annotation_to_field_type (typ, annotation) = + { annotation_deprecated= annotation + ; annotated_type= + AnnotatedType.{nullability= AnnotatedNullability.of_annot_item annotation; typ} } + in + Option.map + (Typ.Struct.get_field_type_and_annotation ~lookup fn typ) + ~f:type_and_annotation_to_field_type diff --git a/infer/src/nullsafe/AnnotatedField.mli b/infer/src/nullsafe/AnnotatedField.mli new file mode 100644 index 000000000..327876413 --- /dev/null +++ b/infer/src/nullsafe/AnnotatedField.mli @@ -0,0 +1,15 @@ +(* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) + +open! IStd + +(** Representation of a declared class field with nullsafe-specific data *) + +type t = {annotation_deprecated: Annot.Item.t; annotated_type: AnnotatedType.t} + +val get : Tenv.t -> Typ.Fieldname.t -> Typ.t -> t option +(** Looks up for a field declaration and, in case of success, converts it to {t} *) diff --git a/infer/src/nullsafe/eradicateChecks.ml b/infer/src/nullsafe/eradicateChecks.ml index 3535ebb63..c2491903d 100644 --- a/infer/src/nullsafe/eradicateChecks.ml +++ b/infer/src/nullsafe/eradicateChecks.ml @@ -9,23 +9,6 @@ open! IStd (** Module for the checks called by Eradicate. *) -(* TODO(T54088319) get rid of annotation_deprecated: - - introduce "field flags" and move all other usages to this dedicated datatype - *) -type field_type = {annotation_deprecated: Annot.Item.t; annotated_type: AnnotatedType.t} - -let get_field_annotation tenv fn typ = - let lookup = Tenv.lookup tenv in - let type_and_annotation_to_field_type (typ, annotation) = - { annotation_deprecated= annotation - ; annotated_type= - AnnotatedType.{nullability= AnnotatedNullability.of_annot_item annotation; typ} } - in - Option.map - (Typ.Struct.get_field_type_and_annotation ~lookup fn typ) - ~f:type_and_annotation_to_field_type - - let report_error tenv = TypeErr.report_error tenv (EradicateCheckers.report_error tenv) let explain_expr tenv node e = @@ -138,7 +121,7 @@ let check_nonzero tenv find_canonical_duplicate = (** Check an assignment to a field. *) let check_field_assignment tenv find_canonical_duplicate curr_pdesc node instr_ref typestate - exp_lhs exp_rhs typ loc fname field_type_opt typecheck_expr : unit = + exp_lhs exp_rhs typ loc fname annotated_field_opt typecheck_expr : unit = let curr_pname = Procdesc.get_proc_name curr_pdesc in let curr_pattrs = Procdesc.get_attributes curr_pdesc in let t_lhs, inferred_nullability_lhs, _ = @@ -152,8 +135,8 @@ let check_field_assignment tenv find_canonical_duplicate curr_pdesc node instr_r loc in let field_is_injector_readwrite () = - match field_type_opt with - | Some {annotation_deprecated} -> + match annotated_field_opt with + | Some AnnotatedField.{annotation_deprecated} -> Annotations.ia_is_field_injector_readwrite annotation_deprecated | _ -> false @@ -181,7 +164,7 @@ let check_field_assignment tenv find_canonical_duplicate curr_pdesc node instr_r (Some instr_ref) loc curr_pdesc -let is_nullable {annotated_type} = +let is_nullable AnnotatedField.{annotated_type} = match annotated_type.nullability with | AnnotatedNullability.Nullable _ -> true @@ -189,7 +172,7 @@ let is_nullable {annotated_type} = false -let is_nonnull {annotated_type} = +let is_nonnull AnnotatedField.{annotated_type} = match annotated_type.nullability with | AnnotatedNullability.Nullable _ -> false @@ -223,7 +206,7 @@ let check_constructor_initialization tenv find_canonical_duplicate curr_pname cu match Tenv.lookup tenv name with | Some {fields} -> let do_field (fn, ft, _) = - let annotated_field = get_field_annotation tenv fn ts in + let annotated_field = AnnotatedField.get tenv fn ts in let is_injector_readonly_annotated = match annotated_field with | None -> diff --git a/infer/src/nullsafe/typeCheck.ml b/infer/src/nullsafe/typeCheck.ml index 56f20a625..0be3ca063 100644 --- a/infer/src/nullsafe/typeCheck.ml +++ b/infer/src/nullsafe/typeCheck.ml @@ -145,8 +145,8 @@ let rec typecheck_expr find_canonical_duplicate visited checks tenv node instr_r in let exp_origin = InferredNullability.get_origin inferred_nullability in let tr_new = - match EradicateChecks.get_field_annotation tenv fn typ with - | Some EradicateChecks.{annotated_type} -> + match AnnotatedField.get tenv fn typ with + | Some AnnotatedField.{annotated_type} -> ( annotated_type.typ , InferredNullability.of_annotated_nullability annotated_type.nullability (TypeOrigin.Field (exp_origin, fn, loc)) @@ -225,8 +225,8 @@ let typecheck_instr tenv calls_this checks (node : Procdesc.Node.t) idenv curr_p | Some _ when not is_assignment -> typestate | _ -> ( - match EradicateChecks.get_field_annotation tenv fn typ with - | Some EradicateChecks.{annotated_type} -> + match AnnotatedField.get tenv fn typ with + | Some AnnotatedField.{annotated_type} -> let range = ( annotated_type.typ , InferredNullability.of_annotated_nullability annotated_type.nullability @@ -438,7 +438,7 @@ let typecheck_instr tenv calls_this checks (node : Procdesc.Node.t) idenv curr_p let check_field_assign () = match e1 with | Exp.Lfield (_, fn, f_typ) -> - let field_type_opt = EradicateChecks.get_field_annotation tenv fn f_typ in + let field_type_opt = AnnotatedField.get tenv fn f_typ in if checks.eradicate then EradicateChecks.check_field_assignment tenv find_canonical_duplicate curr_pdesc node instr_ref typestate1 e1' e2 typ loc fn field_type_opt