Skip to content

Commit 72bf1fa

Browse files
author
Hongbo Zhang
committed
[feature] address #414
1 parent 6144a88 commit 72bf1fa

File tree

6 files changed

+93
-20
lines changed

6 files changed

+93
-20
lines changed

jscomp/ppx_entry.ml

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ let create_local_external loc
150150
pexp_loc = loc
151151
})
152152

153+
let record_as_js_object = ref None (* otherwise has an attribute *)
154+
let obj_type_as_js_obj_type = ref false
153155
let handle_record_as_js_object
154156
loc
155157
attr
@@ -352,25 +354,48 @@ let handle_typ
352354
ptyp_attributes ;
353355
ptyp_loc = loc
354356
} ->
355-
let methods = List.map (fun (label, ptyp_attrs, core_type ) ->
356-
match find_uncurry_attrs_and_remove ptyp_attrs with
357-
| None, _ -> label, ptyp_attrs , self.typ self core_type
358-
| Some v, ptyp_attrs ->
359-
label , ptyp_attrs, self.typ self
360-
{ core_type with ptyp_attributes = v :: core_type.ptyp_attributes}
361-
) methods in
362357
begin match Ext_list.exclude_with_fact (function
363358
| {Location.txt = "bs.obj" ; _}, _ -> true
364359
| _ -> false ) ptyp_attributes with
365-
| None, _ ->
366-
{ty with ptyp_desc = Ptyp_object (methods, closed_flag)}
367360
| 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+
368373
{ptyp_desc =
369374
Ptyp_constr ({ txt = js_obj_type_id () ; loc},
370375
[{ ty with ptyp_desc = Ptyp_object(methods, closed_flag);
371376
ptyp_attributes }]);
372377
ptyp_attributes = [];
373378
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+
374399
end
375400
| _ -> super.typ self ty
376401

@@ -708,12 +733,22 @@ let rec unsafe_mapper : Ast_mapper.mapper =
708733
e.pexp_attributes
709734
with
710735
| Some attr, pexp_attributes ->
711-
{ e with
712-
pexp_desc = handle_record_as_js_object e.pexp_loc attr label_exprs mapper;
713-
pexp_attributes
714-
}
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
715742
| None , _ ->
716-
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
717752
end
718753
| _ -> Ast_mapper.default_mapper.expr mapper e
719754
);

jscomp/test/.depend

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,8 @@ mt.cmj : ../stdlib/list.cmi mt.cmi
333333
mt.cmx : ../stdlib/list.cmx mt.cmi
334334
mt_global.cmj : mt.cmi mt_global.cmi
335335
mt_global.cmx : mt.cmx mt_global.cmi
336+
nested_obj_test.cmj :
337+
nested_obj_test.cmx :
336338
number_lexer.cmj : ../stdlib/sys.cmi ../stdlib/lexing.cmi
337339
number_lexer.cmx : ../stdlib/sys.cmx ../stdlib/lexing.cmx
338340
obj_literal_ppx.cmj : ../stdlib/array.cmi
@@ -987,6 +989,8 @@ mt.cmo : ../stdlib/list.cmi mt.cmi
987989
mt.cmj : ../stdlib/list.cmj mt.cmi
988990
mt_global.cmo : mt.cmi mt_global.cmi
989991
mt_global.cmj : mt.cmj mt_global.cmi
992+
nested_obj_test.cmo :
993+
nested_obj_test.cmj :
990994
number_lexer.cmo : ../stdlib/sys.cmi ../stdlib/lexing.cmi
991995
number_lexer.cmj : ../stdlib/sys.cmj ../stdlib/lexing.cmj
992996
obj_literal_ppx.cmo : ../stdlib/array.cmi

jscomp/test/demo.ml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ class type grid =
8484
object [@uncurry]
8585
inherit widget
8686
inherit measure
87-
method columns__set : <width : int; .. > Js.t array -> unit
87+
method columns__set : (<width : int; .. > [@bs.obj]) array -> unit
8888
method titleRows__set :
89-
<label : <text : string; .. > Js.t ; ..> Js.t array -> unit
89+
(<label : <text : string; .. > ; ..> [@bs.obj]) array -> unit
9090
method dataSource__set :
91-
<label : <text : string; .. > Js.t ; ..> Js.t array array -> unit
91+
(<label : <text : string; .. > ; ..> [@bs.obj]) array array -> unit
9292
end
9393

9494
external set_interval : (unit -> unit [@uncurry]) -> float -> unit = "setInterval"
@@ -186,8 +186,10 @@ let ui_layout
186186
stackPanel##addChild grid;
187187
stackPanel##addChild inputCode;
188188
stackPanel##addChild button;
189-
190-
let mk_titleRow text = {label = {text } [@bs.obj] }[@bs.obj] in
189+
(* {label = {text } [@bs.obj] }[@bs.obj]
190+
should also work
191+
*)
192+
let mk_titleRow text = {label = {text } }[@bs.obj] in
191193
let u = {width = 200} [@bs.obj] in
192194
grid##minHeight__set 300;
193195
grid##titleRows__set

jscomp/test/nested_obj_test.ml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
3+
type f_obj = < x : < y : < z : int > > > [@bs.obj]
4+
let f : f_obj = { x = { y = { z = 3 }}} [@bs.obj]
5+
6+
type 'a x = {x : 'a }
7+
type 'a y = {y : 'a}
8+
type 'a z = { z : 'a}
9+
let f_record = { x = { y = { z = 3 }}}
10+
11+
12+
let f : f_obj = { x = { y = ({ z = 3 }[@bs.obj]) }} [@bs.obj]
13+

jscomp/test/test.mllib

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,4 +310,6 @@ gpr_405_test
310310

311311
attr_test
312312

313-
uncurry_glob_test
313+
uncurry_glob_test
314+
315+
nested_obj_test

lib/js/test/nested_obj_test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// GENERATED CODE BY BUCKLESCRIPT VERSION 0.5.0 , PLEASE EDIT WITH CARE
2+
'use strict';
3+
4+
5+
var f = {
6+
"x": {
7+
"y": {
8+
"z": 3
9+
}
10+
}
11+
};
12+
13+
var f_record = /* record */[/* x : record */[/* y : record */[/* z */3]]];
14+
15+
exports.f_record = f_record;
16+
exports.f = f;
17+
/* Not a pure module */

0 commit comments

Comments
 (0)