Introduce readonly variant of idx
[hiphop-php.git] / hphp / hack / src / typing / typing_special_fun.ml
blob3b71b08f385bb1442ed508081d625f440679c6ad
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 open Hh_prelude
11 open Typing_defs
12 module SN = Naming_special_names
13 module MakeType = Typing_make_type
15 let update_param : decl_fun_param -> decl_ty -> decl_fun_param =
16 (fun param ty -> { param with fp_type = { param.fp_type with et_type = ty } })
18 (** Transform the special function `idx` according to the number
19 of arguments actually passed to the function
21 The idx function has two signatures, depending on number of arguments
22 actually passed:
24 idx<Tk as arraykey, Tv>(?KeyedContainer<Tk, Tv> $collection, ?Tk $index): ?Tv
25 idx<Tk as arraykey, Tv>(?KeyedContainer<Tk, Tv> $collection, ?Tk $index, Tv $default): Tv
27 In the hhi file, it has signature
29 function idx<Tk as arraykey, Tv>
30 (?KeyedContainer<Tk, Tv> $collection, ?Tk $index, $default = null)
32 so this needs to be munged into the above. *)
33 let transform_idx_fun_ty : decl_fun_type -> int -> decl_fun_type =
34 fun fty nargs ->
35 let (param1, param2, param3) =
36 match fty.ft_params with
37 | [param1; param2; param3] -> (param1, param2, param3)
38 | _ -> failwith "Expected 3 parameters for idx in hhi file"
40 let rret = get_reason fty.ft_ret.et_type in
41 let (params, ret) =
42 match nargs with
43 | 2 ->
44 (* Return type should be ?Tv *)
45 let ret = MakeType.nullable_decl rret (MakeType.generic rret "Tv") in
46 ([param1; param2], ret)
47 | 3 ->
48 (* Third parameter should have type Tv *)
49 let param3 =
50 let r3 = get_reason param1.fp_type.et_type in
51 update_param param3 (MakeType.generic r3 "Tv")
53 (* Return type should be Tv *)
54 let ret = MakeType.generic rret "Tv" in
55 ([param1; param2; param3], ret)
56 (* Shouldn't happen! *)
57 | _ -> (fty.ft_params, fty.ft_ret.et_type)
59 { fty with ft_params = params; ft_ret = { fty.ft_ret with et_type = ret } }
61 (** Transform the types of special functions whose type is not denotable in hack, e.g. idx *)
62 let transform_special_fun_ty : decl_fun_type -> Aast.sid -> int -> decl_fun_type
64 fun fty id nargs ->
65 if String.equal (snd id) SN.FB.idx || String.equal (snd id) SN.Readonly.idx
66 then
67 transform_idx_fun_ty fty nargs
68 else
69 fty