Skip to content

Commit a1e53a0

Browse files
authored
Merge pull request #2665 from BuckleScript/customize_label_name_part2
support option in abstract type (part 2)
2 parents 4836428 + 603bf66 commit a1e53a0

13 files changed

+1210
-700
lines changed

jscomp/all.depend

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ syntax/external_process.cmx : common/lam_methname.cmx \
222222
syntax/external_process.cmi
223223
syntax/ast_derive_abstract.cmx : syntax/external_process.cmx \
224224
ext/ext_list.cmx syntax/ast_literal.cmx syntax/ast_derive_util.cmx \
225-
syntax/ast_attributes.cmx syntax/ast_derive_abstract.cmi
225+
syntax/ast_core_type.cmx syntax/ast_attributes.cmx \
226+
syntax/ast_derive_abstract.cmi
226227
syntax/ast_derive_dyn.cmx : ext/ext_list.cmx syntax/bs_syntaxerr.cmx \
227228
syntax/ast_structure.cmx syntax/ast_derive_util.cmx syntax/ast_derive.cmx \
228229
syntax/ast_attributes.cmx syntax/ast_derive_dyn.cmi

jscomp/syntax/ast_attributes.ml

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -292,26 +292,43 @@ let iter_process_bs_string_or_int_as attrs =
292292
) attrs;
293293
!st
294294

295+
let locg = Location.none
295296
let bs : attr
296-
= {txt = "bs" ; loc = Location.none}, Ast_payload.empty
297+
= {txt = "bs" ; loc = locg}, Ast_payload.empty
297298

298299
let is_bs (attr : attr) =
299300
match attr with
300301
| {Location.txt = "bs"; _}, _ -> true
301302
| _ -> false
302303

303304
let bs_this : attr
304-
= {txt = "bs.this" ; loc = Location.none}, Ast_payload.empty
305+
= {txt = "bs.this" ; loc = locg}, Ast_payload.empty
305306

306307
let bs_method : attr
307-
= {txt = "bs.meth"; loc = Location.none}, Ast_payload.empty
308+
= {txt = "bs.meth"; loc = locg}, Ast_payload.empty
308309

309310
let bs_obj : attr
310-
= {txt = "bs.obj"; loc = Location.none}, Ast_payload.empty
311+
= {txt = "bs.obj"; loc = locg}, Ast_payload.empty
311312

312313
let bs_get : attr
313-
= {txt = "bs.get"; loc = Location.none}, Ast_payload.empty
314+
= {txt = "bs.get"; loc = locg}, Ast_payload.empty
314315

315316
let bs_set : attr
316-
= {txt = "bs.set"; loc = Location.none}, Ast_payload.empty
317+
= {txt = "bs.set"; loc = locg}, Ast_payload.empty
318+
319+
let bs_return_undefined : attr
320+
=
321+
{txt = "bs.return"; loc = locg },
322+
PStr
323+
[
324+
{pstr_desc =
325+
Pstr_eval (
326+
{pexp_desc =
327+
Pexp_ident
328+
{ txt = Lident "undefined_to_opt";
329+
loc = locg};
330+
pexp_loc = locg;
331+
pexp_attributes = []
332+
},[])
333+
; pstr_loc = locg}]
317334

jscomp/syntax/ast_attributes.mli

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,5 @@ val bs_obj : attr
7979

8080

8181
val bs_get : attr
82-
val bs_set : attr
82+
val bs_set : attr
83+
val bs_return_undefined : attr

jscomp/syntax/ast_core_type.ml

Lines changed: 92 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(* Copyright (C) 2015-2016 Bloomberg Finance L.P.
2-
*
2+
*
33
* This program is free software: you can redistribute it and/or modify
44
* it under the terms of the GNU Lesser General Public License as published by
55
* the Free Software Foundation, either version 3 of the License, or
@@ -17,162 +17,177 @@
1717
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1818
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1919
* GNU Lesser General Public License for more details.
20-
*
20+
*
2121
* You should have received a copy of the GNU Lesser General Public License
2222
* along with this program; if not, write to the Free Software
2323
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
2424

25-
type t = Parsetree.core_type
25+
type t = Parsetree.core_type
2626

2727
type arg_label =
28-
| Label of string
29-
| Optional of string
28+
| Label of string
29+
| Optional of string
3030
| Empty (* it will be ignored , side effect will be recorded *)
3131

3232

3333

34-
let extract_option_type_exn (ty : t) =
34+
let extract_option_type_exn (ty : t) =
3535
begin match ty with
3636
| {ptyp_desc =
37-
Ptyp_constr({txt =
38-
Ldot (Lident "*predef*", "option") },
39-
[ty])}
40-
->
37+
Ptyp_constr
38+
({txt =
39+
Ldot (Lident "*predef*", "option")
40+
| Lident "option"
41+
},
42+
[ty])}
43+
->
4144
ty
42-
| _ -> assert false
43-
end
45+
| _ -> assert false
46+
end
47+
48+
let extract_option_type (ty : t) =
49+
match ty.ptyp_desc with
50+
| Ptyp_constr(
51+
{txt = (Ldot (Lident "*predef*", "option")
52+
| Lident "option")},
53+
[ty]) -> Some ty
54+
| _ -> None
55+
56+
let predef_option : Longident.t =
57+
Longident.Ldot (Lident "*predef*", "option")
4458

45-
let predef_option : Longident.t = Longident.Ldot (Lident "*predef*", "option")
46-
let predef_int : Longident.t = Ldot (Lident "*predef*", "int")
59+
let predef_int : Longident.t =
60+
Ldot (Lident "*predef*", "int")
4761

4862

49-
let lift_option_type (ty:t) : t =
63+
let lift_option_type ({ptyp_loc} as ty:t) : t =
5064
{ptyp_desc =
5165
Ptyp_constr(
5266
{txt = predef_option;
53-
loc = ty.ptyp_loc}
67+
loc = ptyp_loc}
5468
, [ty]);
55-
ptyp_loc = ty.ptyp_loc;
69+
ptyp_loc = ptyp_loc;
5670
ptyp_attributes = []
5771
}
5872

59-
let is_any (ty : t) =
60-
match ty with {ptyp_desc = Ptyp_any} -> true | _ -> false
73+
let is_any (ty : t) =
74+
ty.ptyp_desc = Ptyp_any
6175

6276
open Ast_helper
6377

64-
let replace_result ty result =
65-
let rec aux (ty : Parsetree.core_type) =
66-
match ty with
67-
| { ptyp_desc =
78+
let replace_result (ty : t) (result : t) : t =
79+
let rec aux (ty : Parsetree.core_type) =
80+
match ty with
81+
| { ptyp_desc =
6882
Ptyp_arrow (label,t1,t2)
6983
} -> { ty with ptyp_desc = Ptyp_arrow(label,t1, aux t2)}
70-
| {ptyp_desc = Ptyp_poly(fs,ty)}
84+
| {ptyp_desc = Ptyp_poly(fs,ty)}
7185
-> {ty with ptyp_desc = Ptyp_poly(fs, aux ty)}
72-
| _ -> result in
73-
aux ty
86+
| _ -> result in
87+
aux ty
7488

75-
let is_unit (ty : t ) =
76-
match ty.ptyp_desc with
89+
let is_unit (ty : t ) =
90+
match ty.ptyp_desc with
7791
| Ptyp_constr({txt =Lident "unit"}, []) -> true
78-
| _ -> false
92+
| _ -> false
7993

80-
let is_array (ty : t) =
81-
match ty.ptyp_desc with
94+
let is_array (ty : t) =
95+
match ty.ptyp_desc with
8296
| Ptyp_constr({txt =Lident "array"}, [_]) -> true
83-
| _ -> false
97+
| _ -> false
8498

85-
let is_user_option (ty : t) =
86-
match ty.ptyp_desc with
87-
| Ptyp_constr({txt = Lident "option"},[_]) -> true
88-
| _ -> false
99+
let is_user_option (ty : t) =
100+
match ty.ptyp_desc with
101+
| Ptyp_constr({txt = Lident "option"},[_]) -> true
102+
| _ -> false
89103

90-
let is_user_bool (ty : t) =
91-
match ty.ptyp_desc with
92-
| Ptyp_constr({txt = Lident "bool"},[]) -> true
93-
| _ -> false
104+
let is_user_bool (ty : t) =
105+
match ty.ptyp_desc with
106+
| Ptyp_constr({txt = Lident "bool"},[]) -> true
107+
| _ -> false
94108

95-
let is_user_int (ty : t) =
96-
match ty.ptyp_desc with
97-
| Ptyp_constr({txt = Lident "int"},[]) -> true
98-
| _ -> false
109+
let is_user_int (ty : t) =
110+
match ty.ptyp_desc with
111+
| Ptyp_constr({txt = Lident "int"},[]) -> true
112+
| _ -> false
99113

100114
let is_optional_label l =
101115
String.length l > 0 && l.[0] = '?'
102116

103117
let label_name l : arg_label =
104-
if l = "" then Empty else
105-
if is_optional_label l
118+
if l = "" then Empty else
119+
if is_optional_label l
106120
then Optional (String.sub l 1 (String.length l - 1))
107121
else Label l
108122

109123

110-
(* Note that OCaml type checker will not allow arbitrary
124+
(* Note that OCaml type checker will not allow arbitrary
111125
name as type variables, for example:
112126
{[
113127
'_x'_
114128
]}
115129
will be recognized as a invalid program
116130
*)
117-
let from_labels ~loc arity labels
131+
let from_labels ~loc arity labels
118132
: t =
119-
let tyvars =
120-
((Ext_list.init arity (fun i ->
133+
let tyvars =
134+
((Ext_list.init arity (fun i ->
121135
Typ.var ~loc ("a" ^ string_of_int i)))) in
122136
let result_type =
123-
Ast_comb.to_js_type loc
137+
Ast_comb.to_js_type loc
124138
(Typ.object_ ~loc
125139
(Ext_list.map2 (fun x y -> x.Asttypes.txt ,[], y) labels tyvars) Closed)
126-
in
127-
Ext_list.fold_right2
140+
in
141+
Ext_list.fold_right2
128142
(fun {Asttypes.loc ; txt = label }
129143
tyvar acc -> Typ.arrow ~loc label tyvar acc) labels tyvars result_type
130144

131145

132146
let make_obj ~loc xs =
133-
Ast_comb.to_js_type loc @@
134-
Ast_helper.Typ.object_ ~loc xs Closed
147+
Ast_comb.to_js_type loc
148+
(Ast_helper.Typ.object_ ~loc xs Closed)
135149

136150

151+
let opt_arrow loc label ty1 ty2 =
152+
Typ.arrow ~loc ("?" ^ label) ty1 ty2
153+
(**
137154
138-
(**
139-
140-
{[ 'a . 'a -> 'b ]}
155+
{[ 'a . 'a -> 'b ]}
141156
OCaml does not support such syntax yet
142157
{[ 'a -> ('a. 'a -> 'b) ]}
143158
144159
*)
145-
let rec get_uncurry_arity_aux (ty : t) acc =
146-
match ty.ptyp_desc with
147-
| Ptyp_arrow(_, _ , new_ty) ->
160+
let rec get_uncurry_arity_aux (ty : t) acc =
161+
match ty.ptyp_desc with
162+
| Ptyp_arrow(_, _ , new_ty) ->
148163
get_uncurry_arity_aux new_ty (succ acc)
149-
| Ptyp_poly (_,ty) ->
150-
get_uncurry_arity_aux ty acc
151-
| _ -> acc
164+
| Ptyp_poly (_,ty) ->
165+
get_uncurry_arity_aux ty acc
166+
| _ -> acc
152167

153168
(**
154-
{[ unit -> 'a1 -> a2']} arity 2
155-
{[ unit -> 'b ]} return arity 0
156-
{[ 'a1 -> 'a2 -> ... 'aN -> 'b ]} return arity N
169+
{[ unit -> 'a1 -> a2']} arity 2
170+
{[ unit -> 'b ]} return arity 0
171+
{[ 'a1 -> 'a2 -> ... 'aN -> 'b ]} return arity N
157172
*)
158-
let get_uncurry_arity (ty : t ) =
159-
match ty.ptyp_desc with
160-
| Ptyp_arrow("", {ptyp_desc = (Ptyp_constr ({txt = Lident "unit"}, []))},
173+
let get_uncurry_arity (ty : t ) =
174+
match ty.ptyp_desc with
175+
| Ptyp_arrow("", {ptyp_desc = (Ptyp_constr ({txt = Lident "unit"}, []))},
161176
({ptyp_desc = Ptyp_arrow _ } as rest )) -> `Arity (get_uncurry_arity_aux rest 1 )
162177
| Ptyp_arrow("", {ptyp_desc = (Ptyp_constr ({txt = Lident "unit"}, []))}, _) -> `Arity 0
163-
| Ptyp_arrow(_,_,rest ) ->
178+
| Ptyp_arrow(_,_,rest ) ->
164179
`Arity(get_uncurry_arity_aux rest 1)
165-
| _ -> `Not_function
180+
| _ -> `Not_function
166181

167182
let get_curry_arity ty =
168183
get_uncurry_arity_aux ty 0
169184

170185
let is_arity_one ty = get_curry_arity ty = 1
171-
172-
let list_of_arrow (ty : t) =
173-
let rec aux (ty : t) acc =
174-
match ty.ptyp_desc with
175-
| Ptyp_arrow(label,t1,t2) ->
186+
187+
let list_of_arrow (ty : t) =
188+
let rec aux (ty : t) acc =
189+
match ty.ptyp_desc with
190+
| Ptyp_arrow(label,t1,t2) ->
176191
aux t2 ((label,t1,ty.ptyp_attributes,ty.ptyp_loc) ::acc)
177192
| Ptyp_poly(_, ty) -> (* should not happen? *)
178193
Bs_syntaxerr.err ty.ptyp_loc Unhandled_poly_type

0 commit comments

Comments
 (0)