[nullsafe] Add NullsafeType to `get_field_annotation`

Summary:
`get_field_annotation` is (together with
`get_modelled_annotated_signature`) an entry point when Nullsafe fetches
annotation information.

In follow up diffs we are going to utilize added information; see also
TODO in the code

Reviewed By: ngorogiannis

Differential Revision: D17475034

fbshipit-source-id: dab77bc7b
master
Mitya Lyubarskiy 6 years ago committed by Facebook Github Bot
parent ba0a0b6d9a
commit 518b154ebe

@ -9,9 +9,22 @@ open! IStd
(** Module for the checks called by Eradicate. *) (** Module for the checks called by Eradicate. *)
(* TODO(T54088319) get rid of annotation_deprecated:
- move all usages related to nullability to nullsafe_type
- introduce "field flags" and move all other usages to this dedicated datatype
*)
type field_type = {annotation_deprecated: Annot.Item.t; nullsafe_type: NullsafeType.t}
let get_field_annotation tenv fn typ = let get_field_annotation tenv fn typ =
let lookup = Tenv.lookup tenv in let lookup = Tenv.lookup tenv in
Typ.Struct.get_field_type_and_annotation ~lookup fn typ let type_and_annotation_to_field_type (typ, annotation) =
{ annotation_deprecated= annotation
; nullsafe_type=
NullsafeType.{nullability= NullsafeType.nullability_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 report_error tenv = TypeErr.report_error tenv (EradicateCheckers.report_error tenv)
@ -121,7 +134,7 @@ let check_nonzero tenv find_canonical_duplicate =
(** Check an assignment to a field. *) (** Check an assignment to a field. *)
let check_field_assignment tenv find_canonical_duplicate curr_pdesc node instr_ref typestate let check_field_assignment tenv find_canonical_duplicate curr_pdesc node instr_ref typestate
exp_lhs exp_rhs typ loc fname t_ia_opt typecheck_expr : unit = exp_lhs exp_rhs typ loc fname field_type_opt typecheck_expr : unit =
let curr_pname = Procdesc.get_proc_name curr_pdesc in let curr_pname = Procdesc.get_proc_name curr_pdesc in
let curr_pattrs = Procdesc.get_attributes curr_pdesc in let curr_pattrs = Procdesc.get_attributes curr_pdesc in
let t_lhs, ta_lhs, _ = let t_lhs, ta_lhs, _ =
@ -135,9 +148,9 @@ let check_field_assignment tenv find_canonical_duplicate curr_pdesc node instr_r
loc loc
in in
let field_is_injector_readwrite () = let field_is_injector_readwrite () =
match t_ia_opt with match field_type_opt with
| Some (_, ia) -> | Some {annotation_deprecated} ->
Annotations.ia_is_field_injector_readwrite ia Annotations.ia_is_field_injector_readwrite annotation_deprecated
| _ -> | _ ->
false false
in in
@ -171,7 +184,11 @@ let check_constructor_initialization tenv find_canonical_duplicate curr_pname cu
| Some {fields} -> | Some {fields} ->
let do_field (fn, ft, _) = let do_field (fn, ft, _) =
let annotated_with f = let annotated_with f =
match get_field_annotation tenv fn ts with None -> false | Some (_, ia) -> f ia match get_field_annotation tenv fn ts with
| None ->
false
| Some {annotation_deprecated} ->
f annotation_deprecated
in in
let nullable_annotated = annotated_with Annotations.ia_is_nullable in let nullable_annotated = annotated_with Annotations.ia_is_nullable in
let injector_readonly_annotated = let injector_readonly_annotated =

@ -146,9 +146,10 @@ let rec typecheck_expr find_canonical_duplicate visited checks tenv node instr_r
let exp_origin = TypeAnnotation.get_origin ta in let exp_origin = TypeAnnotation.get_origin ta in
let tr_new = let tr_new =
match EradicateChecks.get_field_annotation tenv fn typ with match EradicateChecks.get_field_annotation tenv fn typ with
| Some (t, ia) -> | Some EradicateChecks.{nullsafe_type; annotation_deprecated} ->
( t ( nullsafe_type.typ
, TypeAnnotation.from_item_annotation ia (TypeOrigin.Field (exp_origin, fn, loc)) , TypeAnnotation.from_item_annotation annotation_deprecated
(TypeOrigin.Field (exp_origin, fn, loc))
, locs' ) , locs' )
| None -> | None ->
tr_default tr_default
@ -225,10 +226,11 @@ let typecheck_instr tenv calls_this checks (node : Procdesc.Node.t) idenv curr_p
typestate typestate
| _ -> ( | _ -> (
match EradicateChecks.get_field_annotation tenv fn typ with match EradicateChecks.get_field_annotation tenv fn typ with
| Some (t, ia) -> | Some EradicateChecks.{nullsafe_type; annotation_deprecated} ->
let range = let range =
( t ( nullsafe_type.typ
, TypeAnnotation.from_item_annotation ia (TypeOrigin.Field (origin, fn, loc)) , TypeAnnotation.from_item_annotation annotation_deprecated
(TypeOrigin.Field (origin, fn, loc))
, [loc] ) , [loc] )
in in
TypeState.add pvar range typestate TypeState.add pvar range typestate
@ -434,10 +436,10 @@ let typecheck_instr tenv calls_this checks (node : Procdesc.Node.t) idenv curr_p
let check_field_assign () = let check_field_assign () =
match e1 with match e1 with
| Exp.Lfield (_, fn, f_typ) -> | Exp.Lfield (_, fn, f_typ) ->
let t_ia_opt = EradicateChecks.get_field_annotation tenv fn f_typ in let field_type_opt = EradicateChecks.get_field_annotation tenv fn f_typ in
if checks.eradicate then if checks.eradicate then
EradicateChecks.check_field_assignment tenv find_canonical_duplicate curr_pdesc node EradicateChecks.check_field_assignment tenv find_canonical_duplicate curr_pdesc node
instr_ref typestate1 e1' e2 typ loc fn t_ia_opt instr_ref typestate1 e1' e2 typ loc fn field_type_opt
(typecheck_expr find_canonical_duplicate calls_this checks tenv) (typecheck_expr find_canonical_duplicate calls_this checks tenv)
| _ -> | _ ->
() ()

Loading…
Cancel
Save