Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit 269a0de

Browse files
author
Maxim
committed
Make await a keyword again.
Reasoning: In JavaScript `await` is a keyword *only* inside async functions. ```javascript let await = 1 // OK ✅ async function wait() { let await = 1 // NOT OK ❌ } ``` The plot twist is that the newer browsers (chrome or node) support top-level await. (By implicitly wrapping everything in an async function?) ```javascript let await = 1 // NOT OK, with top level await ❌ ``` This makes me think: * We can replicate JavaScript parser; inside async function expressions, use of `await` as identifier will result into a syntax error - Downside: this feels like a responsibility for another part of the compiler, not the parser? This is already implemented in cristianoc/rescript-compiler-experiments#1, so we would also be doing double work. - Other downside: if we ever allow top-level await, then we just implemented the above for nothing. * Allow `await` as a "non-keyword" everywhere with some "tricks". ```javascript let await = 1 let x = await // Ok, now it gets tricky. Does this start an "await"-expression? = await fetch(url) // could be this = await() // could be this = await await() // or even this = await // or we might just be assigning the identifier `await` to `x` ``` Seems like we can infer the following rules for an `await expression`: - space after `await` - next token is on the same line as `await` - next token indicates the start of a unary expression But this "breaks down" in the case of ```javascript let x = await - 1 // could be a binary expression: "identifier" MINUS "1" // could also be an await expression with a unary expression: `await` `(-1)` ``` These whitespace sensitive rules kinda feel super arbitrary. Which makes me think that introducing `await` as a keyword is an ok compromise.
1 parent 1d109fb commit 269a0de

File tree

3 files changed

+20
-28
lines changed

3 files changed

+20
-28
lines changed

src/res_core.ml

+10-21
Original file line numberDiff line numberDiff line change
@@ -2023,7 +2023,7 @@ and parseOperandExpr ~context p =
20232023
when isEs6ArrowExpression ~inTernary:(context = TernaryTrueBranchExpr) p
20242024
->
20252025
parseAsyncArrowExpression p
2026-
| Lident "await" -> parseAwaitExpression p
2026+
| Await -> parseAwaitExpression p
20272027
| Lazy ->
20282028
Parser.next p;
20292029
let expr = parseUnaryExpr p in
@@ -2751,13 +2751,6 @@ and parseBracedOrRecordExpr p =
27512751
let loc = mkLoc startPos p.prevEndPos in
27522752
let braces = makeBracesAttr loc in
27532753
{expr with pexp_attributes = braces :: expr.pexp_attributes}
2754-
| Lident "await" ->
2755-
let expr = parseAwaitExpression p in
2756-
let expr = parseExprBlock ~first:expr p in
2757-
Parser.expect Rbrace p;
2758-
let loc = mkLoc startPos p.prevEndPos in
2759-
let braces = makeBracesAttr loc in
2760-
{expr with pexp_attributes = braces :: expr.pexp_attributes}
27612754
| Uident _ | Lident _ -> (
27622755
let startToken = p.token in
27632756
let valueOrConstructor = parseValueOrConstructor p in
@@ -3130,19 +3123,15 @@ and parseAsyncArrowExpression p =
31303123
| _ -> assert false
31313124

31323125
and parseAwaitExpression p =
3133-
let startPos = p.Parser.startPos in
3134-
match p.token with
3135-
| Lident "await" ->
3136-
let awaitLoc = mkLoc startPos p.endPos in
3137-
let awaitAttr = (Location.mkloc "await" awaitLoc, Parsetree.PStr []) in
3138-
Parser.next p;
3139-
let expr = parseUnaryExpr p in
3140-
{
3141-
expr with
3142-
pexp_attributes = awaitAttr :: expr.pexp_attributes;
3143-
pexp_loc = {expr.pexp_loc with loc_start = awaitLoc.loc_start};
3144-
}
3145-
| _ -> assert false
3126+
let awaitLoc = mkLoc p.Parser.startPos p.endPos in
3127+
let awaitAttr = (Location.mkloc "await" awaitLoc, Parsetree.PStr []) in
3128+
Parser.expect Await p;
3129+
let expr = parseUnaryExpr p in
3130+
{
3131+
expr with
3132+
pexp_attributes = awaitAttr :: expr.pexp_attributes;
3133+
pexp_loc = {expr.pexp_loc with loc_start = awaitLoc.loc_start};
3134+
}
31463135

31473136
and parseTryExpression p =
31483137
let startPos = p.Parser.startPos in

src/res_grammar.ml

+4-4
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ let isExprStart = function
151151
| Underscore (* _ => doThings() *)
152152
| Uident _ | Lident _ | Hash | Lparen | List | Module | Lbracket | Lbrace
153153
| LessThan | Minus | MinusDot | Plus | PlusDot | Bang | Percent | At | If
154-
| Switch | While | For | Assert | Lazy | Try ->
154+
| Switch | While | For | Assert | Await | Lazy | Try ->
155155
true
156156
| _ -> false
157157

@@ -257,9 +257,9 @@ let isJsxChildStart = isAtomicExprStart
257257
let isBlockExprStart = function
258258
| Token.At | Hash | Percent | Minus | MinusDot | Plus | PlusDot | Bang | True
259259
| False | Float _ | Int _ | String _ | Codepoint _ | Lident _ | Uident _
260-
| Lparen | List | Lbracket | Lbrace | Forwardslash | Assert | Lazy | If | For
261-
| While | Switch | Open | Module | Exception | Let | LessThan | Backtick | Try
262-
| Underscore ->
260+
| Lparen | List | Lbracket | Lbrace | Forwardslash | Assert | Await | Lazy
261+
| If | For | While | Switch | Open | Module | Exception | Let | LessThan
262+
| Backtick | Try | Underscore ->
263263
true
264264
| _ -> false
265265

src/res_token.ml

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module Comment = Res_comment
22

33
type t =
4+
| Await
45
| Open
56
| True
67
| False
@@ -111,6 +112,7 @@ let precedence = function
111112
| _ -> 0
112113

113114
let toString = function
115+
| Await -> "await"
114116
| Open -> "open"
115117
| True -> "true"
116118
| False -> "false"
@@ -210,6 +212,7 @@ let keywordTable = function
210212
| "and" -> And
211213
| "as" -> As
212214
| "assert" -> Assert
215+
| "await" -> Await
213216
| "constraint" -> Constraint
214217
| "else" -> Else
215218
| "exception" -> Exception
@@ -238,9 +241,9 @@ let keywordTable = function
238241
[@@raises Not_found]
239242

240243
let isKeyword = function
241-
| And | As | Assert | Constraint | Else | Exception | External | False | For
242-
| If | In | Include | Land | Lazy | Let | List | Lor | Module | Mutable | Of
243-
| Open | Private | Rec | Switch | True | Try | Typ | When | While ->
244+
| Await | And | As | Assert | Constraint | Else | Exception | External | False
245+
| For | If | In | Include | Land | Lazy | Let | List | Lor | Module | Mutable
246+
| Of | Open | Private | Rec | Switch | True | Try | Typ | When | While ->
244247
true
245248
| _ -> false
246249

0 commit comments

Comments
 (0)