Skip to content

Commit 2449a0d

Browse files
committed
translate bs.send.pipe into bs.send internally
1 parent 60be39f commit 2449a0d

22 files changed

+8172
-2987
lines changed

jscomp/frontend/ast_attributes.ml

+31-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,37 @@ let process_derive_type (attrs : t) : derive_attr * t =
221221
st, attr::acc
222222
)
223223

224-
224+
let process_send_pipe (attrs : t ) : (Parsetree.core_type * t) option =
225+
match attrs with
226+
| [] -> None
227+
| _ ->
228+
if not (Ext_list.exists_fst attrs (fun {txt} -> txt = "bs.send.pipe")) then
229+
(* fast path *)
230+
None
231+
else
232+
let ty = ref None in
233+
let attrs =
234+
Ext_list.fold_left attrs []
235+
(fun acc ({txt ; loc}, payload as attr) ->
236+
match txt with
237+
| "bs.send.pipe"
238+
->
239+
begin match !ty with
240+
| None ->
241+
Location.prerr_warning loc (Warnings.Bs_ffi_warning "This attribute is deprecated, use @send instead.");
242+
243+
ty:=Some (Ast_payload.as_core_type loc payload);
244+
(({Asttypes.txt = "bs.send";loc}, Parsetree.PStr []):: acc)
245+
| Some _
246+
->
247+
Location.raise_errorf ~loc "Duplicated bs.send.pipe"
248+
end
249+
| _ ->
250+
attr::acc
251+
) in
252+
match !ty with
253+
| None -> assert false
254+
| Some ty -> Some (ty, attrs)
225255

226256
(* duplicated @uncurry @string not allowed,
227257
it is worse in @uncurry since it will introduce

jscomp/frontend/ast_core_type.ml

+10
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,16 @@ let get_uncurry_arity (ty : t ) =
167167
let get_curry_arity ty =
168168
get_uncurry_arity_aux ty 0
169169

170+
(* add hoc for bs.send.pipe *)
171+
let rec get_curry_labels (ty : t) acc =
172+
match ty.ptyp_desc with
173+
| Ptyp_arrow(label, _, rest)
174+
-> get_curry_labels rest (label ::acc)
175+
| _ -> acc
176+
177+
let get_curry_labels ty =
178+
List.rev (get_curry_labels ty [])
179+
170180
let is_arity_one ty = get_curry_arity ty = 1
171181

172182

jscomp/frontend/ast_core_type.mli

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ val is_user_option : t -> bool
5757
val get_uncurry_arity : t -> int option
5858

5959

60+
val get_curry_labels : t -> Asttypes.arg_label list
6061

6162
(** fails when Ptyp_poly *)
6263
val list_of_arrow :

jscomp/frontend/ast_external.ml

+85-26
Original file line numberDiff line numberDiff line change
@@ -32,32 +32,46 @@ let handleExternalInSig
3232
let loc = prim.pval_loc in
3333
let pval_type = self.typ self prim.pval_type in
3434
let pval_attributes = self.attributes self prim.pval_attributes in
35-
match prim.pval_prim with
36-
| [] ->
37-
Location.raise_errorf
38-
~loc
39-
"empty primitive string"
40-
| a :: b :: _ ->
41-
Location.raise_errorf
42-
~loc
43-
"only a single string is allowed in bs external %S %S" a b
44-
| [ v ] ->
45-
match Ast_external_process.handle_attributes_as_string
46-
loc
47-
pval_type
48-
pval_attributes
49-
prim.pval_name.txt
50-
v
51-
with
52-
| {pval_type; pval_prim; pval_attributes; no_inline_cross_module} ->
53-
{sigi with
54-
psig_desc =
55-
Psig_value
56-
{prim with
57-
pval_type ;
58-
pval_prim = if no_inline_cross_module then [] else pval_prim ;
59-
pval_attributes
60-
}}
35+
match Ast_attributes.process_send_pipe pval_attributes with
36+
| Some (obj , _) ->
37+
(*has bs.send.pipe: best effort *)
38+
begin {
39+
sigi with
40+
psig_desc = Psig_value {
41+
prim with
42+
pval_type = Ast_helper.Typ.arrow ~loc Nolabel obj pval_type ;
43+
pval_prim = [];
44+
pval_attributes = []
45+
}
46+
}
47+
end
48+
| None ->
49+
match prim.pval_prim with
50+
| [] ->
51+
Location.raise_errorf
52+
~loc
53+
"empty primitive string"
54+
| a :: b :: _ ->
55+
Location.raise_errorf
56+
~loc
57+
"only a single string is allowed in bs external %S %S" a b
58+
| [ v ] ->
59+
match Ast_external_process.handle_attributes_as_string
60+
loc
61+
pval_type
62+
pval_attributes
63+
prim.pval_name.txt
64+
v
65+
with
66+
| {pval_type; pval_prim; pval_attributes; no_inline_cross_module} ->
67+
{sigi with
68+
psig_desc =
69+
Psig_value
70+
{prim with
71+
pval_type ;
72+
pval_prim = if no_inline_cross_module then [] else pval_prim ;
73+
pval_attributes
74+
}}
6175

6276
let handleExternalInStru
6377
(self : Bs_ast_mapper.mapper)
@@ -67,6 +81,13 @@ let handleExternalInStru
6781
let loc = prim.pval_loc in
6882
let pval_type = self.typ self prim.pval_type in
6983
let pval_attributes = self.attributes self prim.pval_attributes in
84+
let send_pipe = ref false in
85+
let pval_type , pval_attributes =
86+
match Ast_attributes.process_send_pipe pval_attributes with
87+
| Some (obj, attrs) ->
88+
send_pipe := true ;
89+
Ast_helper.Typ.arrow ~loc Nolabel obj pval_type, attrs
90+
| None -> pval_type, pval_attributes in
7091
match prim.pval_prim with
7192
| []
7293
->
@@ -95,6 +116,44 @@ let handleExternalInStru
95116
pval_prim;
96117
pval_attributes
97118
}} in
119+
if !send_pipe then
120+
let [@warning "-8"] ((_::params) as args) = Ast_core_type.get_curry_labels pval_type in
121+
let arity = List.length args in
122+
let open Ast_helper in
123+
Str.include_ ~loc
124+
(Incl.mk ~loc
125+
(Mod.structure ~loc
126+
[external_result;
127+
Str.value
128+
~loc Nonrecursive [
129+
Vb.mk ~loc
130+
(Pat.var ~loc prim.pval_name)
131+
132+
(let body = (Exp.apply ~loc
133+
(Exp.ident ~loc {txt = Lident prim.pval_name.txt; loc })
134+
(Ext_list.mapi args (fun i x ->
135+
match x with
136+
| Asttypes.Nolabel ->
137+
Asttypes.Nolabel, Exp.ident {txt = Lident ("arg"^string_of_int i); loc}
138+
| Labelled s
139+
| Optional s
140+
->
141+
x, Exp.ident {txt = Lident s ; loc}
142+
))
143+
) in
144+
snd @@
145+
Ext_list.fold_right
146+
params (0, Exp.fun_ Nolabel None (Pat.var ~loc { txt = "arg0"; loc} ) body) (
147+
fun arg (i, obj) ->
148+
i + 1, Exp.fun_ arg None
149+
(Pat.var ~loc {txt = (match arg with | Labelled s | Optional s -> s
150+
| Nolabel -> "arg" ^ string_of_int (arity - i - 1)); loc}) obj
151+
)
152+
)
153+
]
154+
])
155+
)
156+
else
98157
if not no_inline_cross_module then
99158
external_result
100159
else

jscomp/main/builtin_cmi_datasets.ml

+37-37
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)