Transformation for parameter dependent contexts
[hiphop-php.git] / hphp / hack / src / decl / decl_hint.ml
blob457bac3289ea5445373cadcd31588ef0a7d9d263
1 (*
2 * Copyright (c) 2015, Facebook, Inc.
3 * All rights reserved.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
8 *)
10 (*****************************************************************************)
11 (* Converts a type hint into a type *)
12 (*****************************************************************************)
13 open Hh_prelude
14 open Aast
15 open Typing_defs
17 (* Unpacking a hint for typing *)
18 let rec hint env (p, h) =
19 let h = hint_ p env h in
20 mk (Typing_reason.Rhint p, h)
22 and shape_field_info_to_shape_field_type env { sfi_optional; sfi_hint; _ } =
23 { sft_optional = sfi_optional; sft_ty = hint env sfi_hint }
25 and aast_user_attribute_to_decl_user_attribute { ua_name; ua_params } =
27 Typing_defs.ua_name;
28 ua_classname_params =
29 List.filter_map ua_params ~f:(function
30 | (_, Class_const ((_, CI (_, cls)), (_, name)))
31 when String.equal name SN.Members.mClass ->
32 Some cls
33 | _ -> None);
36 and aast_contexts_to_decl_capability env ctxs default_pos =
37 match ctxs with
38 | Some (pos, hl) ->
39 let hl = List.map ~f:(hint env) hl in
40 CapTy (Typing_make_type.intersection (Reason.Rhint pos) hl)
41 | None -> CapDefaults default_pos
43 and aast_tparam_to_decl_tparam env t =
45 tp_variance = t.Aast.tp_variance;
46 tp_name = t.Aast.tp_name;
47 tp_tparams =
48 List.map ~f:(aast_tparam_to_decl_tparam env) t.Aast.tp_parameters;
49 tp_constraints =
50 List.map ~f:(Tuple.T2.map_snd ~f:(hint env)) t.Aast.tp_constraints;
51 tp_reified = t.Aast.tp_reified;
52 tp_user_attributes =
53 List.map
54 ~f:aast_user_attribute_to_decl_user_attribute
55 t.Aast.tp_user_attributes;
58 and hint_ p env = function
59 | Hany -> Typing_defs.make_tany ()
60 | Herr -> Terr
61 | Hmixed -> Tmixed
62 | Hnonnull -> Tnonnull
63 | Hthis -> Tthis
64 | Hdynamic -> Tdynamic
65 | Hnothing -> Tunion []
66 | Hdarray (h1, h2) -> Tdarray (hint env h1, hint env h2)
67 | Hvarray h -> Tvarray (hint env h)
68 | Hvarray_or_darray (h1, h2) ->
69 let t1 =
70 match h1 with
71 | Some h -> hint env h
72 | None -> mk (Typing_reason.Rvarray_or_darray_key p, Tprim Aast.Tarraykey)
74 Tvarray_or_darray (t1, hint env h2)
75 | Hprim p -> Tprim p
76 | Habstr (x, argl) ->
77 let argl = List.map argl (hint env) in
78 Tgeneric (x, argl)
79 | Hoption h ->
80 let h = hint env h in
81 Toption h
82 | Hlike h -> Tlike (hint env h)
83 | Hfun
85 hf_reactive_kind = reactivity;
86 hf_param_tys = hl;
87 hf_param_kinds = kl;
88 hf_param_mutability = muts;
89 hf_variadic_ty = vh;
90 hf_ctxs = ctxs;
91 hf_return_ty = h;
92 hf_is_mutable_return = mut_ret;
93 } ->
94 let make_param ((p, _) as x) k mut =
95 let mutability =
96 match mut with
97 | Some PMutable -> Some Param_borrowed_mutable
98 | Some POwnedMutable -> Some Param_owned_mutable
99 | Some PMaybeMutable -> Some Param_maybe_mutable
100 | _ -> None
103 fp_pos = p;
104 fp_name = None;
105 fp_type = possibly_enforced_hint env x;
106 fp_flags =
107 make_fp_flags
108 ~mode:(get_param_mode k)
109 ~accept_disposable:false
110 ~mutability
111 ~has_default:
112 false
113 (* Currently do not support external and cancall on parameters of function parameters *)
114 ~ifc_external:false
115 ~ifc_can_call:false
116 ~is_atom:false;
117 fp_rx_annotation = None;
120 let paraml = List.map3_exn hl kl muts ~f:make_param in
121 let implicit_params =
122 let capability = aast_contexts_to_decl_capability env ctxs p in
123 { capability }
125 let ret = possibly_enforced_hint env h in
126 let arity =
127 match vh with
128 | Some t -> Fvariadic (make_param t None None)
129 | None -> Fstandard
131 let reactivity =
132 match reactivity with
133 | FPure -> Pure None
134 | FReactive -> Reactive None
135 | FShallow -> Shallow None
136 | FLocal -> Local None
137 | FNonreactive -> Nonreactive
139 Tfun
141 ft_arity = arity;
142 ft_tparams = [];
143 ft_where_constraints = [];
144 ft_params = paraml;
145 ft_implicit_params = implicit_params;
146 ft_ret = ret;
147 ft_flags =
148 make_ft_flags
149 Ast_defs.FSync
150 None
151 ~return_disposable:false
152 ~returns_void_to_rx:false
153 ~returns_mutable:mut_ret;
154 ft_reactive = reactivity;
155 (* TODO: handle function parameters with <<CanCall>> *)
156 ft_ifc_decl = default_ifc_fun_decl;
158 | Happly (id, argl) ->
159 let argl = List.map argl (hint env) in
160 Tapply (id, argl)
161 | Haccess ((_, Hvar n), [(_, id)]) -> Tgeneric ("T" ^ n ^ "@" ^ id, [])
162 | Haccess (root_ty, ids) ->
163 let root_ty = hint_ p env (snd root_ty) in
164 let rec translate res ids =
165 match ids with
166 | [] -> res
167 | id :: ids ->
168 translate (Taccess (mk (Typing_reason.Rhint p, res), id)) ids
170 translate root_ty ids
171 | Htuple hl ->
172 let tyl = List.map hl (hint env) in
173 Ttuple tyl
174 | Hunion hl ->
175 let tyl = List.map hl (hint env) in
176 Tunion tyl
177 | Hintersection hl ->
178 let tyl = List.map hl (hint env) in
179 Tintersection tyl
180 | Hshape { nsi_allows_unknown_fields; nsi_field_map } ->
181 let shape_kind =
182 if nsi_allows_unknown_fields then
183 Open_shape
184 else
185 Closed_shape
187 let fdm =
188 List.fold_left
189 ~f:(fun acc i ->
190 ShapeMap.add
191 i.sfi_name
192 (shape_field_info_to_shape_field_type env i)
193 acc)
194 ~init:ShapeMap.empty
195 nsi_field_map
197 Tshape (shape_kind, fdm)
198 | Hsoft (p, h_) -> hint_ p env h_
199 | Hfun_context n -> Tgeneric ("Tctx" ^ n, [])
200 | Hvar n -> Tgeneric ("T" ^ n, [])
202 and possibly_enforced_hint env h =
203 (* Initially we assume that a type is not enforced at runtime.
204 * We refine this during localization
206 { et_enforced = false; et_type = hint env h }