@@ -79,14 +79,16 @@ let handle_tdcl light (tdcl : Parsetree.type_declaration) :
79
79
Ext_list. exists label_declarations (fun x ->
80
80
Ast_attributes. has_bs_optional x.pld_attributes)
81
81
in
82
- let setter_accessor, make_type , labels =
82
+ let setter_accessor, maker_args , labels =
83
83
Ext_list. fold_right label_declarations
84
84
( [] ,
85
85
(if has_optional_field then
86
- Ast_helper.Typ. arrow ~loc ~arity: None
87
- {attrs = [] ; lbl = Nolabel ; typ = Ast_literal. type_unit () }
88
- core_type
89
- else core_type),
86
+ (* start with the implicit unit argument *)
87
+ [
88
+ ({attrs = [] ; lbl = Nolabel ; typ = Ast_literal. type_unit () }
89
+ : Parsetree. arg);
90
+ ]
91
+ else [] ),
90
92
[] )
91
93
(fun ({
92
94
pld_name = {txt = label_name ; loc = label_loc } as pld_name ;
@@ -106,61 +108,81 @@ let handle_tdcl light (tdcl : Parsetree.type_declaration) :
106
108
let prim = [prim_as_name] in
107
109
let is_optional = Ast_attributes. has_bs_optional pld_attributes in
108
110
109
- let maker, acc =
110
- let arity =
111
- if List. length labels = List. length label_declarations - 1 then
112
- (* toplevel type *)
113
- Some ((if has_optional_field then 2 else 1 ) + List. length labels)
114
- else None
115
- in
111
+ (* build the argument representing this field *)
112
+ let field_arg =
113
+ if is_optional then
114
+ ({attrs = [] ; lbl = Asttypes. Optional pld_name; typ = pld_type}
115
+ : Parsetree. arg)
116
+ else
117
+ ({attrs = [] ; lbl = Asttypes. Labelled pld_name; typ = pld_type}
118
+ : Parsetree. arg)
119
+ in
120
+
121
+ (* prepend to the maker argument list *)
122
+ let maker_args = field_arg :: maker in
123
+
124
+ (* build accessor value description for this field *)
125
+ let accessor_type =
116
126
if is_optional then
117
127
let optional_type = Ast_core_type. lift_option_type pld_type in
118
- ( Ast_helper.Typ. arrow ~loc: pld_loc ~arity
119
- {attrs = [] ; lbl = Asttypes. Optional pld_name; typ = pld_type}
120
- maker,
121
- Val. mk ~loc: pld_loc
122
- (if light then pld_name
123
- else {pld_name with txt = pld_name.txt ^ " Get" })
124
- ~attrs: get_optional_attrs ~prim
125
- (Ast_helper.Typ. arrow ~loc ~arity: (Some 1 )
126
- {attrs = [] ; lbl = Nolabel ; typ = core_type}
127
- optional_type)
128
- :: acc )
128
+ Ast_helper.Typ. arrow ~loc ~arity: (Some 1 )
129
+ {attrs = [] ; lbl = Nolabel ; typ = core_type}
130
+ optional_type
129
131
else
130
- ( Ast_helper.Typ. arrow ~loc: pld_loc ~arity
131
- {attrs = [] ; lbl = Asttypes. Labelled pld_name; typ = pld_type}
132
- maker,
133
- Val. mk ~loc: pld_loc
134
- (if light then pld_name
135
- else {pld_name with txt = pld_name.txt ^ " Get" })
136
- ~attrs: get_attrs
137
- ~prim:
138
- ((* Not needed actually*)
139
- External_ffi_types. ffi_bs_as_prims
140
- [External_arg_spec. dummy] Return_identity
141
- (Js_get {js_get_name = prim_as_name; js_get_scopes = [] }))
142
- (Ast_helper.Typ. arrow ~loc ~arity: (Some 1 )
143
- {attrs = [] ; lbl = Nolabel ; typ = core_type}
144
- pld_type)
145
- :: acc )
132
+ Ast_helper.Typ. arrow ~loc ~arity: (Some 1 )
133
+ {attrs = [] ; lbl = Nolabel ; typ = core_type}
134
+ pld_type
135
+ in
136
+ let accessor_prim =
137
+ (* Not needed actually *)
138
+ if is_optional then prim
139
+ else
140
+ External_ffi_types. ffi_bs_as_prims [External_arg_spec. dummy]
141
+ Return_identity
142
+ (Js_get {js_get_name = prim_as_name; js_get_scopes = [] })
146
143
in
147
- let is_current_field_mutable = pld_mutable = Mutable in
144
+ let accessor_attrs =
145
+ if is_optional then get_optional_attrs else get_attrs
146
+ in
147
+
148
+ let accessor =
149
+ Val. mk ~loc: pld_loc
150
+ (if light then pld_name
151
+ else {pld_name with txt = pld_name.txt ^ " Get" })
152
+ ~attrs: accessor_attrs ~prim: accessor_prim accessor_type
153
+ in
154
+
155
+ (* accumulate *)
156
+ let acc = accessor :: acc in
157
+
158
+ (* add setter for mutable fields *)
148
159
let acc =
149
- if is_current_field_mutable then
160
+ if pld_mutable = Mutable then
150
161
let setter_type =
151
- Ast_helper.Typ. arrow ~arity: (Some 2 )
152
- {attrs = [] ; lbl = Nolabel ; typ = core_type}
153
- (Ast_helper.Typ. arrow ~arity: None
154
- {attrs = [] ; lbl = Nolabel ; typ = pld_type} (* setter *)
155
- (Ast_literal. type_unit () ))
162
+ Ast_helper.Typ. arrows ~loc: pld_loc
163
+ [
164
+ ({attrs = [] ; lbl = Nolabel ; typ = core_type}
165
+ : Parsetree. arg);
166
+ ({attrs = [] ; lbl = Nolabel ; typ = pld_type}
167
+ : Parsetree. arg);
168
+ ]
169
+ (Ast_literal. type_unit () )
170
+ in
171
+ let setter =
172
+ Val. mk ~loc: pld_loc
173
+ {loc = label_loc; txt = label_name ^ " Set" }
174
+ ~attrs: set_attrs ~prim setter_type
156
175
in
157
- Val. mk ~loc: pld_loc
158
- {loc = label_loc; txt = label_name ^ " Set" } (* setter *)
159
- ~attrs: set_attrs ~prim setter_type
160
- :: acc
176
+ setter :: acc
161
177
else acc
162
178
in
163
- (acc, maker, (is_optional, new_label) :: labels))
179
+ (acc, maker_args, (is_optional, new_label) :: labels))
180
+ in
181
+ (* build the final [make] function type from accumulated arguments *)
182
+ let make_type =
183
+ match maker_args with
184
+ | [] -> core_type
185
+ | args -> Ast_helper.Typ. arrows ~loc args core_type
164
186
in
165
187
( new_tdcl,
166
188
if is_private then setter_accessor
0 commit comments