Skip to content

Commit 022c67b

Browse files
committed
Support for @await decorator.
1 parent 5b0b330 commit 022c67b

File tree

6 files changed

+35
-15
lines changed

6 files changed

+35
-15
lines changed

example-async/src/AA.res

+15-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// Boilerplate currently handwritten
2-
external await: Js.Promise.t<'a> => 'a = "?await"
3-
41
type testable = (. unit) => Js.Promise.t<unit>
52

63
let tests: array<testable> = []
@@ -17,17 +14,17 @@ let foo = @async (. x, y) => x + y
1714
let bar =
1815
@async
1916
(. ff) => {
20-
let a = await(ff(. 3, 4))
21-
let b = await(foo(. 5, 6))
17+
let a = @await ff(. 3, 4)
18+
let b = @await foo(. 5, 6)
2219
a + b
2320
}
2421

25-
let baz = @async (. ()) => await(bar(. foo))
22+
let baz = @async (. ()) => @await bar(. foo)
2623

2724
let testBaz: testable =
2825
@async
2926
(. ()) => {
30-
let n = await(baz(.))
27+
let n = @await baz(.)
3128
Js.log2("baz returned", n)
3229
}
3330

@@ -41,14 +38,15 @@ exception E(int)
4138

4239
let e1: testable = @async (. ()) => raise(E(1000))
4340
let e2: testable = @async (. ()) => Js.Exn.raiseError("Some JS error")
44-
let e3: testable = @async (. ()) => await(e1(.))
45-
let e4: testable = @async (. ()) => await(e2(.))
41+
let e3: testable = @async (. ()) => @await e1(.)
42+
let e4: testable = @async (. ()) => @await e2(.)
4643
let e5: testable = %raw(`function() { return Promise.reject(new Error('fail')) }`)
4744

4845
let testTryCatch =
4946
@async
5047
(. fn) =>
51-
try await(fn(.)) catch {
48+
try @await
49+
fn(.) catch {
5250
| E(n) => Js.log2("testTryCatch: E", n)
5351
| JsError(_) => Js.log("testTryCatch: JsError")
5452
}
@@ -82,7 +80,8 @@ let explainError: unknown => string = %raw(`(e)=>e.toString()`)
8280
let testFetch =
8381
@async
8482
(. url) => {
85-
switch await(Fetch.fetch(url)) {
83+
switch @await
84+
Fetch.fetch(url) {
8685
| response =>
8786
let status = response->Fetch.Response.status
8887
Js.log2("Fetch returned status:", status)
@@ -101,8 +100,11 @@ let rec runAllTests =
101100
@async
102101
(. n) => {
103102
if n >= 0 && n < Array.length(tests) {
104-
await(tests[n](.))
105-
await(runAllTests(. n + 1))
103+
@await
104+
tests[n](.)
105+
106+
@await
107+
runAllTests(. n + 1)
106108
}
107109
}
108110

jscomp/frontend/ast_attributes.ml

+6
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ let is_inline : attr -> bool =
164164

165165
let has_inline_payload (attrs : t) = Ext_list.find_first attrs is_inline
166166

167+
let is_await : attr -> bool =
168+
fun ({ txt }, _) -> txt = "await"
169+
170+
let has_await_payload (attrs : t) = Ext_list.find_first attrs is_await
171+
172+
167173
type derive_attr = { bs_deriving : Ast_payload.action list option } [@@unboxed]
168174

169175
let process_derive_type (attrs : t) : derive_attr * t =

jscomp/frontend/ast_attributes.mli

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ val process_bs : t -> bool * t
4444

4545
val has_inline_payload : t -> attr option
4646

47+
val has_await_payload : t -> attr option
48+
4749
type derive_attr = { bs_deriving : Ast_payload.action list option } [@@unboxed]
4850

4951
val iter_process_bs_string_int_unwrap_uncurry :

jscomp/frontend/ast_uncurry_gen.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ let to_uncurry_fn loc (self : Bs_ast_mapper.mapper) (label : Asttypes.arg_label)
8585
let result, rev_extra_args = aux [ (label, first_arg) ] body in
8686
let result =
8787
if async then
88-
let txt = Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_cast") in
88+
let txt = Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_async") in
8989
let pexp_desc = Parsetree.Pexp_ident {txt; loc = result.pexp_loc} in
9090
{result with pexp_desc = Pexp_apply ({result with pexp_desc}, [(Nolabel, result)])}
9191
else result in

jscomp/frontend/bs_builtin_ppx.ml

+9
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ let pat_mapper (self : mapper) (e : Parsetree.pattern) =
7777
{e with ppat_desc = Ppat_constant (Pconst_integer(s,None))}
7878
| _ -> default_pat_mapper self e
7979
let expr_mapper (self : mapper) (e : Parsetree.expression) =
80+
let result =
8081
match e.pexp_desc with
8182
(* Its output should not be rewritten anymore *)
8283
| Pexp_extension extension ->
@@ -193,6 +194,14 @@ let expr_mapper (self : mapper) (e : Parsetree.expression) =
193194
it is very hard to place attributes correctly
194195
*)
195196
| _ -> default_expr_mapper self e
197+
198+
in
199+
match Ast_attributes.has_await_payload e.pexp_attributes with
200+
| None -> result
201+
| Some _ ->
202+
let txt = Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_await") in
203+
let pexp_desc = Parsetree.Pexp_ident {txt; loc = result.pexp_loc} in
204+
{result with pexp_desc = Pexp_apply ({result with pexp_desc}, [(Nolabel, result)])}
196205

197206

198207
let typ_mapper (self : mapper) (typ : Parsetree.core_type) =

jscomp/others/js_promise.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ external catch : ((error -> 'a t)[@bs.uncurry]) -> 'a t = "catch"
9393
external catch2 : 'a t -> ((exn -> 'a t)[@bs.uncurry]) -> 'a t = "catch"
9494
[@@bs.send]
9595

96-
external unsafe_cast : 'a -> 'a t = "%identity"
96+
external unsafe_async : 'a -> 'a t = "%identity"
97+
external unsafe_await : 'a t -> 'a = "?await"
9798

9899

99100
(*

0 commit comments

Comments
 (0)