support arrow function (#4385)

This commit is contained in:
Alex Lam S.L
2020-12-17 10:23:41 +00:00
committed by GitHub
parent 75e9fd8417
commit a96f087ac3
11 changed files with 732 additions and 117 deletions

View File

@@ -502,10 +502,9 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
}
}, AST_Scope);
var AST_Lambda = DEFNODE("Lambda", "name argnames length_read uses_arguments", {
var AST_Lambda = DEFNODE("Lambda", "argnames length_read uses_arguments", {
$documentation: "Base class for functions",
$propdoc: {
name: "[AST_SymbolDeclaration?] the name of this function",
argnames: "[(AST_Destructured|AST_SymbolFunarg)*] array of function arguments and/or destructured literals",
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array",
},
@@ -541,18 +540,49 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames length_read uses_arguments", {
}, AST_Scope);
var AST_Accessor = DEFNODE("Accessor", null, {
$documentation: "A setter/getter function. The `name` property is always null.",
$documentation: "A getter/setter function",
_validate: function() {
if (this.name != null) throw new Error("name must be null");
},
}, AST_Lambda);
function is_function(node) {
return node instanceof AST_AsyncFunction || node instanceof AST_Function;
return node instanceof AST_Arrow || node instanceof AST_AsyncFunction || node instanceof AST_Function;
}
var AST_AsyncFunction = DEFNODE("AsyncFunction", "inlined", {
var AST_Arrow = DEFNODE("Arrow", "inlined value", {
$documentation: "An arrow function expression",
$propdoc: {
value: "[AST_Node?] simple return expression, or null if using function body.",
},
walk: function(visitor) {
var node = this;
visitor.visit(node, function() {
node.argnames.forEach(function(argname) {
argname.walk(visitor);
});
if (node.value) {
node.value.walk(visitor);
} else {
walk_body(node, visitor);
}
});
},
_validate: function() {
if (this.name != null) throw new Error("name must be null");
if (this.uses_arguments) throw new Error("uses_arguments must be false");
if (this.value != null) {
must_be_expression(this, "value");
if (this.body.length) throw new Error("body must be empty if value exists");
}
},
}, AST_Lambda);
var AST_AsyncFunction = DEFNODE("AsyncFunction", "inlined name", {
$documentation: "An asynchronous function expression",
$propdoc: {
name: "[AST_SymbolLambda?] the name of this function",
},
_validate: function() {
if (this.name != null) {
if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda");
@@ -560,8 +590,11 @@ var AST_AsyncFunction = DEFNODE("AsyncFunction", "inlined", {
},
}, AST_Lambda);
var AST_Function = DEFNODE("Function", "inlined", {
var AST_Function = DEFNODE("Function", "inlined name", {
$documentation: "A function expression",
$propdoc: {
name: "[AST_SymbolLambda?] the name of this function",
},
_validate: function() {
if (this.name != null) {
if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda");
@@ -573,15 +606,21 @@ function is_defun(node) {
return node instanceof AST_AsyncDefun || node instanceof AST_Defun;
}
var AST_AsyncDefun = DEFNODE("AsyncDefun", "inlined", {
var AST_AsyncDefun = DEFNODE("AsyncDefun", "inlined name", {
$documentation: "An asynchronous function definition",
$propdoc: {
name: "[AST_SymbolDefun] the name of this function",
},
_validate: function() {
if (!(this.name instanceof AST_SymbolDefun)) throw new Error("name must be AST_SymbolDefun");
},
}, AST_Lambda);
var AST_Defun = DEFNODE("Defun", "inlined", {
var AST_Defun = DEFNODE("Defun", "inlined name", {
$documentation: "A function definition",
$propdoc: {
name: "[AST_SymbolDefun] the name of this function",
},
_validate: function() {
if (!(this.name instanceof AST_SymbolDefun)) throw new Error("name must be AST_SymbolDefun");
},