Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

await AST node for expressions #7368

Merged
merged 5 commits into from
Apr 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- Remove `Stdlib_Char` module for now. https://github.com/rescript-lang/rescript/pull/7367
- Convert internal JavaScript codebase into ESM, ReScript package itself is now ESM (`"type": "module"`). https://github.com/rescript-lang/rescript/pull/6899
- Add built-in support for the JavaScript `in` operator. https://github.com/rescript-lang/rescript/pull/7342
- AST cleanup: add `Pexp_await` ast node instead of `res.await` attribute. (The attribute is still used for await on modules currently). https://github.com/rescript-lang/rescript/pull/7368

#### :nail_care: Polish

Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,19 +123,19 @@ After adding a new file to the repository that should go into the npm package -

```sh
make lib # Build compiler and standard library
./cli/bsc myTestFile.res
./cli/bsc.js myTestFile.res
```

To view the untyped tree of the file run:

```sh
./cli/bsc -dparsetree myTestFile.res
./cli/bsc.js -dparsetree myTestFile.res
```

To view the typed tree of the file run:

```sh
./cli/bsc -dtypedtree myTestFile.res
./cli/bsc.js -dtypedtree myTestFile.res
```

### Project
Expand Down
3 changes: 2 additions & 1 deletion analysis/src/CompletionFrontEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -312,11 +312,12 @@ let rec exprToContextPathInner ~(inJsxContext : bool) (e : Parsetree.expression)
if List.length exprs = List.length exprsAsContextPaths then
Some (CTuple exprsAsContextPaths)
else None
| Pexp_await e -> exprToContextPathInner ~inJsxContext e
| _ -> None

and exprToContextPath ~(inJsxContext : bool) (e : Parsetree.expression) =
match
( Res_parsetree_viewer.has_await_attribute e.pexp_attributes,
( Res_parsetree_viewer.expr_is_await e,
exprToContextPathInner ~inJsxContext e )
with
| true, Some ctxPath -> Some (CPAwait ctxPath)
Expand Down
1 change: 1 addition & 0 deletions analysis/src/Utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ let identifyPexp pexp =
| Pexp_pack _ -> "Pexp_pack"
| Pexp_extension _ -> "Pexp_extension"
| Pexp_open _ -> "Pexp_open"
| Pexp_await _ -> "Pexp_await"

let identifyPpat pat =
match pat with
Expand Down
1 change: 1 addition & 0 deletions compiler/frontend/bs_ast_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ module E = struct
| Pexp_open (ovf, lid, e) ->
open_ ~loc ~attrs ovf (map_loc sub lid) (sub.expr sub e)
| Pexp_extension x -> extension ~loc ~attrs (sub.extension sub x)
| Pexp_await e -> await ~loc ~attrs (sub.expr sub e)
end

module P = struct
Expand Down
10 changes: 6 additions & 4 deletions compiler/frontend/bs_builtin_ppx.ml
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,12 @@ let expr_mapper ~async_context ~in_function_def (self : mapper)
|| Ast_attributes.has_await_payload attrs2 ->
check_await ();
result
| _ when Ast_attributes.has_await_payload e.pexp_attributes ->
check_await ();
Ast_await.create_await_expression result
| _ -> result
| _ -> (
match result.pexp_desc with
| Pexp_await e ->
check_await ();
Ast_await.create_await_expression e
| _ -> result)

let typ_mapper (self : mapper) (typ : Parsetree.core_type) =
Ast_core_type_class_type.typ_mapper self typ
Expand Down
2 changes: 1 addition & 1 deletion compiler/ml/ast_helper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ module Exp = struct
let pack ?loc ?attrs a = mk ?loc ?attrs (Pexp_pack a)
let open_ ?loc ?attrs a b c = mk ?loc ?attrs (Pexp_open (a, b, c))
let extension ?loc ?attrs a = mk ?loc ?attrs (Pexp_extension a)

let await ?loc ?attrs a = mk ?loc ?attrs (Pexp_await a)
let case lhs ?guard rhs = {pc_lhs = lhs; pc_guard = guard; pc_rhs = rhs}
end

Expand Down
1 change: 1 addition & 0 deletions compiler/ml/ast_helper.mli
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ module Exp : sig
val extension : ?loc:loc -> ?attrs:attrs -> extension -> expression

val case : pattern -> ?guard:expression -> expression -> case
val await : ?loc:loc -> ?attrs:attrs -> expression -> expression
end

(** Value declarations *)
Expand Down
1 change: 1 addition & 0 deletions compiler/ml/ast_iterator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ module E = struct
iter_loc sub lid;
sub.expr sub e
| Pexp_extension x -> sub.extension sub x
| Pexp_await e -> sub.expr sub e
end

module P = struct
Expand Down
1 change: 1 addition & 0 deletions compiler/ml/ast_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ module E = struct
| Pexp_open (ovf, lid, e) ->
open_ ~loc ~attrs ovf (map_loc sub lid) (sub.expr sub e)
| Pexp_extension x -> extension ~loc ~attrs (sub.extension sub x)
| Pexp_await e -> await ~loc ~attrs (sub.expr sub e)
end

module P = struct
Expand Down
21 changes: 20 additions & 1 deletion compiler/ml/ast_mapper_from0.ml
Original file line number Diff line number Diff line change
Expand Up @@ -295,11 +295,30 @@ end
module E = struct
(* Value expressions for the core language *)

let map sub {pexp_loc = loc; pexp_desc = desc; pexp_attributes = attrs} =
let has_await_attribute attrs =
List.exists
(function
| {Location.txt = "res.await"}, _ -> true
| _ -> false)
attrs

let remove_await_attribute attrs =
List.filter
(function
| {Location.txt = "res.await"}, _ -> false
| _ -> true)
attrs

let map sub ({pexp_loc = loc; pexp_desc = desc; pexp_attributes = attrs} as e)
=
let open Exp in
let loc = sub.location sub loc in
let attrs = sub.attributes sub attrs in
match desc with
| _ when has_await_attribute attrs ->
let attrs = remove_await_attribute e.pexp_attributes in
let e = sub.expr sub {e with pexp_attributes = attrs} in
await ~loc e
| Pexp_ident x -> ident ~loc ~attrs (map_loc sub x)
| Pexp_constant x -> constant ~loc ~attrs (map_constant x)
| Pexp_let (r, vbs, e) ->
Expand Down
7 changes: 7 additions & 0 deletions compiler/ml/ast_mapper_to0.ml
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,13 @@ module E = struct
| Pexp_open (ovf, lid, e) ->
open_ ~loc ~attrs ovf (map_loc sub lid) (sub.expr sub e)
| Pexp_extension x -> extension ~loc ~attrs (sub.extension sub x)
| Pexp_await e ->
let e = sub.expr sub e in
{
e with
pexp_attributes =
(Location.mknoloc "res.await", Pt.PStr []) :: e.pexp_attributes;
}
end

module P = struct
Expand Down
5 changes: 0 additions & 5 deletions compiler/ml/ast_uncurried.ml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,3 @@ let expr_is_uncurried_fun (expr : Parsetree.expression) =
match expr.pexp_desc with
| Pexp_fun {arity = Some _} -> true
| _ -> false

let expr_extract_uncurried_fun (expr : Parsetree.expression) =
match expr.pexp_desc with
| Pexp_fun {arity = Some _} -> expr
| _ -> assert false
1 change: 1 addition & 0 deletions compiler/ml/depend.ml
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ let rec add_expr bv exp =
| Pstr_eval ({pexp_desc = Pexp_construct (c, None)}, _) -> add bv c
| _ -> handle_extension e)
| Pexp_extension e -> handle_extension e
| Pexp_await e -> add_expr bv e

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

Expand Down
5 changes: 3 additions & 2 deletions compiler/ml/parsetree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,9 @@ and expression_desc =
let open M in E
let! open M in E *)
| Pexp_extension of extension
(* [%id] *)
(* . *)
(* [%id] *)
(* . *)
| Pexp_await of expression

and case = {
(* (P -> E) or (P when E0 -> E) *)
Expand Down
1 change: 1 addition & 0 deletions compiler/ml/pprintast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ and expression ctxt f x =
(expression ctxt) e
| Pexp_variant (l, Some eo) -> pp f "@[<2>`%s@;%a@]" l (simple_expr ctxt) eo
| Pexp_extension e -> extension ctxt f e
| Pexp_await e -> pp f "@[<hov2>await@ %a@]" (simple_expr ctxt) e
| _ -> expression1 ctxt f x

and expression1 ctxt f x =
Expand Down
3 changes: 3 additions & 0 deletions compiler/ml/printast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,9 @@ and expression i ppf x =
| Pexp_extension (s, arg) ->
line i ppf "Pexp_extension \"%s\"\n" s.txt;
payload i ppf arg
| Pexp_await e ->
line i ppf "Pexp_await\n";
expression i ppf e

and value_description i ppf x =
line i ppf "value_description %a %a\n" fmt_string_loc x.pval_name fmt_location
Expand Down
2 changes: 2 additions & 0 deletions compiler/ml/typecore.ml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ let iter_expression f e =
expr e;
module_expr me
| Pexp_pack me -> module_expr me
| Pexp_await _ -> assert false (* should be handled earlier *)
and case {pc_lhs = _; pc_guard; pc_rhs} =
may expr pc_guard;
expr pc_rhs
Expand Down Expand Up @@ -3195,6 +3196,7 @@ and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp
| _ -> raise (Error (loc, env, Invalid_extension_constructor_payload)))
| Pexp_extension ext ->
raise (Error_forward (Builtin_attributes.error_of_extension ext))
| Pexp_await _ -> (* should be handled earlier *) assert false

and type_function ?in_function ~arity ~async loc attrs env ty_expected_ l
caselist =
Expand Down
1 change: 1 addition & 0 deletions compiler/syntax/src/res_ast_debugger.ml
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ module SexpAst = struct
]
| Pexp_extension ext ->
Sexp.list [Sexp.atom "Pexp_extension"; extension ext]
| Pexp_await e -> Sexp.list [Sexp.atom "Pexp_await"; expression e]
in
Sexp.list [Sexp.atom "expression"; desc]

Expand Down
9 changes: 3 additions & 6 deletions compiler/syntax/src/res_core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3307,15 +3307,12 @@ and parse_async_arrow_expression ?(arrow_attrs = []) p =

and parse_await_expression p =
let await_loc = mk_loc p.Parser.start_pos p.end_pos in
let await_attr = make_await_attr await_loc in
Parser.expect Await p;
let token_prec = Token.precedence MinusGreater in
let expr = parse_binary_expr ~context:OrdinaryExpr p token_prec in
{
expr with
pexp_attributes = await_attr :: expr.pexp_attributes;
pexp_loc = {expr.pexp_loc with loc_start = await_loc.loc_start};
}
Ast_helper.Exp.await
~loc:{expr.pexp_loc with loc_start = await_loc.loc_start}
~attrs:[] expr

and parse_try_expression p =
let start_pos = p.Parser.start_pos in
Expand Down
22 changes: 7 additions & 15 deletions compiler/syntax/src/res_parens.ml
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ let call_expr expr =
} ->
Parenthesized
| _ when Ast_uncurried.expr_is_uncurried_fun expr -> Parenthesized
| _ when ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
Parenthesized
| _ when ParsetreeViewer.expr_is_await expr -> Parenthesized
| _ -> Nothing)

let structure_expr expr =
Expand Down Expand Up @@ -109,8 +108,7 @@ let unary_expr_operand expr =
| Pexp_try _ | Pexp_while _ | Pexp_for _ | Pexp_ifthenelse _ );
} ->
Parenthesized
| _ when ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
Parenthesized
| _ when ParsetreeViewer.expr_is_await expr -> Parenthesized
| _ -> Nothing)

let binary_expr_operand ~is_lhs expr =
Expand All @@ -133,8 +131,7 @@ let binary_expr_operand ~is_lhs expr =
| expr when ParsetreeViewer.is_binary_expression expr -> Parenthesized
| expr when ParsetreeViewer.is_ternary_expr expr -> Parenthesized
| {pexp_desc = Pexp_lazy _ | Pexp_assert _} when is_lhs -> Parenthesized
| _ when ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
Parenthesized
| _ when ParsetreeViewer.expr_is_await expr -> Parenthesized
| {Parsetree.pexp_attributes = attrs} ->
if ParsetreeViewer.has_printable_attributes attrs then Parenthesized
else Nothing)
Expand Down Expand Up @@ -229,9 +226,7 @@ let lazy_or_assert_or_await_expr_rhs ?(in_await = false) expr =
| Pexp_while _ | Pexp_for _ | Pexp_ifthenelse _ );
} ->
Parenthesized
| _
when (not in_await)
&& ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
| _ when (not in_await) && ParsetreeViewer.expr_is_await expr ->
Parenthesized
| _ -> Nothing)

Expand Down Expand Up @@ -277,8 +272,7 @@ let field_expr expr =
| Pexp_try _ | Pexp_while _ | Pexp_for _ | Pexp_ifthenelse _ );
} ->
Parenthesized
| _ when ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
Parenthesized
| _ when ParsetreeViewer.expr_is_await expr -> Parenthesized
| _ -> Nothing)

let set_field_expr_rhs expr =
Expand Down Expand Up @@ -339,8 +333,7 @@ let jsx_prop_expr expr =
}
when starts_with_minus x ->
Parenthesized
| _ when ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
Parenthesized
| _ when ParsetreeViewer.expr_is_await expr -> Parenthesized
| {
Parsetree.pexp_desc =
( Pexp_ident _ | Pexp_constant _ | Pexp_field _ | Pexp_construct _
Expand Down Expand Up @@ -377,8 +370,7 @@ let jsx_child_expr expr =
}
when starts_with_minus x ->
Parenthesized
| _ when ParsetreeViewer.has_await_attribute expr.pexp_attributes ->
Parenthesized
| _ when ParsetreeViewer.expr_is_await expr -> Parenthesized
| {
Parsetree.pexp_desc =
( Pexp_ident _ | Pexp_constant _ | Pexp_field _ | Pexp_construct _
Expand Down
12 changes: 6 additions & 6 deletions compiler/syntax/src/res_parsetree_viewer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ let has_await_attribute attrs =
| _ -> false)
attrs

let expr_is_await e =
match e.pexp_desc with
| Pexp_await _ -> true
| _ -> false

let has_inline_record_definition_attribute attrs =
List.exists
(function
Expand Down Expand Up @@ -111,12 +116,7 @@ let collect_list_expressions expr =

(* (__x) => f(a, __x, c) -----> f(a, _, c) *)
let rewrite_underscore_apply expr =
let expr_fun =
if Ast_uncurried.expr_is_uncurried_fun expr then
Ast_uncurried.expr_extract_uncurried_fun expr
else expr
in
match expr_fun.pexp_desc with
match expr.pexp_desc with
| Pexp_fun
{
arg_label = Nolabel;
Expand Down
1 change: 1 addition & 0 deletions compiler/syntax/src/res_parsetree_viewer.mli
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ val functor_type :
list
* Parsetree.module_type

val expr_is_await : Parsetree.expression -> bool
val has_await_attribute : Parsetree.attributes -> bool
val has_inline_record_definition_attribute : Parsetree.attributes -> bool
val has_res_pat_variant_spread_attribute : Parsetree.attributes -> bool
Expand Down
Loading
Loading