Skip to content

Commit 8635766

Browse files
committed
Merge pull request #388 from bloomberg/clean_up_cont_with_better_name
[feature] provide `[%uncurry: < x : int ; y : int > Js.t ] syntactic sugar`
2 parents 92602a3 + 2323695 commit 8635766

File tree

11 files changed

+287
-62
lines changed

11 files changed

+287
-62
lines changed

jscomp/compiler.mllib

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ ext_ident
1515
ext_pp
1616
ext_option
1717
ext_list
18+
ext_ref
1819
ext_string
1920
ext_char
2021
ext_format

jscomp/ext_list.ml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,36 @@ let rec filter_map (f: 'a -> 'b option) xs =
3838
| Some z -> z :: filter_map f ys
3939
end
4040

41+
let excludes p l =
42+
let excluded = ref false in
43+
let rec aux accu = function
44+
| [] -> List.rev accu
45+
| x :: l ->
46+
if p x then
47+
begin
48+
excluded := true ;
49+
aux accu l
50+
end
51+
else aux (x :: accu) l in
52+
let v = aux [] l in
53+
if !excluded then true, v else false,l
54+
55+
let exclude_with_fact p l =
56+
let excluded = ref None in
57+
let rec aux accu = function
58+
| [] -> List.rev accu
59+
| x :: l ->
60+
if p x then
61+
begin
62+
excluded := Some x ;
63+
aux accu l
64+
end
65+
else aux (x :: accu) l in
66+
let v = aux [] l in
67+
!excluded , if !excluded <> None then v else l
68+
69+
70+
4171
let rec same_length xs ys =
4272
match xs, ys with
4373
| [], [] -> true

jscomp/ext_list.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535

3636
val filter_map : ('a -> 'b option) -> 'a list -> 'b list
3737

38+
val excludes : ('a -> bool) -> 'a list -> bool * 'a list
39+
val exclude_with_fact : ('a -> bool) -> 'a list -> 'a option * 'a list
3840
val same_length : 'a list -> 'b list -> bool
3941

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

jscomp/ext_ref.ml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
(* Copyright (C) 2015-2016 Bloomberg Finance L.P.
2+
*
3+
* This program is free software: you can redistribute it and/or modify
4+
* it under the terms of the GNU Lesser General Public License as published by
5+
* the Free Software Foundation, either version 3 of the License, or
6+
* (at your option) any later version.
7+
*
8+
* In addition to the permissions granted to you by the LGPL, you may combine
9+
* or link a "work that uses the Library" with a publicly distributed version
10+
* of this file to produce a combined library or application, then distribute
11+
* that combined work under the terms of your choosing, with no requirement
12+
* to comply with the obligations normally placed on you by section 4 of the
13+
* LGPL version 3 (or the corresponding section of a later version of the LGPL
14+
* should you choose to use a later version).
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Lesser General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Lesser General Public License
22+
* along with this program; if not, write to the Free Software
23+
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
24+
25+
let protect r v body =
26+
let old = !r in
27+
try
28+
r := v;
29+
let res = body() in
30+
r := old;
31+
res
32+
with x ->
33+
r := old;
34+
raise x

jscomp/ext_ref.mli

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
(* Copyright (C) 2015-2016 Bloomberg Finance L.P.
2+
*
3+
* This program is free software: you can redistribute it and/or modify
4+
* it under the terms of the GNU Lesser General Public License as published by
5+
* the Free Software Foundation, either version 3 of the License, or
6+
* (at your option) any later version.
7+
*
8+
* In addition to the permissions granted to you by the LGPL, you may combine
9+
* or link a "work that uses the Library" with a publicly distributed version
10+
* of this file to produce a combined library or application, then distribute
11+
* that combined work under the terms of your choosing, with no requirement
12+
* to comply with the obligations normally placed on you by section 4 of the
13+
* LGPL version 3 (or the corresponding section of a later version of the LGPL
14+
* should you choose to use a later version).
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Lesser General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Lesser General Public License
22+
* along with this program; if not, write to the Free Software
23+
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
24+
25+
val protect : 'a ref -> 'a -> (unit -> 'b) -> 'b

jscomp/ppx_entry.ml

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -118,17 +118,12 @@ let handle_raw ?ty loc e attrs =
118118
| None -> predef_any_type))
119119

120120

121-
(** TODO: Should remove all [uncurry] attributes *)
121+
122122
let find_uncurry_attrs_and_remove (attrs : Parsetree.attributes ) =
123-
let rec aux (attrs : Parsetree.attributes) acc =
124-
match attrs with
125-
| [({txt = "uncurry"}, _) as v ] -> Some (List.rev acc, v)
126-
| ({txt = "uncurry"}, _) as v :: rest ->
127-
Some ((List.rev acc @ rest) , v)
128-
| non_uncurry :: rest -> aux rest (non_uncurry :: acc)
129-
| [] -> None
130-
in
131-
aux attrs []
123+
Ext_list.exclude_with_fact (function
124+
| ({Location.txt = "uncurry"}, _) -> true
125+
| _ -> false ) attrs
126+
132127

133128
let uncurry_attr loc : Parsetree.attribute =
134129
{txt = "uncurry"; loc}, PStr []
@@ -161,27 +156,48 @@ let uncurry_fn_type loc ty ptyp_attributes
161156
ptyp_attributes = []
162157
}
163158

159+
let uncurry = ref false
160+
161+
(*
162+
Attributes are very hard to attribute
163+
(since ptyp_attributes could happen in so many places),
164+
and write ppx extensions correctly,
165+
we can only use it locally
166+
*)
167+
164168
let handle_typ
165169
(super : Ast_mapper.mapper)
166170
(self : Ast_mapper.mapper)
167171
(ty : Parsetree.core_type) =
168172
match ty with
173+
| {ptyp_desc =
174+
Ptyp_extension({txt = "uncurry"},
175+
PTyp ty )}
176+
->
177+
Ext_ref.protect uncurry true begin fun () ->
178+
self.typ self ty
179+
end
169180
| {ptyp_attributes ;
170181
ptyp_desc = Ptyp_arrow ("", args, body);
171182
ptyp_loc = loc
172-
} ->
183+
} ->
173184
begin match find_uncurry_attrs_and_remove ptyp_attributes with
174-
| Some (ptyp_attributes, _) ->
185+
| Some _, ptyp_attributes ->
175186
let args = self.typ self args in
176187
let body = self.typ self body in
177188
uncurry_fn_type loc ty ptyp_attributes args body
178-
| None -> super.typ self ty
189+
| None, _ ->
190+
let args = self.typ self args in
191+
let body = self.typ self body in
192+
if !uncurry then
193+
uncurry_fn_type loc ty ptyp_attributes args body
194+
else {ty with ptyp_desc = Ptyp_arrow("", args, body)}
179195
end
180196
| {ptyp_desc = Ptyp_object ( methods, closed_flag) } ->
181197
let methods = List.map (fun (label, ptyp_attrs, core_type ) ->
182198
match find_uncurry_attrs_and_remove ptyp_attrs with
183-
| None -> label, ptyp_attrs , self.typ self core_type
184-
| Some (ptyp_attrs, v) ->
199+
| None, _ -> label, ptyp_attrs , self.typ self core_type
200+
| Some v, ptyp_attrs ->
185201
label , ptyp_attrs, self.typ self
186202
{ core_type with ptyp_attributes = v :: core_type.ptyp_attributes}
187203
) methods in

jscomp/test/.depend

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,8 @@ hashtbl_test.cmj : mt.cmi ../stdlib/moreLabels.cmi ../stdlib/list.cmi \
224224
../stdlib/hashtbl.cmi ../stdlib/array.cmi
225225
hashtbl_test.cmx : mt.cmx ../stdlib/moreLabels.cmx ../stdlib/list.cmx \
226226
../stdlib/hashtbl.cmx ../stdlib/array.cmx
227-
http_types.cmj : ../runtime/js.cmj
228-
http_types.cmx : ../runtime/js.cmx
227+
http_types.cmj :
228+
http_types.cmx :
229229
ignore_test.cmj : mt.cmi ../runtime/js.cmj
230230
ignore_test.cmx : mt.cmx ../runtime/js.cmx
231231
inline_edge_cases.cmj : inline_edge_cases.cmi
@@ -870,8 +870,8 @@ hashtbl_test.cmo : mt.cmi ../stdlib/moreLabels.cmi ../stdlib/list.cmi \
870870
../stdlib/hashtbl.cmi ../stdlib/array.cmi
871871
hashtbl_test.cmj : mt.cmj ../stdlib/moreLabels.cmj ../stdlib/list.cmj \
872872
../stdlib/hashtbl.cmj ../stdlib/array.cmj
873-
http_types.cmo : ../runtime/js.cmo
874-
http_types.cmj : ../runtime/js.cmj
873+
http_types.cmo :
874+
http_types.cmj :
875875
ignore_test.cmo : mt.cmi ../runtime/js.cmo
876876
ignore_test.cmj : mt.cmj ../runtime/js.cmj
877877
inline_edge_cases.cmo : inline_edge_cases.cmi

jscomp/test/http_types.ml

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,22 @@
1313

1414

1515
type req
16-
type resp = <
17-
statusCode__set : int -> unit [@uncurry] ;
18-
setHeader : string * string -> unit [@uncurry];
19-
end__ : string -> unit [@uncurry]
20-
>
2116

22-
type server = <
23-
listen : int * string * (unit -> unit [@uncurry]) -> unit [@uncurry]
24-
>
17+
type resp = [%uncurry: <
18+
statusCode__set : int -> unit ;
19+
setHeader : string * string -> unit ;
20+
end__ : string -> unit
21+
> Js.t ]
2522

23+
type server = [%uncurry: <
24+
listen : int * string * (unit -> unit) -> unit
25+
> Js.t]
2626

2727

28-
type http = <
29-
createServer : (req Js.t * resp Js.t -> unit [@uncurry]) -> server Js.t [@uncurry]
30-
>
3128

29+
type http = [%uncurry:<
30+
createServer : (req * resp -> unit ) -> server
31+
> Js.t ]
3232

33-
external http : http Js.t = "http" [@@bs.val_of_module ]
33+
34+
external http : http = "http" [@@bs.val_of_module ]

jscomp/test/test_index.ml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,23 @@ let ff (x : int case Js.t)
2626
let h (x : (< case : (int -> (int -> 'a [@uncurry]) [@uncurry]); .. > as 'b) Js.t) =
2727
let a = x##case 3 in
2828
a #@ 2
29+
30+
31+
type x_obj = [%uncurry: <
32+
case : int -> int ;
33+
case__set : int * int -> unit ;
34+
> Js.t ]
35+
36+
let f_ext
37+
(x : x_obj)
38+
=
39+
x ## case__set (3, 2) ;
40+
x ## case 3
41+
42+
type 'a h_obj = [%uncurry: <
43+
case : int -> (int -> 'a)
44+
> Js.t ]
45+
46+
let h_ext (x : 'a h_obj) =
47+
let a = x ##case 3 in
48+
a #@ 2

0 commit comments

Comments
 (0)