support async function (#4333)

This commit is contained in:
Alex Lam S.L
2020-12-06 21:22:40 +00:00
committed by GitHub
parent 3c384cf9a8
commit 2cbbf5c375
11 changed files with 434 additions and 62 deletions

View File

@@ -211,7 +211,7 @@ function must_be_expression(node, prop) {
if (!(node[prop] instanceof AST_Node)) throw new Error(prop + " must be AST_Node");
if (node[prop] instanceof AST_Hole) throw new Error(prop + " cannot be AST_Hole");
if (node[prop] instanceof AST_Spread) throw new Error(prop + " cannot be AST_Spread");
if (node[prop] instanceof AST_Statement && !(node[prop] instanceof AST_Function)) {
if (node[prop] instanceof AST_Statement && !is_function(node[prop])) {
throw new Error(prop + " cannot be AST_Statement");
}
}
@@ -280,7 +280,7 @@ var AST_Block = DEFNODE("Block", "body", {
_validate: function() {
this.body.forEach(function(node) {
if (!(node instanceof AST_Statement)) throw new Error("body must be AST_Statement[]");
if (node instanceof AST_Function) throw new Error("body cannot contain AST_Function");
if (is_function(node)) throw new Error("body cannot contain AST_Function");
});
},
}, AST_BlockScope);
@@ -296,7 +296,7 @@ var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {
},
_validate: function() {
if (!(this.body instanceof AST_Statement)) throw new Error("body must be AST_Statement");
if (this.body instanceof AST_Function) throw new Error("body cannot be AST_Function");
if (is_function(this.body)) throw new Error("body cannot be AST_Function");
},
}, AST_BlockScope);
@@ -390,7 +390,7 @@ var AST_For = DEFNODE("For", "init condition step", {
if (this.init != null) {
if (!(this.init instanceof AST_Node)) throw new Error("init must be AST_Node");
if (this.init instanceof AST_Statement
&& !(this.init instanceof AST_Definitions || this.init instanceof AST_Function)) {
&& !(this.init instanceof AST_Definitions || is_function(this.init))) {
throw new Error("init cannot be AST_Statement");
}
}
@@ -547,6 +547,19 @@ var AST_Accessor = DEFNODE("Accessor", null, {
},
}, AST_Lambda);
function is_function(node) {
return node instanceof AST_AsyncFunction || node instanceof AST_Function;
}
var AST_AsyncFunction = DEFNODE("AsyncFunction", null, {
$documentation: "An asynchronous function expression",
_validate: function() {
if (this.name != null) {
if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda");
}
},
}, AST_Lambda);
var AST_Function = DEFNODE("Function", "inlined", {
$documentation: "A function expression",
_validate: function() {
@@ -556,6 +569,13 @@ var AST_Function = DEFNODE("Function", "inlined", {
},
}, AST_Lambda);
var AST_AsyncDefun = DEFNODE("AsyncDefun", null, {
$documentation: "An asynchronous function definition",
_validate: function() {
if (!(this.name instanceof AST_SymbolDefun)) throw new Error("name must be AST_SymbolDefun");
},
}, AST_Lambda);
var AST_Defun = DEFNODE("Defun", "inlined", {
$documentation: "A function definition",
_validate: function() {
@@ -642,7 +662,7 @@ var AST_If = DEFNODE("If", "condition alternative", {
must_be_expression(this, "condition");
if (this.alternative != null) {
if (!(this.alternative instanceof AST_Statement)) throw new Error("alternative must be AST_Statement");
if (this.alternative instanceof AST_Function) throw new error("alternative cannot be AST_Function");
if (is_function(this.alternative)) throw new error("alternative cannot be AST_Function");
}
},
}, AST_StatementWithBody);
@@ -824,7 +844,7 @@ function must_be_expressions(node, prop, allow_spread, allow_hole) {
if (!(node instanceof AST_Node)) throw new Error(prop + " must be AST_Node[]");
if (!allow_hole && node instanceof AST_Hole) throw new Error(prop + " cannot be AST_Hole");
if (!allow_spread && node instanceof AST_Spread) throw new Error(prop + " cannot be AST_Spread");
if (node instanceof AST_Statement && !(node instanceof AST_Function)) {
if (node instanceof AST_Statement && !is_function(node)) {
throw new Error(prop + " cannot contain AST_Statement");
}
});
@@ -1024,6 +1044,22 @@ var AST_Assign = DEFNODE("Assign", null, {
},
}, AST_Binary);
var AST_Await = DEFNODE("Await", "expression", {
$documentation: "An await expression",
$propdoc: {
expression: "[AST_Node] expression with Promise to resolve on",
},
walk: function(visitor) {
var node = this;
visitor.visit(node, function() {
node.expression.walk(visitor);
});
},
_validate: function() {
must_be_expression(this, "expression");
},
});
/* -----[ LITERALS ]----- */
var AST_Array = DEFNODE("Array", "elements", {