@@ -86,7 +86,7 @@ let curry_type_id () =
86
86
87
87
let ignore_id = Longident. Ldot (Lident " Pervasives" , " ignore" )
88
88
89
-
89
+ let arrow = Ast_helper.Typ. arrow
90
90
91
91
(* note we first declare its type is [unit],
92
92
then [ignore] it, [ignore] is necessary since
@@ -150,6 +150,8 @@ let create_local_external loc
150
150
pexp_loc = loc
151
151
})
152
152
153
+ let record_as_js_object = ref None (* otherwise has an attribute *)
154
+ let obj_type_as_js_obj_type = ref false
153
155
let handle_record_as_js_object
154
156
loc
155
157
attr
@@ -166,11 +168,6 @@ let handle_record_as_js_object
166
168
let pval_attributes = [attr] in
167
169
let local_module_name = " Tmp" in
168
170
let local_fun_name = " run" in
169
- let arrow label a b =
170
- {Parsetree. ptyp_desc = Ptyp_arrow (label, a, b);
171
- ptyp_attributes = [] ;
172
- ptyp_loc = loc} in
173
-
174
171
let pval_type =
175
172
let arity = List. length labels in
176
173
let tyvars = (Ext_list. init arity (fun i ->
@@ -190,7 +187,7 @@ let handle_record_as_js_object
190
187
ptyp_attributes = []
191
188
} in
192
189
List. fold_right2
193
- (fun label tyvar acc -> arrow label tyvar acc) labels tyvars result_type
190
+ (fun label tyvar acc -> arrow ~loc label tyvar acc) labels tyvars result_type
194
191
in
195
192
create_local_external loc
196
193
~pval_prim
@@ -225,14 +222,9 @@ let gen_fn_run loc arity args : Parsetree.expression_desc =
225
222
ptyp_loc = loc }]);
226
223
ptyp_attributes;
227
224
ptyp_loc = loc} in
228
- let arrow a b =
229
- {ptyp_desc =
230
- Ptyp_arrow (" " , a, b);
231
- ptyp_attributes ;
232
- ptyp_loc = loc} in
233
225
(* * could be optimized *)
234
226
let pval_type =
235
- Ext_list. reduce_from_right arrow (uncurry_fn :: tyvars) in
227
+ Ext_list. reduce_from_right ( fun a b -> arrow ~loc " " a b) (uncurry_fn :: tyvars) in
236
228
create_local_external loc ~pval_prim ~pval_type ~pval_attributes: []
237
229
local_module_name local_fun_name args
238
230
@@ -262,15 +254,11 @@ let gen_fn_mk loc arity args : Parsetree.expression_desc =
262
254
ptyp_loc = loc }]);
263
255
ptyp_attributes;
264
256
ptyp_loc = loc} in
265
- let arrow a b =
266
- {ptyp_desc =
267
- Ptyp_arrow (" " , a, b);
268
- ptyp_attributes ;
269
- ptyp_loc = loc} in
257
+ let arrow = arrow ~loc " " in
270
258
(* * could be optimized *)
271
259
let pval_type =
272
260
if arity = 0 then
273
- arrow (arrow predef_unit_type (List. hd tyvars) ) uncurry_fn
261
+ arrow (arrow predef_unit_type (List. hd tyvars) ) uncurry_fn
274
262
else
275
263
arrow (Ext_list. reduce_from_right arrow tyvars) uncurry_fn in
276
264
create_local_external loc ~pval_prim ~pval_type ~pval_attributes: []
@@ -280,16 +268,13 @@ let gen_fn_mk loc arity args : Parsetree.expression_desc =
280
268
281
269
282
270
let handle_raw loc e =
283
- Ast_helper.Exp. letmodule
284
- {txt = tmp_module_name; loc }
285
- (Ast_helper.Mod. structure [
286
- Ast_helper.Str. primitive
287
- (Ast_helper.Val. mk {loc ; txt = tmp_fn}
288
- ~prim: [prim]
289
- (Ast_helper.Typ. arrow " " predef_string_type predef_any_type))])
290
- (Ast_helper.Exp. apply
291
- (Ast_helper.Exp. ident {txt= Ldot (Lident tmp_module_name, tmp_fn) ; loc})
292
- [(" " ,e)])
271
+ create_local_external loc
272
+ ~pval_prim: prim
273
+ ~pval_type: (arrow " " predef_string_type predef_any_type)
274
+ ~pval_attributes: []
275
+ tmp_module_name
276
+ tmp_fn
277
+ [(" " ,e)]
293
278
294
279
295
280
@@ -369,25 +354,48 @@ let handle_typ
369
354
ptyp_attributes ;
370
355
ptyp_loc = loc
371
356
} ->
372
- let methods = List. map (fun (label , ptyp_attrs , core_type ) ->
373
- match find_uncurry_attrs_and_remove ptyp_attrs with
374
- | None , _ -> label, ptyp_attrs , self.typ self core_type
375
- | Some v , ptyp_attrs ->
376
- label , ptyp_attrs, self.typ self
377
- { core_type with ptyp_attributes = v :: core_type .ptyp_attributes}
378
- ) methods in
379
357
begin match Ext_list. exclude_with_fact (function
380
358
| {Location. txt = "bs.obj" ; _} , _ -> true
381
359
| _ -> false ) ptyp_attributes with
382
- | None , _ ->
383
- {ty with ptyp_desc = Ptyp_object (methods, closed_flag)}
384
360
| Some _ , ptyp_attributes ->
361
+ let methods =
362
+ Ext_ref. protect obj_type_as_js_obj_type true begin fun _ ->
363
+ List. map (fun (label , ptyp_attrs , core_type ) ->
364
+ match find_uncurry_attrs_and_remove ptyp_attrs with
365
+ | None , _ -> label, ptyp_attrs , self.typ self core_type
366
+ | Some v , ptyp_attrs ->
367
+ label , ptyp_attrs, self.typ self
368
+ { core_type with ptyp_attributes = v :: core_type .ptyp_attributes}
369
+ ) methods
370
+ end
371
+ in
372
+
385
373
{ptyp_desc =
386
374
Ptyp_constr ({ txt = js_obj_type_id () ; loc},
387
375
[{ ty with ptyp_desc = Ptyp_object (methods, closed_flag);
388
376
ptyp_attributes }]);
389
377
ptyp_attributes = [] ;
390
378
ptyp_loc = loc }
379
+ | None , _ ->
380
+ let methods =
381
+ List. map (fun (label , ptyp_attrs , core_type ) ->
382
+ match find_uncurry_attrs_and_remove ptyp_attrs with
383
+ | None , _ -> label, ptyp_attrs , self.typ self core_type
384
+ | Some v , ptyp_attrs ->
385
+ label , ptyp_attrs, self.typ self
386
+ { core_type with ptyp_attributes = v :: core_type .ptyp_attributes}
387
+ ) methods
388
+ in
389
+ if ! obj_type_as_js_obj_type then
390
+ {ptyp_desc =
391
+ Ptyp_constr ({ txt = js_obj_type_id () ; loc},
392
+ [{ ty with ptyp_desc = Ptyp_object (methods, closed_flag);
393
+ ptyp_attributes }]);
394
+ ptyp_attributes = [] ;
395
+ ptyp_loc = loc }
396
+ else
397
+ {ty with ptyp_desc = Ptyp_object (methods, closed_flag)}
398
+
391
399
end
392
400
| _ -> super.typ self ty
393
401
@@ -413,18 +421,13 @@ let handle_debugger loc payload =
413
421
match payload with
414
422
| Parsetree. PStr ( [] )
415
423
->
416
- Ast_helper.Exp. letmodule
417
- {txt = tmp_module_name; loc }
418
- (Ast_helper.Mod. structure [
419
- Ast_helper.Str. primitive
420
- (Ast_helper.Val. mk {loc ; txt = tmp_fn}
421
- ~prim: [prim_debugger]
422
- (Ast_helper.Typ. arrow " " predef_unit_type predef_unit_type)
423
- )])
424
- (Ast_helper.Exp. apply
425
- (Ast_helper.Exp. ident
426
- {txt= Ldot (Lident tmp_module_name, tmp_fn) ; loc})
427
- [(" " , predef_val_unit)])
424
+ create_local_external loc
425
+ ~pval_prim: prim_debugger
426
+ ~pval_type: (arrow " " predef_unit_type predef_unit_type)
427
+ ~pval_attributes: []
428
+ tmp_module_name
429
+ tmp_fn
430
+ [(" " , predef_val_unit)]
428
431
| Parsetree. PTyp _
429
432
| Parsetree. PPat (_,_)
430
433
| Parsetree. PStr _
@@ -644,7 +647,7 @@ let rec unsafe_mapper : Ast_mapper.mapper =
644
647
} as e ,
645
648
_); pstr_loc = _ }]))
646
649
->
647
- handle_raw loc e
650
+ {e with pexp_desc = handle_raw loc e }
648
651
| Pexp_extension ({txt = " bs.raw" ; loc}, (PTyp _ | PPat _ | PStr _))
649
652
->
650
653
Location. raise_errorf ~loc " bs.raw can only be applied to a string"
@@ -653,7 +656,7 @@ let rec unsafe_mapper : Ast_mapper.mapper =
653
656
654
657
(* * Begin rewriting [bs.debugger], its output should not be rewritten any more*)
655
658
| Pexp_extension ({txt = " bs.debugger" ; loc} , payload)
656
- -> handle_debugger loc payload
659
+ -> {e with pexp_desc = handle_debugger loc payload}
657
660
(* * End rewriting *)
658
661
| Pexp_fun (" " , None , pat , body)
659
662
->
@@ -730,12 +733,22 @@ let rec unsafe_mapper : Ast_mapper.mapper =
730
733
e.pexp_attributes
731
734
with
732
735
| Some attr , pexp_attributes ->
733
- { e with
734
- pexp_desc = handle_record_as_js_object e.pexp_loc attr label_exprs mapper;
735
- pexp_attributes
736
- }
736
+ Ext_ref. protect record_as_js_object (Some attr) begin fun () ->
737
+ { e with
738
+ pexp_desc = handle_record_as_js_object e.pexp_loc attr label_exprs mapper;
739
+ pexp_attributes
740
+ }
741
+ end
737
742
| None , _ ->
738
- Ast_mapper. default_mapper.expr mapper e
743
+ begin match ! record_as_js_object with
744
+ | Some attr
745
+ ->
746
+ { e with
747
+ pexp_desc = handle_record_as_js_object e.pexp_loc attr label_exprs mapper;
748
+ }
749
+ | None ->
750
+ Ast_mapper. default_mapper.expr mapper e
751
+ end
739
752
end
740
753
| _ -> Ast_mapper. default_mapper.expr mapper e
741
754
);
@@ -751,19 +764,16 @@ let rec unsafe_mapper : Ast_mapper.mapper =
751
764
pexp_desc = Pexp_constant (Const_string (cont, opt_label)) ;
752
765
pexp_loc; pexp_attributes } as e ,_); pstr_loc }])
753
766
->
754
- Ast_helper.Str. eval @@
755
- Ast_helper.Exp. letmodule
756
- {txt = tmp_module_name; loc }
757
- (Ast_helper.Mod. structure [
758
- Ast_helper.Str. primitive
759
- (Ast_helper.Val. mk {loc ; txt = tmp_fn}
760
- ~prim: [prim_stmt]
761
- (Ast_helper.Typ. arrow " "
762
- predef_string_type predef_any_type))])
763
- (Ast_helper.Exp. apply
764
- (Ast_helper.Exp. ident
765
- {txt= Ldot (Lident tmp_module_name, tmp_fn) ; loc})
766
- [(" " ,e)])
767
+ Ast_helper.Str. eval
768
+ { e with pexp_desc =
769
+ create_local_external loc
770
+ ~pval_prim: prim_stmt
771
+ ~pval_type: (arrow " "
772
+ predef_string_type predef_any_type)
773
+ ~pval_attributes: []
774
+ tmp_module_name
775
+ tmp_fn
776
+ [(" " ,e)]}
767
777
| Parsetree. PTyp _
768
778
| Parsetree. PPat (_,_)
769
779
| Parsetree. PStr _
0 commit comments