Skip to content

Commit d3534f4

Browse files
author
Hongbo Zhang
committed
done with object type protection
1 parent a8937cc commit d3534f4

File tree

11 files changed

+197
-92
lines changed

11 files changed

+197
-92
lines changed

docs/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33

44
* [FAQ](./FAQ.md)
55

6-
* [About OCaml](https://ocaml.org/)
7-
86
* [Compiler options](./Compiler-options.md)
97

108
* [How to adapt your build system](./How-to-adapt-your-build-system.md)
@@ -21,7 +19,7 @@ everywhere: users don't need to install binaries or use package managers to acce
2119
Another important factor is that the JavaScript VM is quite fast and keeps getting faster.
2220
The JavaScript platform is therefore increasingly capable of supporting large applications.
2321

24-
# Why OCaml?
22+
# Why [OCaml](https://ocaml.org/)?
2523

2624
BuckleScript is mainly designed to solve the problems of large scale JavaScript programming:
2725

docs/SUMMARY.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
* [Home](./README.md)
22

3-
* [Playground](https://bloomberg.github.io/bucklescript/js-demo)
3+
* Playground
4+
* [OCaml Playground](https://bloomberg.github.io/bucklescript/js-demo)
5+
* [Reason Playground](https://bloomberg.github.io/bucklescript/reason-demo)
46

57
* Get Started
68
* [Installation](./Installation.md)

jscomp/ext_list.ml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,28 @@ let exclude_with_fact p l =
6767
!excluded , if !excluded <> None then v else l
6868

6969

70+
(** Make sure [p2 x] and [p1 x] will not hold at the same time *)
71+
let exclude_with_fact2 p1 p2 l =
72+
let excluded1 = ref None in
73+
let excluded2 = ref None in
74+
let rec aux accu = function
75+
| [] -> List.rev accu
76+
| x :: l ->
77+
if p1 x then
78+
begin
79+
excluded1 := Some x ;
80+
aux accu l
81+
end
82+
else if p2 x then
83+
begin
84+
excluded2 := Some x ;
85+
aux accu l
86+
end
87+
else aux (x :: accu) l in
88+
let v = aux [] l in
89+
!excluded1, !excluded2 , if !excluded1 <> None && !excluded2 <> None then v else l
90+
91+
7092

7193
let rec same_length xs ys =
7294
match xs, ys with

jscomp/ext_list.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ val filter_map : ('a -> 'b option) -> 'a list -> 'b list
3737

3838
val excludes : ('a -> bool) -> 'a list -> bool * 'a list
3939
val exclude_with_fact : ('a -> bool) -> 'a list -> 'a option * 'a list
40+
val exclude_with_fact2 :
41+
('a -> bool) -> ('a -> bool) -> 'a list -> 'a option * 'a option * 'a list
4042
val same_length : 'a list -> 'b list -> bool
4143

4244
val init : int -> (int -> 'a) -> 'a list

jscomp/ext_ref.ml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,19 @@ let protect r v body =
3232
with x ->
3333
r := old;
3434
raise x
35+
36+
37+
let protect2 r1 r2 v1 v2 body =
38+
let old1 = !r1 in
39+
let old2 = !r2 in
40+
try
41+
r1 := v1;
42+
r2 := v2;
43+
let res = body() in
44+
r1 := old1;
45+
r2 := old2;
46+
res
47+
with x ->
48+
r1 := old1;
49+
r2 := old2;
50+
raise x

jscomp/ext_ref.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@
2323
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
2424

2525
val protect : 'a ref -> 'a -> (unit -> 'b) -> 'b
26+
27+
val protect2 : 'a ref -> 'b ref -> 'a -> 'b -> (unit -> 'c) -> 'c

jscomp/ppx_entry.ml

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ let uncurry_fn_type loc ty ptyp_attributes
312312
ptyp_attributes = []
313313
}
314314

315-
let uncurry = ref false
315+
let uncurry_type = ref false
316316

317317
(*
318318
Attributes are very hard to attribute
@@ -326,13 +326,6 @@ let handle_typ
326326
(self : Ast_mapper.mapper)
327327
(ty : Parsetree.core_type) =
328328
match ty with
329-
| {ptyp_desc =
330-
Ptyp_extension({txt = "uncurry"},
331-
PTyp ty )}
332-
->
333-
Ext_ref.protect uncurry true begin fun () ->
334-
self.typ self ty
335-
end
336329
| {ptyp_attributes ;
337330
ptyp_desc = Ptyp_arrow ("", args, body);
338331
ptyp_loc = loc
@@ -345,7 +338,7 @@ let handle_typ
345338
| None, _ ->
346339
let args = self.typ self args in
347340
let body = self.typ self body in
348-
if !uncurry then
341+
if !uncurry_type then
349342
uncurry_fn_type loc ty ptyp_attributes args body
350343
else {ty with ptyp_desc = Ptyp_arrow("", args, body)}
351344
end
@@ -354,29 +347,15 @@ let handle_typ
354347
ptyp_attributes ;
355348
ptyp_loc = loc
356349
} ->
357-
begin match Ext_list.exclude_with_fact (function
358-
| {Location.txt = "bs.obj" ; _}, _ -> true
359-
| _ -> false ) ptyp_attributes with
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-
373-
{ptyp_desc =
374-
Ptyp_constr ({ txt = js_obj_type_id () ; loc},
375-
[{ ty with ptyp_desc = Ptyp_object(methods, closed_flag);
376-
ptyp_attributes }]);
377-
ptyp_attributes = [];
378-
ptyp_loc = loc }
379-
| None, _ ->
350+
begin match Ext_list.exclude_with_fact2
351+
(function
352+
| {Location.txt = "bs.obj" ; _}, _ -> true
353+
| _ -> false )
354+
(function
355+
| {Location.txt = "uncurry"; _}, _ -> true
356+
| _ -> false)
357+
ptyp_attributes with
358+
| None, None, _ ->
380359
let methods =
381360
List.map (fun (label, ptyp_attrs, core_type ) ->
382361
match find_uncurry_attrs_and_remove ptyp_attrs with
@@ -395,7 +374,33 @@ let handle_typ
395374
ptyp_loc = loc }
396375
else
397376
{ty with ptyp_desc = Ptyp_object (methods, closed_flag)}
398-
377+
| fact1 , fact2, ptyp_attributes ->
378+
let obj_type_as_js_obj_type_cxt = fact1 <> None || !obj_type_as_js_obj_type in
379+
let uncurry_type_cxt = fact2 <> None || !uncurry_type in
380+
let methods =
381+
Ext_ref.protect2
382+
obj_type_as_js_obj_type
383+
uncurry_type
384+
obj_type_as_js_obj_type_cxt
385+
uncurry_type_cxt begin fun _ ->
386+
List.map (fun (label, ptyp_attrs, core_type ) ->
387+
match find_uncurry_attrs_and_remove ptyp_attrs with
388+
| None, _ -> label, ptyp_attrs , self.typ self core_type
389+
| Some v, ptyp_attrs ->
390+
label , ptyp_attrs, self.typ self
391+
{ core_type with ptyp_attributes = v :: core_type.ptyp_attributes}
392+
) methods
393+
end
394+
in
395+
let inner_type = { ty with ptyp_desc = Ptyp_object(methods, closed_flag);
396+
ptyp_attributes } in
397+
if obj_type_as_js_obj_type_cxt then
398+
{ptyp_desc =
399+
Ptyp_constr ({ txt = js_obj_type_id () ; loc},
400+
[inner_type]);
401+
ptyp_attributes = [];
402+
ptyp_loc = loc }
403+
else inner_type
399404
end
400405
| _ -> super.typ self ty
401406

@@ -410,7 +415,7 @@ let handle_ctyp
410415
} ->
411416
begin match find_uncurry_attrs_and_remove pcty_attributes with
412417
| Some _, pcty_attributes' ->
413-
Ext_ref.protect uncurry true begin fun () ->
418+
Ext_ref.protect uncurry_type true begin fun () ->
414419
self.class_type self {ty with pcty_attributes = pcty_attributes'}
415420
end
416421
| None, _ -> super.class_type self ty

jscomp/test/attr_test.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ let u = fun [@uncurry] (x,y) -> x + y
44
let h = u (1,2) [@uncurry]
55

66
type u = < v : int ; y : int > [@uncurry]
7+
type ('a,'b) xx =
8+
(< case : (int -> (int -> 'a [@uncurry]) [@uncurry]); .. > as 'b)
9+
type ('a,'b) xx_uncurry =
10+
(< case : int -> (int -> 'a ); .. > [@uncurry]) as 'b
711

12+
type yy_uncurry = < x : int > [@uncurry]
13+
type yy = < x : int >
814
type number = float
915

1016
class type date =

jscomp/test/http_types.ml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,24 @@
1414

1515
type req
1616

17-
type resp = [%uncurry: <
17+
type resp =
18+
<
1819
statusCode__set : int -> unit ;
1920
setHeader : string * string -> unit ;
2021
end__ : string -> unit
21-
> Js.t ]
22+
> [@bs.obj] [@uncurry]
2223

23-
type server = [%uncurry: <
24-
listen : int * string * (unit -> unit) -> unit
25-
> Js.t]
24+
type server =
25+
<
26+
listen : int * string * (unit -> unit) -> unit
27+
> [@bs.obj] [@uncurry]
2628

2729

2830

29-
type http = [%uncurry:<
31+
type http =
32+
<
3033
createServer : (req * resp -> unit ) -> server
31-
> Js.t ]
34+
> [@bs.obj] [@uncurry]
3235

3336

3437
external http : http = "http" [@@bs.val_of_module ]

jscomp/test/test_index.ml

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44

55

66

7-
let f (x : (< case : int -> 'a [@uncurry];
8-
case__set : int * int -> unit [@uncurry];
9-
.. > as 'b) Js.t)
7+
let f (x : < case : int -> 'a ;
8+
case__set : int * int -> unit ;
9+
.. > [@uncurry] [@bs.obj])
1010
=
1111
x ## case__set (3, 2) ;
1212
x ## case 3
1313

14-
class type ['a] case = object
15-
method case : int -> 'a [@uncurry]
16-
method case__set : int * 'a -> unit [@uncurry]
14+
class type ['a] case = object [@uncurry]
15+
method case : int -> 'a
16+
method case__set : int * 'a -> unit
1717
end
1818

1919
let ff (x : int case Js.t)
@@ -23,26 +23,29 @@ let ff (x : int case Js.t)
2323

2424

2525

26-
let h (x : (< case : (int -> (int -> 'a [@uncurry]) [@uncurry]); .. > as 'b) Js.t) =
26+
let h (x :
27+
< case : (int -> (int -> 'a ) ); .. > [@uncurry] [@bs.obj]) =
2728
let a = x##case 3 in
28-
a #@ 2
29+
a 2 [@uncurry]
2930

3031

31-
type x_obj = [%uncurry: <
32-
case : int -> int ;
33-
case__set : int * int -> unit ;
34-
> Js.t ]
32+
type x_obj =
33+
<
34+
case : int -> int ;
35+
case__set : int * int -> unit ;
36+
> [@uncurry] [@bs.obj]
3537

3638
let f_ext
3739
(x : x_obj)
3840
=
3941
x ## case__set (3, 2) ;
4042
x ## case 3
4143

42-
type 'a h_obj = [%uncurry: <
43-
case : int -> (int -> 'a)
44-
> Js.t ]
44+
type 'a h_obj =
45+
<
46+
case : int -> (int -> 'a)
47+
> [@uncurry] [@bs.obj]
4548

4649
let h_ext (x : 'a h_obj) =
4750
let a = x ##case 3 in
48-
a #@ 2
51+
a 2 [@uncurry]

0 commit comments

Comments
 (0)