Skip to content

Commit 17939af

Browse files
committed
wip: await AST
1 parent db89ef2 commit 17939af

22 files changed

+102
-64
lines changed

analysis/src/CompletionFrontEnd.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ let rec exprToContextPathInner ~(inJsxContext : bool) (e : Parsetree.expression)
316316

317317
and exprToContextPath ~(inJsxContext : bool) (e : Parsetree.expression) =
318318
match
319-
( Res_parsetree_viewer.has_await_attribute e.pexp_attributes,
319+
( Res_parsetree_viewer.has_await_attribute e,
320320
exprToContextPathInner ~inJsxContext e )
321321
with
322322
| true, Some ctxPath -> Some (CPAwait ctxPath)

compiler/frontend/bs_ast_mapper.ml

+1
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ module E = struct
366366
| Pexp_open (ovf, lid, e) ->
367367
open_ ~loc ~attrs ovf (map_loc sub lid) (sub.expr sub e)
368368
| Pexp_extension x -> extension ~loc ~attrs (sub.extension sub x)
369+
| Pexp_await e -> await ~loc ~attrs (sub.expr sub e)
369370
end
370371

371372
module P = struct

compiler/frontend/bs_builtin_ppx.ml

+12-9
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ let expr_mapper ~async_context ~in_function_def (self : mapper)
177177
(* module M = await Belt.List *)
178178
| Pexp_letmodule
179179
(lid, ({pmod_desc = Pmod_ident {txt}; pmod_attributes} as me), expr)
180-
when Res_parsetree_viewer.has_await_attribute pmod_attributes ->
180+
when Res_parsetree_viewer.has_await_attribute2 pmod_attributes ->
181181
let safe_module_type_lid : Ast_helper.lid =
182182
{txt = Lident (local_module_type_name txt); loc = me.pmod_loc}
183183
in
@@ -201,8 +201,8 @@ let expr_mapper ~async_context ~in_function_def (self : mapper)
201201
pmod_attributes = attrs2;
202202
} as me),
203203
expr )
204-
when Res_parsetree_viewer.has_await_attribute attrs1
205-
|| Res_parsetree_viewer.has_await_attribute attrs2 ->
204+
when Res_parsetree_viewer.has_await_attribute2 attrs1
205+
|| Res_parsetree_viewer.has_await_attribute2 attrs2 ->
206206
{
207207
e with
208208
pexp_desc =
@@ -242,10 +242,12 @@ let expr_mapper ~async_context ~in_function_def (self : mapper)
242242
|| Ast_attributes.has_await_payload attrs2 ->
243243
check_await ();
244244
result
245-
| _ when Ast_attributes.has_await_payload e.pexp_attributes ->
246-
check_await ();
247-
Ast_await.create_await_expression result
248-
| _ -> result
245+
| _ -> (
246+
match result.pexp_desc with
247+
| Pexp_await e ->
248+
check_await ();
249+
Ast_await.create_await_expression e
250+
| _ -> result)
249251

250252
let typ_mapper (self : mapper) (typ : Parsetree.core_type) =
251253
Ast_core_type_class_type.typ_mapper self typ
@@ -493,7 +495,7 @@ let rec structure_mapper ~await_context (self : mapper) (stru : Ast_structure.t)
493495
| Pstr_module
494496
({pmb_expr = {pmod_desc = Pmod_ident {txt; loc}; pmod_attributes} as me}
495497
as mb)
496-
when Res_parsetree_viewer.has_await_attribute pmod_attributes ->
498+
when Res_parsetree_viewer.has_await_attribute2 pmod_attributes ->
497499
let item = self.structure_item self item in
498500
let safe_module_type_name = local_module_type_name txt in
499501
let has_local_module_name =
@@ -544,7 +546,8 @@ let rec structure_mapper ~await_context (self : mapper) (stru : Ast_structure.t)
544546
( _,
545547
({pmod_desc = Pmod_ident {txt; loc}; pmod_attributes} as me),
546548
expr )
547-
when Res_parsetree_viewer.has_await_attribute pmod_attributes -> (
549+
when Res_parsetree_viewer.has_await_attribute2 pmod_attributes
550+
-> (
548551
let safe_module_type_name = local_module_type_name txt in
549552
let has_local_module_name =
550553
Hashtbl.find_opt !await_context safe_module_type_name

compiler/ml/ast_helper.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ module Exp = struct
180180
let pack ?loc ?attrs a = mk ?loc ?attrs (Pexp_pack a)
181181
let open_ ?loc ?attrs a b c = mk ?loc ?attrs (Pexp_open (a, b, c))
182182
let extension ?loc ?attrs a = mk ?loc ?attrs (Pexp_extension a)
183-
183+
let await ?loc ?attrs a = mk ?loc ?attrs (Pexp_await a)
184184
let case lhs ?guard rhs = {pc_lhs = lhs; pc_guard = guard; pc_rhs = rhs}
185185
end
186186

compiler/ml/ast_helper.mli

+1
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ module Exp : sig
210210
val extension : ?loc:loc -> ?attrs:attrs -> extension -> expression
211211

212212
val case : pattern -> ?guard:expression -> expression -> case
213+
val await : ?loc:loc -> ?attrs:attrs -> expression -> expression
213214
end
214215

215216
(** Value declarations *)

compiler/ml/ast_iterator.ml

+1
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ module E = struct
344344
iter_loc sub lid;
345345
sub.expr sub e
346346
| Pexp_extension x -> sub.extension sub x
347+
| Pexp_await e -> sub.expr sub e
347348
end
348349

349350
module P = struct

compiler/ml/ast_mapper.ml

+1
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ module E = struct
329329
| Pexp_open (ovf, lid, e) ->
330330
open_ ~loc ~attrs ovf (map_loc sub lid) (sub.expr sub e)
331331
| Pexp_extension x -> extension ~loc ~attrs (sub.extension sub x)
332+
| Pexp_await e -> await ~loc ~attrs (sub.expr sub e)
332333
end
333334

334335
module P = struct

compiler/ml/ast_mapper_to0.ml

+1
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ module E = struct
407407
| Pexp_open (ovf, lid, e) ->
408408
open_ ~loc ~attrs ovf (map_loc sub lid) (sub.expr sub e)
409409
| Pexp_extension x -> extension ~loc ~attrs (sub.extension sub x)
410+
| Pexp_await _ -> (* TODO *) assert false
410411
end
411412

412413
module P = struct

compiler/ml/depend.ml

+1
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ let rec add_expr bv exp =
289289
| Pstr_eval ({pexp_desc = Pexp_construct (c, None)}, _) -> add bv c
290290
| _ -> handle_extension e)
291291
| Pexp_extension e -> handle_extension e
292+
| Pexp_await e -> add_expr bv e
292293

293294
and add_cases bv cases = List.iter (add_case bv) cases
294295

compiler/ml/parsetree.ml

+3-2
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,9 @@ and expression_desc =
313313
let open M in E
314314
let! open M in E *)
315315
| Pexp_extension of extension
316-
(* [%id] *)
317-
(* . *)
316+
(* [%id] *)
317+
(* . *)
318+
| Pexp_await of expression
318319

319320
and case = {
320321
(* (P -> E) or (P when E0 -> E) *)

compiler/ml/pprintast.ml

+1
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,7 @@ and expression ctxt f x =
722722
(expression ctxt) e
723723
| Pexp_variant (l, Some eo) -> pp f "@[<2>`%s@;%a@]" l (simple_expr ctxt) eo
724724
| Pexp_extension e -> extension ctxt f e
725+
| Pexp_await e -> pp f "@[<hov2>await@ %a@]" (simple_expr ctxt) e
725726
| _ -> expression1 ctxt f x
726727

727728
and expression1 ctxt f x =

compiler/ml/printast.ml

+3
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,9 @@ and expression i ppf x =
345345
| Pexp_extension (s, arg) ->
346346
line i ppf "Pexp_extension \"%s\"\n" s.txt;
347347
payload i ppf arg
348+
| Pexp_await e ->
349+
line i ppf "Pexp_await\n";
350+
expression i ppf e
348351

349352
and value_description i ppf x =
350353
line i ppf "value_description %a %a\n" fmt_string_loc x.pval_name fmt_location

compiler/ml/typecore.ml

+2
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ let iter_expression f e =
178178
expr e;
179179
module_expr me
180180
| Pexp_pack me -> module_expr me
181+
| Pexp_await _ -> assert false (* should be handled earlier *)
181182
and case {pc_lhs = _; pc_guard; pc_rhs} =
182183
may expr pc_guard;
183184
expr pc_rhs
@@ -3194,6 +3195,7 @@ and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp
31943195
| _ -> raise (Error (loc, env, Invalid_extension_constructor_payload)))
31953196
| Pexp_extension ext ->
31963197
raise (Error_forward (Builtin_attributes.error_of_extension ext))
3198+
| Pexp_await _ -> (* should be handled earlier *) assert false
31973199
31983200
and type_function ?in_function ~arity ~async loc attrs env ty_expected_ l
31993201
caselist =

compiler/syntax/src/res_ast_debugger.ml

+1
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,7 @@ module SexpAst = struct
707707
]
708708
| Pexp_extension ext ->
709709
Sexp.list [Sexp.atom "Pexp_extension"; extension ext]
710+
| Pexp_await e -> Sexp.list [Sexp.atom "Pexp_await"; expression e]
710711
in
711712
Sexp.list [Sexp.atom "expression"; desc]
712713

compiler/syntax/src/res_core.ml

+3-6
Original file line numberDiff line numberDiff line change
@@ -3297,15 +3297,12 @@ and parse_async_arrow_expression ?(arrow_attrs = []) p =
32973297

32983298
and parse_await_expression p =
32993299
let await_loc = mk_loc p.Parser.start_pos p.end_pos in
3300-
let await_attr = make_await_attr await_loc in
33013300
Parser.expect Await p;
33023301
let token_prec = Token.precedence MinusGreater in
33033302
let expr = parse_binary_expr ~context:OrdinaryExpr p token_prec in
3304-
{
3305-
expr with
3306-
pexp_attributes = await_attr :: expr.pexp_attributes;
3307-
pexp_loc = {expr.pexp_loc with loc_start = await_loc.loc_start};
3308-
}
3303+
Ast_helper.Exp.await
3304+
~loc:{expr.pexp_loc with loc_start = await_loc.loc_start}
3305+
~attrs:[] expr
33093306

33103307
and parse_try_expression p =
33113308
let start_pos = p.Parser.start_pos in

compiler/syntax/src/res_parens.ml

+7-15
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ let call_expr expr =
5656
} ->
5757
Parenthesized
5858
| _ when Ast_uncurried.expr_is_uncurried_fun expr -> Parenthesized
59-
| _ when ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
60-
Parenthesized
59+
| _ when ParsetreeViewer.has_await_attribute expr -> Parenthesized
6160
| _ -> Nothing)
6261

6362
let structure_expr expr =
@@ -109,8 +108,7 @@ let unary_expr_operand expr =
109108
| Pexp_try _ | Pexp_while _ | Pexp_for _ | Pexp_ifthenelse _ );
110109
} ->
111110
Parenthesized
112-
| _ when ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
113-
Parenthesized
111+
| _ when ParsetreeViewer.has_await_attribute expr -> Parenthesized
114112
| _ -> Nothing)
115113

116114
let binary_expr_operand ~is_lhs expr =
@@ -133,8 +131,7 @@ let binary_expr_operand ~is_lhs expr =
133131
| expr when ParsetreeViewer.is_binary_expression expr -> Parenthesized
134132
| expr when ParsetreeViewer.is_ternary_expr expr -> Parenthesized
135133
| {pexp_desc = Pexp_lazy _ | Pexp_assert _} when is_lhs -> Parenthesized
136-
| _ when ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
137-
Parenthesized
134+
| _ when ParsetreeViewer.has_await_attribute expr -> Parenthesized
138135
| {Parsetree.pexp_attributes = attrs} ->
139136
if ParsetreeViewer.has_printable_attributes attrs then Parenthesized
140137
else Nothing)
@@ -230,9 +227,7 @@ let lazy_or_assert_or_await_expr_rhs ?(in_await = false) expr =
230227
| Pexp_while _ | Pexp_for _ | Pexp_ifthenelse _ );
231228
} ->
232229
Parenthesized
233-
| _
234-
when (not in_await)
235-
&& ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
230+
| _ when (not in_await) && ParsetreeViewer.has_await_attribute expr ->
236231
Parenthesized
237232
| _ -> Nothing)
238233

@@ -278,8 +273,7 @@ let field_expr expr =
278273
| Pexp_try _ | Pexp_while _ | Pexp_for _ | Pexp_ifthenelse _ );
279274
} ->
280275
Parenthesized
281-
| _ when ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
282-
Parenthesized
276+
| _ when ParsetreeViewer.has_await_attribute expr -> Parenthesized
283277
| _ -> Nothing)
284278

285279
let set_field_expr_rhs expr =
@@ -340,8 +334,7 @@ let jsx_prop_expr expr =
340334
}
341335
when starts_with_minus x ->
342336
Parenthesized
343-
| _ when ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
344-
Parenthesized
337+
| _ when ParsetreeViewer.has_await_attribute expr -> Parenthesized
345338
| {
346339
Parsetree.pexp_desc =
347340
( Pexp_ident _ | Pexp_constant _ | Pexp_field _ | Pexp_construct _
@@ -378,8 +371,7 @@ let jsx_child_expr expr =
378371
}
379372
when starts_with_minus x ->
380373
Parenthesized
381-
| _ when ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
382-
Parenthesized
374+
| _ when ParsetreeViewer.has_await_attribute expr -> Parenthesized
383375
| {
384376
Parsetree.pexp_desc =
385377
( Pexp_ident _ | Pexp_constant _ | Pexp_field _ | Pexp_construct _

compiler/syntax/src/res_parsetree_viewer.ml

+10-1
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,22 @@ let functor_type modtype =
6565
in
6666
process [] modtype
6767

68-
let has_await_attribute attrs =
68+
let has_await_attribute2 attrs =
6969
List.exists
7070
(function
7171
| {Location.txt = "res.await"}, _ -> true
7272
| _ -> false)
7373
attrs
7474

75+
let has_await_attribute e =
76+
(match e.pexp_desc with
77+
| Pexp_await _ -> true
78+
| _ -> false)
79+
|| List.exists
80+
(function
81+
| {Location.txt = "res.await"}, _ -> true
82+
| _ -> false)
83+
e.pexp_attributes
7584
let has_res_pat_variant_spread_attribute attrs =
7685
List.exists
7786
(function

compiler/syntax/src/res_parsetree_viewer.mli

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ val functor_type :
1414
list
1515
* Parsetree.module_type
1616

17-
val has_await_attribute : Parsetree.attributes -> bool
17+
val has_await_attribute : Parsetree.expression -> bool
18+
val has_await_attribute2 : Parsetree.attributes -> bool
1819
val has_res_pat_variant_spread_attribute : Parsetree.attributes -> bool
1920
val has_dict_pattern_attribute : Parsetree.attributes -> bool
2021

compiler/syntax/src/res_printer.ml

+30-5
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ and print_module_binding ~state ~is_rec module_binding cmt_tbl i =
674674
match module_binding.pmb_expr with
675675
| {pmod_desc = Pmod_constraint (mod_expr, mod_type)}
676676
when not
677-
(ParsetreeViewer.has_await_attribute
677+
(ParsetreeViewer.has_await_attribute2
678678
module_binding.pmb_expr.pmod_attributes) ->
679679
( print_mod_expr ~state mod_expr cmt_tbl,
680680
Doc.concat [Doc.text ": "; print_mod_type ~state mod_type cmt_tbl] )
@@ -3384,9 +3384,31 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
33843384
Doc.concat [Doc.text "\""; member_doc; Doc.text "\""]
33853385
in
33863386
Doc.group (Doc.concat [parent_doc; Doc.lbracket; member; Doc.rbracket])
3387+
| Pexp_await e ->
3388+
let printed_expression =
3389+
print_expression_with_comments ~state e cmt_tbl
3390+
in
3391+
let rhs =
3392+
match
3393+
Parens.lazy_or_assert_or_await_expr_rhs ~in_await:true
3394+
{
3395+
e with
3396+
pexp_attributes =
3397+
List.filter
3398+
(function
3399+
| {Location.txt = "res.braces" | "ns.braces"}, _ -> false
3400+
| _ -> true)
3401+
e.pexp_attributes;
3402+
}
3403+
with
3404+
| Parens.Parenthesized -> add_parens printed_expression
3405+
| Braced braces -> print_braces printed_expression e braces
3406+
| Nothing -> printed_expression
3407+
in
3408+
Doc.concat [Doc.text "await "; rhs]
33873409
in
33883410
let expr_with_await =
3389-
if ParsetreeViewer.has_await_attribute e.pexp_attributes then
3411+
if ParsetreeViewer.has_await_attribute2 e.pexp_attributes then
33903412
let rhs =
33913413
match
33923414
Parens.lazy_or_assert_or_await_expr_rhs ~in_await:true
@@ -3713,7 +3735,10 @@ and print_binary_expression ~state (expr : Parsetree.expression) cmt_tbl =
37133735
| _ -> add_parens doc
37143736
in
37153737
let is_await =
3716-
ParsetreeViewer.has_await_attribute expr.pexp_attributes
3738+
(match expr.pexp_desc with
3739+
| Pexp_await _ -> true
3740+
| _ -> false)
3741+
|| ParsetreeViewer.has_await_attribute expr
37173742
in
37183743
let doc =
37193744
if is_await then
@@ -5250,7 +5275,7 @@ and print_expression_block ~state ~braces expr cmt_tbl =
52505275
match mod_expr.pmod_desc with
52515276
| Pmod_constraint (mod_expr2, mod_type)
52525277
when not
5253-
(ParsetreeViewer.has_await_attribute mod_expr.pmod_attributes)
5278+
(ParsetreeViewer.has_await_attribute2 mod_expr.pmod_attributes)
52545279
->
52555280
let name =
52565281
Doc.concat
@@ -5744,7 +5769,7 @@ and print_mod_expr ~state mod_expr cmt_tbl =
57445769
| Pmod_functor _ -> print_mod_functor ~state mod_expr cmt_tbl
57455770
in
57465771
let doc =
5747-
if ParsetreeViewer.has_await_attribute mod_expr.pmod_attributes then
5772+
if ParsetreeViewer.has_await_attribute2 mod_expr.pmod_attributes then
57485773
match mod_expr.pmod_desc with
57495774
| Pmod_constraint _ ->
57505775
Doc.concat [Doc.text "await "; Doc.lparen; doc; Doc.rparen]

tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
let greetUser async [arity:1]userId =
2-
((let name = ((getUserName userId)[@res.await ]) in
2+
((let name = await (getUserName userId) in
33
({js|Hello |js} ++ name) ++ {js|!|js})
44
[@res.braces ])
55
;;async fun [arity:1]() -> 123
@@ -23,10 +23,10 @@ let f =
2323
[@res.ternary ])
2424
let foo = async ~a:34
2525
let bar async [arity:1]~a = a + 1
26-
let ex1 = ((3)[@res.await ]) + ((4)[@res.await ])
27-
let ex2 = ((3)[@res.await ]) ** ((4)[@res.await ])
28-
let ex3 = ((foo -> (bar ~arg))[@res.await ])
29-
let ex4 = (((foo.bar).baz)[@res.await ])
26+
let ex1 = (await 3) + (await 4)
27+
let ex2 = (await 3) ** (await 4)
28+
let ex3 = await (foo -> (bar ~arg))
29+
let ex4 = await ((foo.bar).baz)
3030
let attr1 = ((async fun [arity:1]x -> x + 1)[@a ])
3131
let attr2 = ((fun (type a) ->
3232
async fun [arity:1]() -> fun (type b) -> fun (type c) ->

0 commit comments

Comments
 (0)