Source file ast_uncurry_gen.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
open Import
open Ast_helper
let to_method_callback loc (self : Ast_traverse.map) label pat body :
expression_desc =
Error.optional_err ~loc label;
let rec aux acc (body : expression) =
match Ast_attributes.process_attributes_rev body.pexp_attributes with
| Nothing, _ -> (
match body.pexp_desc with
| Pexp_fun (arg_label, _, arg, body) ->
Error.optional_err ~loc arg_label;
aux ((arg_label, self#pattern arg) :: acc) body
| _ -> (self#expression body, acc))
| _, _ -> (self#expression body, acc)
in
let first_arg = self#pattern pat in
if not (Ast_pat.is_single_variable_pattern_conservative first_arg) then
Error.err ~loc:first_arg.ppat_loc Mel_this_simple_pattern;
let result, = aux [ (label, first_arg) ] body in
let body =
List.fold_left
~f:(fun e (label, p) -> Ast_helper.Exp.fun_ ~loc label None p e)
~init:result rev_extra_args
in
let arity = List.length rev_extra_args in
let arity_s = string_of_int arity in
Pexp_apply
( Exp.ident ~loc { loc; txt = Ast_literal.unsafe_to_method },
[
( Nolabel,
Exp.constraint_ ~loc
(Exp.record ~loc
[ ({ loc; txt = Ast_literal.hidden_field arity_s }, body) ]
None)
(Typ.constr ~loc
{
loc;
txt = Ldot (Ast_literal.js_meth_callback, "arity" ^ arity_s);
}
[ Typ.any ~loc () ]) );
] )
let to_uncurry_fn loc (self : Ast_traverse.map) (label : Asttypes.arg_label) pat
body : expression_desc =
Error.optional_err ~loc label;
let rec aux acc (body : expression) =
match Ast_attributes.process_attributes_rev body.pexp_attributes with
| Nothing, _ -> (
match body.pexp_desc with
| Pexp_fun (arg_label, _, arg, body) ->
Error.optional_err ~loc arg_label;
aux ((arg_label, self#pattern arg) :: acc) body
| _ -> (self#expression body, acc))
| _, _ -> (self#expression body, acc)
in
let first_arg = self#pattern pat in
let result, = aux [ (label, first_arg) ] body in
let body =
List.fold_left
~f:(fun e (label, p) -> Ast_helper.Exp.fun_ ~loc label None p e)
~init:result rev_extra_args
in
let len = List.length rev_extra_args in
let arity =
match rev_extra_args with
| [ (_, p) ] -> Ast_pat.is_unit_cont ~yes:0 ~no:len p
| _ -> len
in
Error.err_large_arity ~loc arity;
let arity_s = string_of_int arity in
Pexp_record
([ ({ txt = Ldot (Ast_literal.js_fn, "I" ^ arity_s); loc }, body) ], None)