Parse async do expressions (#13043)
* parse async do expressions * add test cases * update test fixtures * chore: add syntax-async-do-expressions * generater support * fix: do not transform async do expressions * chore: add asyncDoExpressions to missing plugin helpers * update ast types * add more test cases * throw when asyncDoExpressions is enabled but not doExpressions * avoid add parentheses for async do expressions * address review comments * chore: update parser typings
This commit is contained in:
committed by
Nicolò Ribaudo
parent
f30c99aa24
commit
28d7442aae
@@ -1033,6 +1033,8 @@ export default class ExpressionParser extends LValParser {
|
||||
);
|
||||
} else if (this.match(tt.name)) {
|
||||
return this.parseAsyncArrowUnaryFunction(id);
|
||||
} else if (this.match(tt._do)) {
|
||||
return this.parseDo(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1049,7 +1051,7 @@ export default class ExpressionParser extends LValParser {
|
||||
}
|
||||
|
||||
case tt._do: {
|
||||
return this.parseDo();
|
||||
return this.parseDo(false);
|
||||
}
|
||||
|
||||
case tt.regexp: {
|
||||
@@ -1231,13 +1233,27 @@ export default class ExpressionParser extends LValParser {
|
||||
}
|
||||
|
||||
// https://github.com/tc39/proposal-do-expressions
|
||||
parseDo(): N.DoExpression {
|
||||
// https://github.com/tc39/proposal-async-do-expressions
|
||||
parseDo(isAsync: boolean): N.DoExpression {
|
||||
this.expectPlugin("doExpressions");
|
||||
if (isAsync) {
|
||||
this.expectPlugin("asyncDoExpressions");
|
||||
}
|
||||
const node = this.startNode();
|
||||
node.async = isAsync;
|
||||
this.next(); // eat `do`
|
||||
const oldLabels = this.state.labels;
|
||||
this.state.labels = [];
|
||||
node.body = this.parseBlock();
|
||||
if (isAsync) {
|
||||
// AsyncDoExpression :
|
||||
// async [no LineTerminator here] do Block[~Yield, +Await, ~Return]
|
||||
this.prodParam.enter(PARAM_AWAIT);
|
||||
node.body = this.parseBlock();
|
||||
this.prodParam.exit();
|
||||
} else {
|
||||
node.body = this.parseBlock();
|
||||
}
|
||||
|
||||
this.state.labels = oldLabels;
|
||||
return this.finishNode(node, "DoExpression");
|
||||
}
|
||||
|
||||
@@ -117,6 +117,18 @@ export function validatePlugins(plugins: PluginList) {
|
||||
RECORD_AND_TUPLE_SYNTAX_TYPES.map(p => `'${p}'`).join(", "),
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
hasPlugin(plugins, "asyncDoExpressions") &&
|
||||
!hasPlugin(plugins, "doExpressions")
|
||||
) {
|
||||
const error = new Error(
|
||||
"'asyncDoExpressions' requires 'doExpressions', please add 'doExpressions' to parser plugins.",
|
||||
);
|
||||
// $FlowIgnore
|
||||
error.missingPlugins = "doExpressions"; // so @babel/core can provide better error message
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// These plugins are defined using a mixin which extends the parser class.
|
||||
|
||||
@@ -402,6 +402,7 @@ export type ArrayExpression = NodeBase & {
|
||||
export type DoExpression = NodeBase & {
|
||||
type: "DoExpression",
|
||||
body: ?BlockStatement,
|
||||
async: boolean,
|
||||
};
|
||||
|
||||
export type TupleExpression = NodeBase & {
|
||||
|
||||
Reference in New Issue
Block a user