diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2020-12-05 21:19:31 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-06 05:19:31 +0800 |
commit | 1e4985ed9e0822118ad01313af09008af1e9f036 (patch) | |
tree | a30030887031071c32dce0a37841732fe8c66cf5 /lib/ast.js | |
parent | d2d56e301ecd8f6af056ccd355f940e11c851bd5 (diff) | |
download | tracifyjs-1e4985ed9e0822118ad01313af09008af1e9f036.tar.gz tracifyjs-1e4985ed9e0822118ad01313af09008af1e9f036.zip |
support spread syntax (#4328)
Diffstat (limited to 'lib/ast.js')
-rw-r--r-- | lib/ast.js | 32 |
1 files changed, 27 insertions, 5 deletions
@@ -209,6 +209,8 @@ var AST_EmptyStatement = DEFNODE("EmptyStatement", null, { 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)) { throw new Error(prop + " cannot be AST_Statement"); } @@ -817,9 +819,11 @@ var AST_VarDef = DEFNODE("VarDef", "name value", { /* -----[ OTHER ]----- */ -function must_be_expressions(node, prop) { +function must_be_expressions(node, prop, allow_spread, allow_hole) { node[prop].forEach(function(node) { 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)) { throw new Error(prop + " cannot contain AST_Statement"); } @@ -843,7 +847,7 @@ var AST_Call = DEFNODE("Call", "expression args pure", { }, _validate: function() { must_be_expression(this, "expression"); - must_be_expressions(this, "args"); + must_be_expressions(this, "args", true); }, }); @@ -920,6 +924,22 @@ var AST_Sub = DEFNODE("Sub", null, { }, }, AST_PropAccess); +var AST_Spread = DEFNODE("Spread", "expression", { + $documentation: "Spread expression in array/object literals or function calls", + $propdoc: { + expression: "[AST_Node] expression to be expanded", + }, + walk: function(visitor) { + var node = this; + visitor.visit(node, function() { + node.expression.walk(visitor); + }); + }, + _validate: function() { + must_be_expression(this, "expression"); + }, +}); + var AST_Unary = DEFNODE("Unary", "operator expression", { $documentation: "Base class for unary expressions", $propdoc: { @@ -1020,7 +1040,7 @@ var AST_Array = DEFNODE("Array", "elements", { }); }, _validate: function() { - must_be_expressions(this, "elements"); + must_be_expressions(this, "elements", true, true); }, }); @@ -1098,7 +1118,7 @@ var AST_DestructuredObject = DEFNODE("DestructuredObject", "properties", { var AST_Object = DEFNODE("Object", "properties", { $documentation: "An object literal", $propdoc: { - properties: "[AST_ObjectProperty*] array of properties" + properties: "[(AST_ObjectProperty|AST_Spread)*] array of properties" }, walk: function(visitor) { var node = this; @@ -1110,7 +1130,9 @@ var AST_Object = DEFNODE("Object", "properties", { }, _validate: function() { this.properties.forEach(function(node) { - if (!(node instanceof AST_ObjectProperty)) throw new Error("properties must be AST_ObjectProperty[]"); + if (!(node instanceof AST_ObjectProperty || node instanceof AST_Spread)) { + throw new Error("properties must contain AST_ObjectProperty and/or AST_Spread only"); + } }); }, }); |