support rest parameters (#4515)
This commit is contained in:
37
lib/ast.js
37
lib/ast.js
@@ -513,10 +513,11 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||
}
|
||||
}, AST_Scope);
|
||||
|
||||
var AST_Lambda = DEFNODE("Lambda", "argnames length_read uses_arguments", {
|
||||
var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest uses_arguments", {
|
||||
$documentation: "Base class for functions",
|
||||
$propdoc: {
|
||||
argnames: "[(AST_Destructured|AST_SymbolFunarg)*] array of function arguments and/or destructured literals",
|
||||
argnames: "[(AST_DefaultValue|AST_Destructured|AST_SymbolFunarg)*] array of function arguments and/or destructured literals",
|
||||
rest: "[(AST_Destructured|AST_SymbolFunarg)?] rest parameter, or null if absent",
|
||||
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array",
|
||||
},
|
||||
each_argname: function(visit) {
|
||||
@@ -534,6 +535,7 @@ var AST_Lambda = DEFNODE("Lambda", "argnames length_read uses_arguments", {
|
||||
this.argnames.forEach(function(argname) {
|
||||
argname.walk(tw);
|
||||
});
|
||||
if (this.rest) this.rest.walk(tw);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -542,6 +544,7 @@ var AST_Lambda = DEFNODE("Lambda", "argnames length_read uses_arguments", {
|
||||
node.argnames.forEach(function(argname) {
|
||||
argname.walk(visitor);
|
||||
});
|
||||
if (node.rest) node.rest.walk(visitor);
|
||||
walk_body(node, visitor);
|
||||
});
|
||||
},
|
||||
@@ -551,6 +554,9 @@ var AST_Lambda = DEFNODE("Lambda", "argnames length_read uses_arguments", {
|
||||
if (!(node instanceof AST_SymbolFunarg)) throw new Error("argnames must be AST_SymbolFunarg[]");
|
||||
}, true);
|
||||
});
|
||||
if (this.rest != null) validate_destructured(this.rest, function(node) {
|
||||
if (!(node instanceof AST_SymbolFunarg)) throw new Error("rest must be AST_SymbolFunarg");
|
||||
});
|
||||
},
|
||||
}, AST_Scope);
|
||||
|
||||
@@ -576,6 +582,7 @@ var AST_Arrow = DEFNODE("Arrow", "inlined value", {
|
||||
node.argnames.forEach(function(argname) {
|
||||
argname.walk(visitor);
|
||||
});
|
||||
if (node.rest) node.rest.walk(visitor);
|
||||
if (node.value) {
|
||||
node.value.walk(visitor);
|
||||
} else {
|
||||
@@ -1155,25 +1162,31 @@ var AST_Array = DEFNODE("Array", "elements", {
|
||||
},
|
||||
});
|
||||
|
||||
var AST_Destructured = DEFNODE("Destructured", null, {
|
||||
var AST_Destructured = DEFNODE("Destructured", "rest", {
|
||||
$documentation: "Base class for destructured literal",
|
||||
$propdoc: {
|
||||
rest: "[(AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)?] rest parameter, or null if absent",
|
||||
},
|
||||
});
|
||||
|
||||
function validate_destructured(node, check, allow_default) {
|
||||
if (node instanceof AST_DefaultValue && allow_default) return validate_destructured(node.name, check);
|
||||
if (node instanceof AST_DestructuredArray) return node.elements.forEach(function(node) {
|
||||
if (!(node instanceof AST_Hole)) validate_destructured(node, check, true);
|
||||
});
|
||||
if (node instanceof AST_DestructuredObject) return node.properties.forEach(function(prop) {
|
||||
validate_destructured(prop.value, check, true);
|
||||
});
|
||||
if (node instanceof AST_Destructured) {
|
||||
if (node.rest != null) validate_destructured(node.rest, check);
|
||||
if (node instanceof AST_DestructuredArray) return node.elements.forEach(function(node) {
|
||||
if (!(node instanceof AST_Hole)) validate_destructured(node, check, true);
|
||||
});
|
||||
if (node instanceof AST_DestructuredObject) return node.properties.forEach(function(prop) {
|
||||
validate_destructured(prop.value, check, true);
|
||||
});
|
||||
}
|
||||
check(node);
|
||||
}
|
||||
|
||||
var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", {
|
||||
$documentation: "A destructured array literal",
|
||||
$propdoc: {
|
||||
elements: "[AST_Node*] array of elements",
|
||||
elements: "[(AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)*] array of elements",
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1181,6 +1194,7 @@ var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", {
|
||||
node.elements.forEach(function(element) {
|
||||
element.walk(visitor);
|
||||
});
|
||||
if (node.rest) node.rest.walk(visitor);
|
||||
});
|
||||
},
|
||||
}, AST_Destructured);
|
||||
@@ -1189,7 +1203,7 @@ var AST_DestructuredKeyVal = DEFNODE("DestructuredKeyVal", "key value", {
|
||||
$documentation: "A key: value destructured property",
|
||||
$propdoc: {
|
||||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
||||
value: "[AST_Node] property value",
|
||||
value: "[AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef] property value",
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1218,6 +1232,7 @@ var AST_DestructuredObject = DEFNODE("DestructuredObject", "properties", {
|
||||
node.properties.forEach(function(prop) {
|
||||
prop.walk(visitor);
|
||||
});
|
||||
if (node.rest) node.rest.walk(visitor);
|
||||
});
|
||||
},
|
||||
_validate: function() {
|
||||
|
||||
Reference in New Issue
Block a user