2 * Copyright (c) 2017, Facebook, Inc.
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the "hack" directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
11 open Instruction_sequence
15 let find_first_redeclaration pick_name_span l
=
20 match pick_name_span x
with
21 | Some
(name
, span
) ->
22 begin match SMap.get name seen
with
23 | None
-> aux (SMap.add name span seen
) xs
24 | Some original
-> Some
(name
, original
, span
)
26 | None
-> aux seen xs
in
29 (* Given a function definition, emit code, and in the case of <<__Memoize>>,
32 let emit_function : A.fun_
* bool -> Hhas_function.t list
=
33 fun (ast_fun
, is_top
) ->
34 let namespace = ast_fun
.A.f_namespace
in
36 Hhbc_id.Function.elaborate_id
namespace ast_fun
.A.f_name
in
37 let function_is_async =
38 ast_fun
.Ast.f_fun_kind
= Ast_defs.FAsync
39 || ast_fun
.Ast.f_fun_kind
= Ast_defs.FAsyncGenerator
in
40 let function_attributes =
41 Emit_attribute.from_asts
namespace ast_fun
.Ast.f_user_attributes
in
42 let is_memoize = Hhas_attribute.is_memoized
function_attributes in
43 let deprecation_info = Hhas_attribute.deprecation_info function_attributes in
44 let inout_param_locations = List.filter_mapi ast_fun
.Ast.f_params
45 ~f
:(fun i p
-> if p
.Ast.param_callconv
<> Some
Ast.Pinout
46 then None
else Some
(string_of_int i
)) in
47 let has_inout_args = List.length
inout_param_locations <> 0 in
50 then Hhbc_id.Function.add_suffix
51 original_id Emit_memoize_helpers.memoize_suffix
52 else if has_inout_args
53 then Hhbc_id.Function.add_suffix
54 original_id (Emit_inout_helpers.inout_suffix
inout_param_locations)
56 let scope = [Ast_scope.ScopeItem.Function ast_fun
] in
57 let function_body, function_is_generator
, function_is_pair_generator
=
59 ~pos
: ast_fun
.A.f_span
61 ~is_closure_body
:false
63 ~is_async
:function_is_async
64 ~
deprecation_info:(if is_memoize then None
else deprecation_info)
65 ~skipawaitable
:(ast_fun
.Ast.f_fun_kind
= Ast_defs.FAsync
)
66 ~is_return_by_ref
:ast_fun
.Ast.f_ret_by_ref
67 ~default_dropthrough
:None
68 ~return_value
:instr_null
70 ~doc_comment
:ast_fun
.Ast.f_doc_comment
73 [Ast.Stmt
(Ast.Block ast_fun
.Ast.f_body
)] in
79 (Hhas_pos.pos_to_span ast_fun
.Ast.f_span
)
82 function_is_pair_generator
84 false (*no_injection*)
85 false (*inout_wrapper*)
88 then [normal_function;
89 Emit_memoize_function.emit_wrapper_function
95 else if has_inout_args
96 then [Emit_inout_function.emit_wrapper_function
99 ~verify_ret
:(ast_fun
.Ast.f_ret
<> None
)
102 else [normal_function]
104 let emit_functions_from_program ast
=
105 List.concat_map
(List.sort
(fun (t1
, _
) (t2
, _
) -> compare t1 t2
) ast
)
107 match d
with Ast.Fun fd
-> emit_function (fd
, is_top
) | _
-> [])