1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/tests/js1_8_5/extensions/reflect-parse.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1205 @@ 1.4 +// |reftest| skip-if(!xulRuntime.shell) 1.5 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.6 +/* 1.7 + * Any copyright is dedicated to the Public Domain. 1.8 + * http://creativecommons.org/licenses/publicdomain/ 1.9 + */ 1.10 + 1.11 +(function runtest(main) { 1.12 + try { 1.13 + main(); 1.14 + } catch (exc) { 1.15 + print(exc.stack); 1.16 + throw exc; 1.17 + } 1.18 +})(function main() { 1.19 + 1.20 +var { Pattern, MatchError } = Match; 1.21 + 1.22 +var _ = Pattern.ANY; 1.23 + 1.24 +function program(elts) Pattern({ type: "Program", body: elts }) 1.25 +function exprStmt(expr) Pattern({ type: "ExpressionStatement", expression: expr }) 1.26 +function throwStmt(expr) Pattern({ type: "ThrowStatement", argument: expr }) 1.27 +function returnStmt(expr) Pattern({ type: "ReturnStatement", argument: expr }) 1.28 +function yieldExpr(expr) Pattern({ type: "YieldExpression", argument: expr }) 1.29 +function lit(val) Pattern({ type: "Literal", value: val }) 1.30 +function spread(val) Pattern({ type: "SpreadExpression", expression: val}) 1.31 +var thisExpr = Pattern({ type: "ThisExpression" }); 1.32 +function funDecl(id, params, body, defaults=[], rest=null) Pattern( 1.33 + { type: "FunctionDeclaration", 1.34 + id: id, 1.35 + params: params, 1.36 + defaults: defaults, 1.37 + body: body, 1.38 + rest: rest, 1.39 + generator: false }) 1.40 +function genFunDecl(id, params, body) Pattern({ type: "FunctionDeclaration", 1.41 + id: id, 1.42 + params: params, 1.43 + defaults: [], 1.44 + body: body, 1.45 + generator: true }) 1.46 +function varDecl(decls) Pattern({ type: "VariableDeclaration", declarations: decls, kind: "var" }) 1.47 +function letDecl(decls) Pattern({ type: "VariableDeclaration", declarations: decls, kind: "let" }) 1.48 +function constDecl(decls) Pattern({ type: "VariableDeclaration", declarations: decls, kind: "const" }) 1.49 +function ident(name) Pattern({ type: "Identifier", name: name }) 1.50 +function dotExpr(obj, id) Pattern({ type: "MemberExpression", computed: false, object: obj, property: id }) 1.51 +function memExpr(obj, id) Pattern({ type: "MemberExpression", computed: true, object: obj, property: id }) 1.52 +function forStmt(init, test, update, body) Pattern({ type: "ForStatement", init: init, test: test, update: update, body: body }) 1.53 +function forOfStmt(lhs, rhs, body) Pattern({ type: "ForOfStatement", left: lhs, right: rhs, body: body }) 1.54 +function forInStmt(lhs, rhs, body) Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: false }) 1.55 +function forEachInStmt(lhs, rhs, body) Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: true }) 1.56 +function breakStmt(lab) Pattern({ type: "BreakStatement", label: lab }) 1.57 +function continueStmt(lab) Pattern({ type: "ContinueStatement", label: lab }) 1.58 +function blockStmt(body) Pattern({ type: "BlockStatement", body: body }) 1.59 +var emptyStmt = Pattern({ type: "EmptyStatement" }) 1.60 +function ifStmt(test, cons, alt) Pattern({ type: "IfStatement", test: test, alternate: alt, consequent: cons }) 1.61 +function labStmt(lab, stmt) Pattern({ type: "LabeledStatement", label: lab, body: stmt }) 1.62 +function withStmt(obj, stmt) Pattern({ type: "WithStatement", object: obj, body: stmt }) 1.63 +function whileStmt(test, stmt) Pattern({ type: "WhileStatement", test: test, body: stmt }) 1.64 +function doStmt(stmt, test) Pattern({ type: "DoWhileStatement", test: test, body: stmt }) 1.65 +function switchStmt(disc, cases) Pattern({ type: "SwitchStatement", discriminant: disc, cases: cases }) 1.66 +function caseClause(test, stmts) Pattern({ type: "SwitchCase", test: test, consequent: stmts }) 1.67 +function defaultClause(stmts) Pattern({ type: "SwitchCase", test: null, consequent: stmts }) 1.68 +function catchClause(id, guard, body) Pattern({ type: "CatchClause", param: id, guard: guard, body: body }) 1.69 +function tryStmt(body, guarded, unguarded, fin) Pattern({ type: "TryStatement", block: body, guardedHandlers: guarded, handler: unguarded, finalizer: fin }) 1.70 +function letStmt(head, body) Pattern({ type: "LetStatement", head: head, body: body }) 1.71 +function funExpr(id, args, body, gen) Pattern({ type: "FunctionExpression", 1.72 + id: id, 1.73 + params: args, 1.74 + body: body, 1.75 + generator: false }) 1.76 +function genFunExpr(id, args, body) Pattern({ type: "FunctionExpression", 1.77 + id: id, 1.78 + params: args, 1.79 + body: body, 1.80 + generator: true }) 1.81 +function arrowExpr(args, body) Pattern({ type: "ArrowExpression", 1.82 + params: args, 1.83 + body: body }) 1.84 + 1.85 +function unExpr(op, arg) Pattern({ type: "UnaryExpression", operator: op, argument: arg }) 1.86 +function binExpr(op, left, right) Pattern({ type: "BinaryExpression", operator: op, left: left, right: right }) 1.87 +function aExpr(op, left, right) Pattern({ type: "AssignmentExpression", operator: op, left: left, right: right }) 1.88 +function updExpr(op, arg, prefix) Pattern({ type: "UpdateExpression", operator: op, argument: arg, prefix: prefix }) 1.89 +function logExpr(op, left, right) Pattern({ type: "LogicalExpression", operator: op, left: left, right: right }) 1.90 + 1.91 +function condExpr(test, cons, alt) Pattern({ type: "ConditionalExpression", test: test, consequent: cons, alternate: alt }) 1.92 +function seqExpr(exprs) Pattern({ type: "SequenceExpression", expressions: exprs }) 1.93 +function newExpr(callee, args) Pattern({ type: "NewExpression", callee: callee, arguments: args }) 1.94 +function callExpr(callee, args) Pattern({ type: "CallExpression", callee: callee, arguments: args }) 1.95 +function arrExpr(elts) Pattern({ type: "ArrayExpression", elements: elts }) 1.96 +function objExpr(elts) Pattern({ type: "ObjectExpression", properties: elts }) 1.97 +function compExpr(body, blocks, filter) Pattern({ type: "ComprehensionExpression", body: body, blocks: blocks, filter: filter }) 1.98 +function genExpr(body, blocks, filter) Pattern({ type: "GeneratorExpression", body: body, blocks: blocks, filter: filter }) 1.99 +function graphExpr(idx, body) Pattern({ type: "GraphExpression", index: idx, expression: body }) 1.100 +function letExpr(head, body) Pattern({ type: "LetExpression", head: head, body: body }) 1.101 +function idxExpr(idx) Pattern({ type: "GraphIndexExpression", index: idx }) 1.102 + 1.103 +function compBlock(left, right) Pattern({ type: "ComprehensionBlock", left: left, right: right, each: false, of: false }) 1.104 +function compEachBlock(left, right) Pattern({ type: "ComprehensionBlock", left: left, right: right, each: true, of: false }) 1.105 +function compOfBlock(left, right) Pattern({ type: "ComprehensionBlock", left: left, right: right, each: false, of: true }) 1.106 + 1.107 +function arrPatt(elts) Pattern({ type: "ArrayPattern", elements: elts }) 1.108 +function objPatt(elts) Pattern({ type: "ObjectPattern", properties: elts }) 1.109 + 1.110 +function localSrc(src) "(function(){ " + src + " })" 1.111 +function localPatt(patt) program([exprStmt(funExpr(null, [], blockStmt([patt])))]) 1.112 +function blockSrc(src) "(function(){ { " + src + " } })" 1.113 +function blockPatt(patt) program([exprStmt(funExpr(null, [], blockStmt([blockStmt([patt])])))]) 1.114 + 1.115 +function assertBlockStmt(src, patt) { 1.116 + blockPatt(patt).assert(Reflect.parse(blockSrc(src))); 1.117 +} 1.118 + 1.119 +function assertBlockExpr(src, patt) { 1.120 + assertBlockStmt(src, exprStmt(patt)); 1.121 +} 1.122 + 1.123 +function assertBlockDecl(src, patt, builder) { 1.124 + blockPatt(patt).assert(Reflect.parse(blockSrc(src), {builder: builder})); 1.125 +} 1.126 + 1.127 +function assertLocalStmt(src, patt) { 1.128 + localPatt(patt).assert(Reflect.parse(localSrc(src))); 1.129 +} 1.130 + 1.131 +function assertLocalExpr(src, patt) { 1.132 + assertLocalStmt(src, exprStmt(patt)); 1.133 +} 1.134 + 1.135 +function assertLocalDecl(src, patt) { 1.136 + localPatt(patt).assert(Reflect.parse(localSrc(src))); 1.137 +} 1.138 + 1.139 +function assertGlobalStmt(src, patt, builder) { 1.140 + program([patt]).assert(Reflect.parse(src, {builder: builder})); 1.141 +} 1.142 + 1.143 +function assertGlobalExpr(src, patt, builder) { 1.144 + program([exprStmt(patt)]).assert(Reflect.parse(src, {builder: builder})); 1.145 + //assertStmt(src, exprStmt(patt)); 1.146 +} 1.147 + 1.148 +function assertGlobalDecl(src, patt) { 1.149 + program([patt]).assert(Reflect.parse(src)); 1.150 +} 1.151 + 1.152 +function assertProg(src, patt) { 1.153 + program(patt).assert(Reflect.parse(src)); 1.154 +} 1.155 + 1.156 +function assertStmt(src, patt) { 1.157 + assertLocalStmt(src, patt); 1.158 + assertGlobalStmt(src, patt); 1.159 + assertBlockStmt(src, patt); 1.160 +} 1.161 + 1.162 +function assertExpr(src, patt) { 1.163 + assertLocalExpr(src, patt); 1.164 + assertGlobalExpr(src, patt); 1.165 + assertBlockExpr(src, patt); 1.166 +} 1.167 + 1.168 +function assertDecl(src, patt) { 1.169 + assertLocalDecl(src, patt); 1.170 + assertGlobalDecl(src, patt); 1.171 + assertBlockDecl(src, patt); 1.172 +} 1.173 + 1.174 +function assertError(src, errorType) { 1.175 + try { 1.176 + Reflect.parse(src); 1.177 + } catch (expected if expected instanceof errorType) { 1.178 + return; 1.179 + } 1.180 + throw new Error("expected " + errorType.name + " for " + uneval(src)); 1.181 +} 1.182 + 1.183 + 1.184 +// general tests 1.185 + 1.186 +// NB: These are useful but for now jit-test doesn't do I/O reliably. 1.187 + 1.188 +//program(_).assert(Reflect.parse(snarf('data/flapjax.txt'))); 1.189 +//program(_).assert(Reflect.parse(snarf('data/jquery-1.4.2.txt'))); 1.190 +//program(_).assert(Reflect.parse(snarf('data/prototype.js'))); 1.191 +//program(_).assert(Reflect.parse(snarf('data/dojo.js.uncompressed.js'))); 1.192 +//program(_).assert(Reflect.parse(snarf('data/mootools-1.2.4-core-nc.js'))); 1.193 + 1.194 + 1.195 +// declarations 1.196 + 1.197 +assertDecl("var x = 1, y = 2, z = 3", 1.198 + varDecl([{ id: ident("x"), init: lit(1) }, 1.199 + { id: ident("y"), init: lit(2) }, 1.200 + { id: ident("z"), init: lit(3) }])); 1.201 +assertDecl("var x, y, z", 1.202 + varDecl([{ id: ident("x"), init: null }, 1.203 + { id: ident("y"), init: null }, 1.204 + { id: ident("z"), init: null }])); 1.205 +assertDecl("function foo() { }", 1.206 + funDecl(ident("foo"), [], blockStmt([]))); 1.207 +assertDecl("function foo() { return 42 }", 1.208 + funDecl(ident("foo"), [], blockStmt([returnStmt(lit(42))]))); 1.209 + 1.210 +assertDecl("function foo(...rest) { }", 1.211 + funDecl(ident("foo"), [], blockStmt([]), [], ident("rest"))); 1.212 + 1.213 +assertDecl("function foo(a=4) { }", funDecl(ident("foo"), [ident("a")], blockStmt([]), [lit(4)])); 1.214 +assertDecl("function foo(a, b=4) { }", funDecl(ident("foo"), [ident("a"), ident("b")], blockStmt([]), [lit(4)])); 1.215 +assertDecl("function foo(a, b=4, ...rest) { }", 1.216 + funDecl(ident("foo"), [ident("a"), ident("b")], blockStmt([]), [lit(4)], ident("rest"))); 1.217 +assertDecl("function foo(a=(function () {})) { function a() {} }", 1.218 + funDecl(ident("foo"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))]), 1.219 + [funExpr(ident("a"), [], blockStmt([]))])); 1.220 + 1.221 + 1.222 +// Bug 591437: rebound args have their defs turned into uses 1.223 +assertDecl("function f(a) { function a() { } }", 1.224 + funDecl(ident("f"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))]))); 1.225 +assertDecl("function f(a,b,c) { function b() { } }", 1.226 + funDecl(ident("f"), [ident("a"),ident("b"),ident("c")], blockStmt([funDecl(ident("b"), [], blockStmt([]))]))); 1.227 +assertDecl("function f(a,[x,y]) { function a() { } }", 1.228 + funDecl(ident("f"), 1.229 + [ident("a"), arrPatt([ident("x"), ident("y")])], 1.230 + blockStmt([funDecl(ident("a"), [], blockStmt([]))]))); 1.231 + 1.232 +// Bug 632027: array holes should reflect as null 1.233 +assertExpr("[,]=[,]", aExpr("=", arrPatt([null]), arrExpr([null]))); 1.234 + 1.235 +// Bug 591450: this test currently crashes because of a bug in jsparse 1.236 +// assertDecl("function f(a,[x,y],b,[w,z],c) { function b() { } }", 1.237 +// funDecl(ident("f"), 1.238 +// [ident("a"), arrPatt([ident("x"), ident("y")]), ident("b"), arrPatt([ident("w"), ident("z")]), ident("c")], 1.239 +// blockStmt([funDecl(ident("b"), [], blockStmt([]))]))); 1.240 + 1.241 + 1.242 +// expressions 1.243 + 1.244 +assertExpr("true", lit(true)); 1.245 +assertExpr("false", lit(false)); 1.246 +assertExpr("42", lit(42)); 1.247 +assertExpr("(/asdf/)", lit(/asdf/)); 1.248 +assertExpr("this", thisExpr); 1.249 +assertExpr("foo", ident("foo")); 1.250 +assertExpr("foo.bar", dotExpr(ident("foo"), ident("bar"))); 1.251 +assertExpr("foo[bar]", memExpr(ident("foo"), ident("bar"))); 1.252 +assertExpr("foo['bar']", memExpr(ident("foo"), lit("bar"))); 1.253 +assertExpr("foo[42]", memExpr(ident("foo"), lit(42))); 1.254 +assertExpr("(function(){})", funExpr(null, [], blockStmt([]))); 1.255 +assertExpr("(function f() {})", funExpr(ident("f"), [], blockStmt([]))); 1.256 +assertExpr("(function f(x,y,z) {})", funExpr(ident("f"), [ident("x"),ident("y"),ident("z")], blockStmt([]))); 1.257 +assertExpr("a => a", arrowExpr([ident("a")], ident("a"))); 1.258 +assertExpr("(a) => a", arrowExpr([ident("a")], ident("a"))); 1.259 +assertExpr("a => b => a", arrowExpr([ident("a")], arrowExpr([ident("b")], ident("a")))); 1.260 +assertExpr("a => {}", arrowExpr([ident("a")], blockStmt([]))); 1.261 +assertExpr("a => ({})", arrowExpr([ident("a")], objExpr([]))); 1.262 +assertExpr("(a, b, c) => {}", arrowExpr([ident("a"), ident("b"), ident("c")], blockStmt([]))); 1.263 +assertExpr("([a, b]) => {}", arrowExpr([arrPatt([ident("a"), ident("b")])], blockStmt([]))); 1.264 +assertExpr("(++x)", updExpr("++", ident("x"), true)); 1.265 +assertExpr("(x++)", updExpr("++", ident("x"), false)); 1.266 +assertExpr("(+x)", unExpr("+", ident("x"))); 1.267 +assertExpr("(-x)", unExpr("-", ident("x"))); 1.268 +assertExpr("(!x)", unExpr("!", ident("x"))); 1.269 +assertExpr("(~x)", unExpr("~", ident("x"))); 1.270 +assertExpr("(delete x)", unExpr("delete", ident("x"))); 1.271 +assertExpr("(typeof x)", unExpr("typeof", ident("x"))); 1.272 +assertExpr("(void x)", unExpr("void", ident("x"))); 1.273 +assertExpr("(x == y)", binExpr("==", ident("x"), ident("y"))); 1.274 +assertExpr("(x != y)", binExpr("!=", ident("x"), ident("y"))); 1.275 +assertExpr("(x === y)", binExpr("===", ident("x"), ident("y"))); 1.276 +assertExpr("(x !== y)", binExpr("!==", ident("x"), ident("y"))); 1.277 +assertExpr("(x < y)", binExpr("<", ident("x"), ident("y"))); 1.278 +assertExpr("(x <= y)", binExpr("<=", ident("x"), ident("y"))); 1.279 +assertExpr("(x > y)", binExpr(">", ident("x"), ident("y"))); 1.280 +assertExpr("(x >= y)", binExpr(">=", ident("x"), ident("y"))); 1.281 +assertExpr("(x << y)", binExpr("<<", ident("x"), ident("y"))); 1.282 +assertExpr("(x >> y)", binExpr(">>", ident("x"), ident("y"))); 1.283 +assertExpr("(x >>> y)", binExpr(">>>", ident("x"), ident("y"))); 1.284 +assertExpr("(x + y)", binExpr("+", ident("x"), ident("y"))); 1.285 +assertExpr("(w + x + y + z)", binExpr("+", binExpr("+", binExpr("+", ident("w"), ident("x")), ident("y")), ident("z"))); 1.286 +assertExpr("(x - y)", binExpr("-", ident("x"), ident("y"))); 1.287 +assertExpr("(w - x - y - z)", binExpr("-", binExpr("-", binExpr("-", ident("w"), ident("x")), ident("y")), ident("z"))); 1.288 +assertExpr("(x * y)", binExpr("*", ident("x"), ident("y"))); 1.289 +assertExpr("(x / y)", binExpr("/", ident("x"), ident("y"))); 1.290 +assertExpr("(x % y)", binExpr("%", ident("x"), ident("y"))); 1.291 +assertExpr("(x | y)", binExpr("|", ident("x"), ident("y"))); 1.292 +assertExpr("(x ^ y)", binExpr("^", ident("x"), ident("y"))); 1.293 +assertExpr("(x & y)", binExpr("&", ident("x"), ident("y"))); 1.294 +assertExpr("(x in y)", binExpr("in", ident("x"), ident("y"))); 1.295 +assertExpr("(x instanceof y)", binExpr("instanceof", ident("x"), ident("y"))); 1.296 +assertExpr("(x = y)", aExpr("=", ident("x"), ident("y"))); 1.297 +assertExpr("(x += y)", aExpr("+=", ident("x"), ident("y"))); 1.298 +assertExpr("(x -= y)", aExpr("-=", ident("x"), ident("y"))); 1.299 +assertExpr("(x *= y)", aExpr("*=", ident("x"), ident("y"))); 1.300 +assertExpr("(x /= y)", aExpr("/=", ident("x"), ident("y"))); 1.301 +assertExpr("(x %= y)", aExpr("%=", ident("x"), ident("y"))); 1.302 +assertExpr("(x <<= y)", aExpr("<<=", ident("x"), ident("y"))); 1.303 +assertExpr("(x >>= y)", aExpr(">>=", ident("x"), ident("y"))); 1.304 +assertExpr("(x >>>= y)", aExpr(">>>=", ident("x"), ident("y"))); 1.305 +assertExpr("(x |= y)", aExpr("|=", ident("x"), ident("y"))); 1.306 +assertExpr("(x ^= y)", aExpr("^=", ident("x"), ident("y"))); 1.307 +assertExpr("(x &= y)", aExpr("&=", ident("x"), ident("y"))); 1.308 +assertExpr("(x || y)", logExpr("||", ident("x"), ident("y"))); 1.309 +assertExpr("(x && y)", logExpr("&&", ident("x"), ident("y"))); 1.310 +assertExpr("(w || x || y || z)", logExpr("||", logExpr("||", logExpr("||", ident("w"), ident("x")), ident("y")), ident("z"))) 1.311 +assertExpr("(x ? y : z)", condExpr(ident("x"), ident("y"), ident("z"))); 1.312 +assertExpr("(x,y)", seqExpr([ident("x"),ident("y")])) 1.313 +assertExpr("(x,y,z)", seqExpr([ident("x"),ident("y"),ident("z")])) 1.314 +assertExpr("(a,b,c,d,e,f,g)", seqExpr([ident("a"),ident("b"),ident("c"),ident("d"),ident("e"),ident("f"),ident("g")])); 1.315 +assertExpr("(new Object)", newExpr(ident("Object"), [])); 1.316 +assertExpr("(new Object())", newExpr(ident("Object"), [])); 1.317 +assertExpr("(new Object(42))", newExpr(ident("Object"), [lit(42)])); 1.318 +assertExpr("(new Object(1,2,3))", newExpr(ident("Object"), [lit(1),lit(2),lit(3)])); 1.319 +assertExpr("(String())", callExpr(ident("String"), [])); 1.320 +assertExpr("(String(42))", callExpr(ident("String"), [lit(42)])); 1.321 +assertExpr("(String(1,2,3))", callExpr(ident("String"), [lit(1),lit(2),lit(3)])); 1.322 +assertExpr("[]", arrExpr([])); 1.323 +assertExpr("[1]", arrExpr([lit(1)])); 1.324 +assertExpr("[1,2]", arrExpr([lit(1),lit(2)])); 1.325 +assertExpr("[1,2,3]", arrExpr([lit(1),lit(2),lit(3)])); 1.326 +assertExpr("[1,,2,3]", arrExpr([lit(1),null,lit(2),lit(3)])); 1.327 +assertExpr("[1,,,2,3]", arrExpr([lit(1),null,null,lit(2),lit(3)])); 1.328 +assertExpr("[1,,,2,,3]", arrExpr([lit(1),null,null,lit(2),null,lit(3)])); 1.329 +assertExpr("[1,,,2,,,3]", arrExpr([lit(1),null,null,lit(2),null,null,lit(3)])); 1.330 +assertExpr("[,1,2,3]", arrExpr([null,lit(1),lit(2),lit(3)])); 1.331 +assertExpr("[,,1,2,3]", arrExpr([null,null,lit(1),lit(2),lit(3)])); 1.332 +assertExpr("[,,,1,2,3]", arrExpr([null,null,null,lit(1),lit(2),lit(3)])); 1.333 +assertExpr("[,,,1,2,3,]", arrExpr([null,null,null,lit(1),lit(2),lit(3)])); 1.334 +assertExpr("[,,,1,2,3,,]", arrExpr([null,null,null,lit(1),lit(2),lit(3),null])); 1.335 +assertExpr("[,,,1,2,3,,,]", arrExpr([null,null,null,lit(1),lit(2),lit(3),null,null])); 1.336 +assertExpr("[,,,,,]", arrExpr([null,null,null,null,null])); 1.337 +assertExpr("[1, ...a, 2]", arrExpr([lit(1), spread(ident("a")), lit(2)])); 1.338 +assertExpr("[,, ...a,, ...b, 42]", arrExpr([null,null, spread(ident("a")),, spread(ident("b")), lit(42)])); 1.339 +assertExpr("[1,(2,3)]", arrExpr([lit(1),seqExpr([lit(2),lit(3)])])); 1.340 +assertExpr("[,(2,3)]", arrExpr([null,seqExpr([lit(2),lit(3)])])); 1.341 +assertExpr("({})", objExpr([])); 1.342 +assertExpr("({x:1})", objExpr([{ key: ident("x"), value: lit(1) }])); 1.343 +assertExpr("({x:1, y:2})", objExpr([{ key: ident("x"), value: lit(1) }, 1.344 + { key: ident("y"), value: lit(2) } ])); 1.345 +assertExpr("({x:1, y:2, z:3})", objExpr([{ key: ident("x"), value: lit(1) }, 1.346 + { key: ident("y"), value: lit(2) }, 1.347 + { key: ident("z"), value: lit(3) } ])); 1.348 +assertExpr("({x:1, 'y':2, z:3})", objExpr([{ key: ident("x"), value: lit(1) }, 1.349 + { key: lit("y"), value: lit(2) }, 1.350 + { key: ident("z"), value: lit(3) } ])); 1.351 +assertExpr("({'x':1, 'y':2, z:3})", objExpr([{ key: lit("x"), value: lit(1) }, 1.352 + { key: lit("y"), value: lit(2) }, 1.353 + { key: ident("z"), value: lit(3) } ])); 1.354 +assertExpr("({'x':1, 'y':2, 3:3})", objExpr([{ key: lit("x"), value: lit(1) }, 1.355 + { key: lit("y"), value: lit(2) }, 1.356 + { key: lit(3), value: lit(3) } ])); 1.357 + 1.358 +// Bug 571617: eliminate constant-folding 1.359 +assertExpr("2 + 3", binExpr("+", lit(2), lit(3))); 1.360 + 1.361 +// Bug 632026: constant-folding 1.362 +assertExpr("typeof(0?0:a)", unExpr("typeof", condExpr(lit(0), lit(0), ident("a")))); 1.363 + 1.364 +// Bug 632029: constant-folding 1.365 +assertExpr("[x for each (x in y) if (false)]", compExpr(ident("x"), [compEachBlock(ident("x"), ident("y"))], lit(false))); 1.366 + 1.367 +// Bug 632056: constant-folding 1.368 +program([exprStmt(ident("f")), 1.369 + ifStmt(lit(1), 1.370 + funDecl(ident("f"), [], blockStmt([])), 1.371 + null)]).assert(Reflect.parse("f; if (1) function f(){}")); 1.372 + 1.373 +// statements 1.374 + 1.375 +assertStmt("throw 42", throwStmt(lit(42))); 1.376 +assertStmt("for (;;) break", forStmt(null, null, null, breakStmt(null))); 1.377 +assertStmt("for (x; y; z) break", forStmt(ident("x"), ident("y"), ident("z"), breakStmt(null))); 1.378 +assertStmt("for (var x; y; z) break", forStmt(varDecl([{ id: ident("x"), init: null }]), ident("y"), ident("z"))); 1.379 +assertStmt("for (var x = 42; y; z) break", forStmt(varDecl([{ id: ident("x"), init: lit(42) }]), ident("y"), ident("z"))); 1.380 +assertStmt("for (x; ; z) break", forStmt(ident("x"), null, ident("z"), breakStmt(null))); 1.381 +assertStmt("for (var x; ; z) break", forStmt(varDecl([{ id: ident("x"), init: null }]), null, ident("z"))); 1.382 +assertStmt("for (var x = 42; ; z) break", forStmt(varDecl([{ id: ident("x"), init: lit(42) }]), null, ident("z"))); 1.383 +assertStmt("for (x; y; ) break", forStmt(ident("x"), ident("y"), null, breakStmt(null))); 1.384 +assertStmt("for (var x; y; ) break", forStmt(varDecl([{ id: ident("x"), init: null }]), ident("y"), null, breakStmt(null))); 1.385 +assertStmt("for (var x = 42; y; ) break", forStmt(varDecl([{ id: ident("x"), init: lit(42) }]), ident("y"), null, breakStmt(null))); 1.386 +assertStmt("for (var x in y) break", forInStmt(varDecl([{ id: ident("x"), init: null }]), ident("y"), breakStmt(null))); 1.387 +assertStmt("for (x in y) break", forInStmt(ident("x"), ident("y"), breakStmt(null))); 1.388 +assertStmt("{ }", blockStmt([])); 1.389 +assertStmt("{ throw 1; throw 2; throw 3; }", blockStmt([ throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))])); 1.390 +assertStmt(";", emptyStmt); 1.391 +assertStmt("if (foo) throw 42;", ifStmt(ident("foo"), throwStmt(lit(42)), null)); 1.392 +assertStmt("if (foo) throw 42; else true;", ifStmt(ident("foo"), throwStmt(lit(42)), exprStmt(lit(true)))); 1.393 +assertStmt("if (foo) { throw 1; throw 2; throw 3; }", 1.394 + ifStmt(ident("foo"), 1.395 + blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]), 1.396 + null)); 1.397 +assertStmt("if (foo) { throw 1; throw 2; throw 3; } else true;", 1.398 + ifStmt(ident("foo"), 1.399 + blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]), 1.400 + exprStmt(lit(true)))); 1.401 +assertStmt("foo: for(;;) break foo;", labStmt(ident("foo"), forStmt(null, null, null, breakStmt(ident("foo"))))); 1.402 +assertStmt("foo: for(;;) continue foo;", labStmt(ident("foo"), forStmt(null, null, null, continueStmt(ident("foo"))))); 1.403 +assertStmt("with (obj) { }", withStmt(ident("obj"), blockStmt([]))); 1.404 +assertStmt("with (obj) { obj; }", withStmt(ident("obj"), blockStmt([exprStmt(ident("obj"))]))); 1.405 +assertStmt("while (foo) { }", whileStmt(ident("foo"), blockStmt([]))); 1.406 +assertStmt("while (foo) { foo; }", whileStmt(ident("foo"), blockStmt([exprStmt(ident("foo"))]))); 1.407 +assertStmt("do { } while (foo);", doStmt(blockStmt([]), ident("foo"))); 1.408 +assertStmt("do { foo; } while (foo)", doStmt(blockStmt([exprStmt(ident("foo"))]), ident("foo"))); 1.409 +assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; }", 1.410 + switchStmt(ident("foo"), 1.411 + [ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]), 1.412 + caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]), 1.413 + defaultClause([ exprStmt(lit(3)) ]) ])); 1.414 +assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; case 42: 42; }", 1.415 + switchStmt(ident("foo"), 1.416 + [ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]), 1.417 + caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]), 1.418 + defaultClause([ exprStmt(lit(3)) ]), 1.419 + caseClause(lit(42), [ exprStmt(lit(42)) ]) ])); 1.420 +assertStmt("try { } catch (e) { }", 1.421 + tryStmt(blockStmt([]), 1.422 + [], 1.423 + catchClause(ident("e"), null, blockStmt([])), 1.424 + null)); 1.425 +assertStmt("try { } catch (e) { } finally { }", 1.426 + tryStmt(blockStmt([]), 1.427 + [], 1.428 + catchClause(ident("e"), null, blockStmt([])), 1.429 + blockStmt([]))); 1.430 +assertStmt("try { } finally { }", 1.431 + tryStmt(blockStmt([]), 1.432 + [], 1.433 + null, 1.434 + blockStmt([]))); 1.435 +assertStmt("try { } catch (e if foo) { } catch (e if bar) { } finally { }", 1.436 + tryStmt(blockStmt([]), 1.437 + [ catchClause(ident("e"), ident("foo"), blockStmt([])), 1.438 + catchClause(ident("e"), ident("bar"), blockStmt([])) ], 1.439 + null, 1.440 + blockStmt([]))); 1.441 +assertStmt("try { } catch (e if foo) { } catch (e if bar) { } catch (e) { } finally { }", 1.442 + tryStmt(blockStmt([]), 1.443 + [ catchClause(ident("e"), ident("foo"), blockStmt([])), 1.444 + catchClause(ident("e"), ident("bar"), blockStmt([])) ], 1.445 + catchClause(ident("e"), null, blockStmt([])), 1.446 + blockStmt([]))); 1.447 + 1.448 +// Bug 632028: yield outside of a function should throw 1.449 +(function() { 1.450 + var threw = false; 1.451 + try { 1.452 + Reflect.parse("yield 0"); 1.453 + } catch (expected) { 1.454 + threw = true; 1.455 + } 1.456 + assertEq(threw, true); 1.457 +})(); 1.458 + 1.459 +// redeclarations (TOK_NAME nodes with lexdef) 1.460 + 1.461 +assertStmt("function f() { function g() { } function g() { } }", 1.462 + funDecl(ident("f"), [], blockStmt([emptyStmt, 1.463 + funDecl(ident("g"), [], blockStmt([]))]))); 1.464 + 1.465 +// Fails due to parser quirks (bug 638577) 1.466 +//assertStmt("function f() { function g() { } function g() { return 42 } }", 1.467 +// funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])), 1.468 +// funDecl(ident("g"), [], blockStmt([returnStmt(lit(42))]))]))); 1.469 + 1.470 +assertStmt("function f() { var x = 42; var x = 43; }", 1.471 + funDecl(ident("f"), [], blockStmt([varDecl([{ id: ident("x"), init: lit(42) }]), 1.472 + varDecl([{ id: ident("x"), init: lit(43) }])]))); 1.473 + 1.474 + 1.475 +assertDecl("var {x:y} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), 1.476 + init: ident("foo") }])); 1.477 + 1.478 +// Bug 632030: redeclarations between var and funargs, var and function 1.479 +assertStmt("function g(x) { var x }", 1.480 + funDecl(ident("g"), [ident("x")], blockStmt([varDecl[{ id: ident("x"), init: null }]]))); 1.481 +assertProg("f.p = 1; var f; f.p; function f(){}", 1.482 + [exprStmt(aExpr("=", dotExpr(ident("f"), ident("p")), lit(1))), 1.483 + varDecl([{ id: ident("f"), init: null }]), 1.484 + exprStmt(dotExpr(ident("f"), ident("p"))), 1.485 + funDecl(ident("f"), [], blockStmt([]))]); 1.486 + 1.487 +// global let is var 1.488 +assertGlobalDecl("let {x:y} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), 1.489 + init: ident("foo") }])); 1.490 +// function-global let is var 1.491 +assertLocalDecl("let {x:y} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), 1.492 + init: ident("foo") }])); 1.493 +// block-local let is let 1.494 +assertBlockDecl("let {x:y} = foo;", letDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), 1.495 + init: ident("foo") }])); 1.496 + 1.497 +assertDecl("const {x:y} = foo;", constDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), 1.498 + init: ident("foo") }])); 1.499 + 1.500 + 1.501 +// various combinations of identifiers and destructuring patterns: 1.502 +function makePatternCombinations(id, destr) 1.503 + [ 1.504 + [ id(1) ], 1.505 + [ id(1), id(2) ], 1.506 + [ id(1), id(2), id(3) ], 1.507 + [ id(1), id(2), id(3), id(4) ], 1.508 + [ id(1), id(2), id(3), id(4), id(5) ], 1.509 + 1.510 + [ destr(1) ], 1.511 + [ destr(1), destr(2) ], 1.512 + [ destr(1), destr(2), destr(3) ], 1.513 + [ destr(1), destr(2), destr(3), destr(4) ], 1.514 + [ destr(1), destr(2), destr(3), destr(4), destr(5) ], 1.515 + 1.516 + [ destr(1), id(2) ], 1.517 + 1.518 + [ destr(1), id(2), id(3) ], 1.519 + [ destr(1), id(2), id(3), id(4) ], 1.520 + [ destr(1), id(2), id(3), id(4), id(5) ], 1.521 + [ destr(1), id(2), id(3), id(4), destr(5) ], 1.522 + [ destr(1), id(2), id(3), destr(4) ], 1.523 + [ destr(1), id(2), id(3), destr(4), id(5) ], 1.524 + [ destr(1), id(2), id(3), destr(4), destr(5) ], 1.525 + 1.526 + [ destr(1), id(2), destr(3) ], 1.527 + [ destr(1), id(2), destr(3), id(4) ], 1.528 + [ destr(1), id(2), destr(3), id(4), id(5) ], 1.529 + [ destr(1), id(2), destr(3), id(4), destr(5) ], 1.530 + [ destr(1), id(2), destr(3), destr(4) ], 1.531 + [ destr(1), id(2), destr(3), destr(4), id(5) ], 1.532 + [ destr(1), id(2), destr(3), destr(4), destr(5) ], 1.533 + 1.534 + [ id(1), destr(2) ], 1.535 + 1.536 + [ id(1), destr(2), id(3) ], 1.537 + [ id(1), destr(2), id(3), id(4) ], 1.538 + [ id(1), destr(2), id(3), id(4), id(5) ], 1.539 + [ id(1), destr(2), id(3), id(4), destr(5) ], 1.540 + [ id(1), destr(2), id(3), destr(4) ], 1.541 + [ id(1), destr(2), id(3), destr(4), id(5) ], 1.542 + [ id(1), destr(2), id(3), destr(4), destr(5) ], 1.543 + 1.544 + [ id(1), destr(2), destr(3) ], 1.545 + [ id(1), destr(2), destr(3), id(4) ], 1.546 + [ id(1), destr(2), destr(3), id(4), id(5) ], 1.547 + [ id(1), destr(2), destr(3), id(4), destr(5) ], 1.548 + [ id(1), destr(2), destr(3), destr(4) ], 1.549 + [ id(1), destr(2), destr(3), destr(4), id(5) ], 1.550 + [ id(1), destr(2), destr(3), destr(4), destr(5) ] 1.551 + ] 1.552 + 1.553 +// destructuring function parameters 1.554 + 1.555 +function testParamPatternCombinations(makePattSrc, makePattPatt) { 1.556 + var pattSrcs = makePatternCombinations(function(n) ("x" + n), makePattSrc); 1.557 + var pattPatts = makePatternCombinations(function(n) (ident("x" + n)), makePattPatt); 1.558 + 1.559 + for (var i = 0; i < pattSrcs.length; i++) { 1.560 + function makeSrc(body) ("(function(" + pattSrcs[i].join(",") + ") " + body + ")") 1.561 + function makePatt(body) (funExpr(null, pattPatts[i], body)) 1.562 + 1.563 + // no upvars, block body 1.564 + assertExpr(makeSrc("{ }", makePatt(blockStmt([])))); 1.565 + // upvars, block body 1.566 + assertExpr(makeSrc("{ return [x1,x2,x3,x4,x5]; }"), 1.567 + makePatt(blockStmt([returnStmt(arrExpr([ident("x1"), ident("x2"), ident("x3"), ident("x4"), ident("x5")]))]))); 1.568 + // no upvars, expression body 1.569 + assertExpr(makeSrc("(0)"), makePatt(lit(0))); 1.570 + // upvars, expression body 1.571 + assertExpr(makeSrc("[x1,x2,x3,x4,x5]"), 1.572 + makePatt(arrExpr([ident("x1"), ident("x2"), ident("x3"), ident("x4"), ident("x5")]))); 1.573 + } 1.574 +} 1.575 + 1.576 +testParamPatternCombinations(function(n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "}"), 1.577 + function(n) (objPatt([{ key: ident("a" + n), value: ident("x" + n) }, 1.578 + { key: ident("b" + n), value: ident("y" + n) }, 1.579 + { key: ident("c" + n), value: ident("z" + n) }]))); 1.580 + 1.581 +testParamPatternCombinations(function(n) ("[x" + n + "," + "y" + n + "," + "z" + n + "]"), 1.582 + function(n) (arrPatt([ident("x" + n), ident("y" + n), ident("z" + n)]))); 1.583 + 1.584 + 1.585 +// destructuring variable declarations 1.586 + 1.587 +function testVarPatternCombinations(makePattSrc, makePattPatt) { 1.588 + var pattSrcs = makePatternCombinations(function(n) ("x" + n), makePattSrc); 1.589 + var pattPatts = makePatternCombinations(function(n) ({ id: ident("x" + n), init: null }), makePattPatt); 1.590 + 1.591 + for (var i = 0; i < pattSrcs.length; i++) { 1.592 + // variable declarations in blocks 1.593 + assertDecl("var " + pattSrcs[i].join(",") + ";", varDecl(pattPatts[i])); 1.594 + 1.595 + assertGlobalDecl("let " + pattSrcs[i].join(",") + ";", varDecl(pattPatts[i])); 1.596 + assertLocalDecl("let " + pattSrcs[i].join(",") + ";", varDecl(pattPatts[i])); 1.597 + assertBlockDecl("let " + pattSrcs[i].join(",") + ";", letDecl(pattPatts[i])); 1.598 + 1.599 + assertDecl("const " + pattSrcs[i].join(",") + ";", constDecl(pattPatts[i])); 1.600 + 1.601 + // variable declarations in for-loop heads 1.602 + assertStmt("for (var " + pattSrcs[i].join(",") + "; foo; bar);", 1.603 + forStmt(varDecl(pattPatts[i]), ident("foo"), ident("bar"), emptyStmt)); 1.604 + assertStmt("for (let " + pattSrcs[i].join(",") + "; foo; bar);", 1.605 + letStmt(pattPatts[i], forStmt(null, ident("foo"), ident("bar"), emptyStmt))); 1.606 + assertStmt("for (const " + pattSrcs[i].join(",") + "; foo; bar);", 1.607 + forStmt(constDecl(pattPatts[i]), ident("foo"), ident("bar"), emptyStmt)); 1.608 + } 1.609 +} 1.610 + 1.611 +testVarPatternCombinations(function (n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "} = 0"), 1.612 + function (n) ({ id: objPatt([{ key: ident("a" + n), value: ident("x" + n) }, 1.613 + { key: ident("b" + n), value: ident("y" + n) }, 1.614 + { key: ident("c" + n), value: ident("z" + n) }]), 1.615 + init: lit(0) })); 1.616 + 1.617 +testVarPatternCombinations(function(n) ("[x" + n + "," + "y" + n + "," + "z" + n + "] = 0"), 1.618 + function(n) ({ id: arrPatt([ident("x" + n), ident("y" + n), ident("z" + n)]), 1.619 + init: lit(0) })); 1.620 + 1.621 +// destructuring assignment 1.622 + 1.623 +function testAssignmentCombinations(makePattSrc, makePattPatt) { 1.624 + var pattSrcs = makePatternCombinations(function(n) ("x" + n + " = 0"), makePattSrc); 1.625 + var pattPatts = makePatternCombinations(function(n) (aExpr("=", ident("x" + n), lit(0))), makePattPatt); 1.626 + 1.627 + for (var i = 0; i < pattSrcs.length; i++) { 1.628 + var src = pattSrcs[i].join(","); 1.629 + var patt = pattPatts[i].length === 1 ? pattPatts[i][0] : seqExpr(pattPatts[i]); 1.630 + 1.631 + // assignment expression statement 1.632 + assertExpr("(" + src + ")", patt); 1.633 + 1.634 + // for-loop head assignment 1.635 + assertStmt("for (" + src + "; foo; bar);", 1.636 + forStmt(patt, ident("foo"), ident("bar"), emptyStmt)); 1.637 + } 1.638 +} 1.639 + 1.640 +testAssignmentCombinations(function (n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "} = 0"), 1.641 + function (n) (aExpr("=", 1.642 + objPatt([{ key: ident("a" + n), value: ident("x" + n) }, 1.643 + { key: ident("b" + n), value: ident("y" + n) }, 1.644 + { key: ident("c" + n), value: ident("z" + n) }]), 1.645 + lit(0)))); 1.646 + 1.647 + 1.648 +// destructuring in for-in and for-each-in loop heads 1.649 + 1.650 +var axbycz = objPatt([{ key: ident("a"), value: ident("x") }, 1.651 + { key: ident("b"), value: ident("y") }, 1.652 + { key: ident("c"), value: ident("z") }]); 1.653 +var xyz = arrPatt([ident("x"), ident("y"), ident("z")]); 1.654 + 1.655 +assertStmt("for (var {a:x,b:y,c:z} in foo);", forInStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); 1.656 +assertStmt("for (let {a:x,b:y,c:z} in foo);", forInStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); 1.657 +assertStmt("for ({a:x,b:y,c:z} in foo);", forInStmt(axbycz, ident("foo"), emptyStmt)); 1.658 +assertStmt("for (var [x,y,z] in foo);", forInStmt(varDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); 1.659 +assertStmt("for (let [x,y,z] in foo);", forInStmt(letDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); 1.660 +assertStmt("for ([x,y,z] in foo);", forInStmt(xyz, ident("foo"), emptyStmt)); 1.661 +assertStmt("for (var {a:x,b:y,c:z} of foo);", forOfStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); 1.662 +assertStmt("for (let {a:x,b:y,c:z} of foo);", forOfStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); 1.663 +assertStmt("for ({a:x,b:y,c:z} of foo);", forOfStmt(axbycz, ident("foo"), emptyStmt)); 1.664 +assertStmt("for (var [x,y,z] of foo);", forOfStmt(varDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); 1.665 +assertStmt("for (let [x,y,z] of foo);", forOfStmt(letDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); 1.666 +assertStmt("for ([x,y,z] of foo);", forOfStmt(xyz, ident("foo"), emptyStmt)); 1.667 +assertStmt("for each (var {a:x,b:y,c:z} in foo);", forEachInStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); 1.668 +assertStmt("for each (let {a:x,b:y,c:z} in foo);", forEachInStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); 1.669 +assertStmt("for each ({a:x,b:y,c:z} in foo);", forEachInStmt(axbycz, ident("foo"), emptyStmt)); 1.670 +assertStmt("for each (var [x,y,z] in foo);", forEachInStmt(varDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); 1.671 +assertStmt("for each (let [x,y,z] in foo);", forEachInStmt(letDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); 1.672 +assertStmt("for each ([x,y,z] in foo);", forEachInStmt(xyz, ident("foo"), emptyStmt)); 1.673 +assertError("for (const x in foo);", SyntaxError); 1.674 +assertError("for (const {a:x,b:y,c:z} in foo);", SyntaxError); 1.675 +assertError("for (const [x,y,z] in foo);", SyntaxError); 1.676 +assertError("for (const x of foo);", SyntaxError); 1.677 +assertError("for (const {a:x,b:y,c:z} of foo);", SyntaxError); 1.678 +assertError("for (const [x,y,z] of foo);", SyntaxError); 1.679 +assertError("for each (const x in foo);", SyntaxError); 1.680 +assertError("for each (const {a:x,b:y,c:z} in foo);", SyntaxError); 1.681 +assertError("for each (const [x,y,z] in foo);", SyntaxError); 1.682 + 1.683 +// destructuring in for-in and for-each-in loop heads with initializers 1.684 + 1.685 +assertStmt("for (var {a:x,b:y,c:z} = 22 in foo);", forInStmt(varDecl([{ id: axbycz, init: lit(22) }]), ident("foo"), emptyStmt)); 1.686 +assertStmt("for (var [x,y,z] = 22 in foo);", forInStmt(varDecl([{ id: xyz, init: lit(22) }]), ident("foo"), emptyStmt)); 1.687 +assertStmt("for each (var {a:x,b:y,c:z} = 22 in foo);", forEachInStmt(varDecl([{ id: axbycz, init: lit(22) }]), ident("foo"), emptyStmt)); 1.688 +assertStmt("for each (var [x,y,z] = 22 in foo);", forEachInStmt(varDecl([{ id: xyz, init: lit(22) }]), ident("foo"), emptyStmt)); 1.689 +assertError("for (x = 22 in foo);", SyntaxError); 1.690 +assertError("for ({a:x,b:y,c:z} = 22 in foo);", SyntaxError); 1.691 +assertError("for ([x,y,z] = 22 in foo);", SyntaxError); 1.692 +assertError("for (const x = 22 in foo);", SyntaxError); 1.693 +assertError("for (const {a:x,b:y,c:z} = 22 in foo);", SyntaxError); 1.694 +assertError("for (const [x,y,z] = 22 in foo);", SyntaxError); 1.695 +assertError("for each (const x = 22 in foo);", SyntaxError); 1.696 +assertError("for each (const {a:x,b:y,c:z} = 22 in foo);", SyntaxError); 1.697 +assertError("for each (const [x,y,z] = 22 in foo);", SyntaxError); 1.698 + 1.699 +// expression closures 1.700 + 1.701 +assertDecl("function inc(x) (x + 1)", funDecl(ident("inc"), [ident("x")], binExpr("+", ident("x"), lit(1)))); 1.702 +assertExpr("(function(x) (x+1))", funExpr(null, [ident("x")], binExpr("+"), ident("x"), lit(1))); 1.703 + 1.704 +// generators 1.705 + 1.706 +assertDecl("function gen(x) { yield }", genFunDecl(ident("gen"), [ident("x")], blockStmt([exprStmt(yieldExpr(null))]))); 1.707 +assertExpr("(function(x) { yield })", genFunExpr(null, [ident("x")], blockStmt([exprStmt(yieldExpr(null))]))); 1.708 +assertDecl("function gen(x) { yield 42 }", genFunDecl(ident("gen"), [ident("x")], blockStmt([exprStmt(yieldExpr(lit(42)))]))); 1.709 +assertExpr("(function(x) { yield 42 })", genFunExpr(null, [ident("x")], blockStmt([exprStmt(yieldExpr(lit(42)))]))); 1.710 + 1.711 +// getters and setters 1.712 + 1.713 +assertExpr("({ get x() { return 42 } })", 1.714 + objExpr([ { key: ident("x"), 1.715 + value: funExpr(null, [], blockStmt([returnStmt(lit(42))])), 1.716 + kind: "get" } ])); 1.717 +assertExpr("({ set x(v) { return 42 } })", 1.718 + objExpr([ { key: ident("x"), 1.719 + value: funExpr(null, [ident("v")], blockStmt([returnStmt(lit(42))])), 1.720 + kind: "set" } ])); 1.721 + 1.722 +// comprehensions 1.723 + 1.724 +assertExpr("[ x for (x in foo)]", 1.725 + compExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], null)); 1.726 +assertExpr("[ [x,y] for (x in foo) for (y in bar)]", 1.727 + compExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], null)); 1.728 +assertExpr("[ [x,y,z] for (x in foo) for (y in bar) for (z in baz)]", 1.729 + compExpr(arrExpr([ident("x"), ident("y"), ident("z")]), 1.730 + [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))], 1.731 + null)); 1.732 + 1.733 +assertExpr("[ x for (x in foo) if (p)]", 1.734 + compExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], ident("p"))); 1.735 +assertExpr("[ [x,y] for (x in foo) for (y in bar) if (p)]", 1.736 + compExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], ident("p"))); 1.737 +assertExpr("[ [x,y,z] for (x in foo) for (y in bar) for (z in baz) if (p) ]", 1.738 + compExpr(arrExpr([ident("x"), ident("y"), ident("z")]), 1.739 + [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))], 1.740 + ident("p"))); 1.741 + 1.742 +assertExpr("[ x for each (x in foo)]", 1.743 + compExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], null)); 1.744 +assertExpr("[ [x,y] for each (x in foo) for each (y in bar)]", 1.745 + compExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], null)); 1.746 +assertExpr("[ [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz)]", 1.747 + compExpr(arrExpr([ident("x"), ident("y"), ident("z")]), 1.748 + [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))], 1.749 + null)); 1.750 + 1.751 +assertExpr("[ x for each (x in foo) if (p)]", 1.752 + compExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], ident("p"))); 1.753 +assertExpr("[ [x,y] for each (x in foo) for each (y in bar) if (p)]", 1.754 + compExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], ident("p"))); 1.755 +assertExpr("[ [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz) if (p) ]", 1.756 + compExpr(arrExpr([ident("x"), ident("y"), ident("z")]), 1.757 + [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))], 1.758 + ident("p"))); 1.759 + 1.760 +assertExpr("[ x for (x of foo)]", 1.761 + compExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], null)); 1.762 +assertExpr("[ [x,y] for (x of foo) for (y of bar)]", 1.763 + compExpr(arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], null)); 1.764 +assertExpr("[ [x,y,z] for (x of foo) for (y of bar) for (z of baz)]", 1.765 + compExpr(arrExpr([ident("x"), ident("y"), ident("z")]), 1.766 + [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))], 1.767 + null)); 1.768 + 1.769 +assertExpr("[ x for (x of foo) if (p)]", 1.770 + compExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], ident("p"))); 1.771 +assertExpr("[ [x,y] for (x of foo) for (y of bar) if (p)]", 1.772 + compExpr(arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], ident("p"))); 1.773 +assertExpr("[ [x,y,z] for (x of foo) for (y of bar) for (z of baz) if (p) ]", 1.774 + compExpr(arrExpr([ident("x"), ident("y"), ident("z")]), 1.775 + [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))], 1.776 + ident("p"))); 1.777 + 1.778 +// generator expressions 1.779 + 1.780 +assertExpr("( x for (x in foo))", 1.781 + genExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], null)); 1.782 +assertExpr("( [x,y] for (x in foo) for (y in bar))", 1.783 + genExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], null)); 1.784 +assertExpr("( [x,y,z] for (x in foo) for (y in bar) for (z in baz))", 1.785 + genExpr(arrExpr([ident("x"), ident("y"), ident("z")]), 1.786 + [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))], 1.787 + null)); 1.788 + 1.789 +assertExpr("( x for (x in foo) if (p))", 1.790 + genExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], ident("p"))); 1.791 +assertExpr("( [x,y] for (x in foo) for (y in bar) if (p))", 1.792 + genExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], ident("p"))); 1.793 +assertExpr("( [x,y,z] for (x in foo) for (y in bar) for (z in baz) if (p) )", 1.794 + genExpr(arrExpr([ident("x"), ident("y"), ident("z")]), 1.795 + [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))], 1.796 + ident("p"))); 1.797 + 1.798 +assertExpr("( x for each (x in foo))", 1.799 + genExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], null)); 1.800 +assertExpr("( [x,y] for each (x in foo) for each (y in bar))", 1.801 + genExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], null)); 1.802 +assertExpr("( [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz))", 1.803 + genExpr(arrExpr([ident("x"), ident("y"), ident("z")]), 1.804 + [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))], 1.805 + null)); 1.806 + 1.807 +assertExpr("( x for each (x in foo) if (p))", 1.808 + genExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], ident("p"))); 1.809 +assertExpr("( [x,y] for each (x in foo) for each (y in bar) if (p))", 1.810 + genExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], ident("p"))); 1.811 +assertExpr("( [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz) if (p) )", 1.812 + genExpr(arrExpr([ident("x"), ident("y"), ident("z")]), 1.813 + [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))], 1.814 + ident("p"))); 1.815 + 1.816 +assertExpr("( x for (x of foo))", 1.817 + genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], null)); 1.818 +assertExpr("( [x,y] for (x of foo) for (y of bar))", 1.819 + genExpr(arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], null)); 1.820 +assertExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz))", 1.821 + genExpr(arrExpr([ident("x"), ident("y"), ident("z")]), 1.822 + [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))], 1.823 + null)); 1.824 + 1.825 +assertExpr("( x for (x of foo) if (p))", 1.826 + genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], ident("p"))); 1.827 +assertExpr("( [x,y] for (x of foo) for (y of bar) if (p))", 1.828 + genExpr(arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], ident("p"))); 1.829 +assertExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz) if (p) )", 1.830 + genExpr(arrExpr([ident("x"), ident("y"), ident("z")]), 1.831 + [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))], 1.832 + ident("p"))); 1.833 + 1.834 +// NOTE: it would be good to test generator expressions both with and without upvars, just like functions above. 1.835 + 1.836 + 1.837 +// let expressions 1.838 + 1.839 +assertExpr("(let (x=1) x)", letExpr([{ id: ident("x"), init: lit(1) }], ident("x"))); 1.840 +assertExpr("(let (x=1,y=2) y)", letExpr([{ id: ident("x"), init: lit(1) }, 1.841 + { id: ident("y"), init: lit(2) }], 1.842 + ident("y"))); 1.843 +assertExpr("(let (x=1,y=2,z=3) z)", letExpr([{ id: ident("x"), init: lit(1) }, 1.844 + { id: ident("y"), init: lit(2) }, 1.845 + { id: ident("z"), init: lit(3) }], 1.846 + ident("z"))); 1.847 +assertExpr("(let (x) x)", letExpr([{ id: ident("x"), init: null }], ident("x"))); 1.848 +assertExpr("(let (x,y) y)", letExpr([{ id: ident("x"), init: null }, 1.849 + { id: ident("y"), init: null }], 1.850 + ident("y"))); 1.851 +assertExpr("(let (x,y,z) z)", letExpr([{ id: ident("x"), init: null }, 1.852 + { id: ident("y"), init: null }, 1.853 + { id: ident("z"), init: null }], 1.854 + ident("z"))); 1.855 +assertExpr("(let (x = 1, y = x) y)", letExpr([{ id: ident("x"), init: lit(1) }, 1.856 + { id: ident("y"), init: ident("x") }], 1.857 + ident("y"))); 1.858 +assertError("(let (x = 1, x = 2) x)", TypeError); 1.859 + 1.860 +// let statements 1.861 + 1.862 +assertStmt("let (x=1) { }", letStmt([{ id: ident("x"), init: lit(1) }], blockStmt([]))); 1.863 +assertStmt("let (x=1,y=2) { }", letStmt([{ id: ident("x"), init: lit(1) }, 1.864 + { id: ident("y"), init: lit(2) }], 1.865 + blockStmt([]))); 1.866 +assertStmt("let (x=1,y=2,z=3) { }", letStmt([{ id: ident("x"), init: lit(1) }, 1.867 + { id: ident("y"), init: lit(2) }, 1.868 + { id: ident("z"), init: lit(3) }], 1.869 + blockStmt([]))); 1.870 +assertStmt("let (x) { }", letStmt([{ id: ident("x"), init: null }], blockStmt([]))); 1.871 +assertStmt("let (x,y) { }", letStmt([{ id: ident("x"), init: null }, 1.872 + { id: ident("y"), init: null }], 1.873 + blockStmt([]))); 1.874 +assertStmt("let (x,y,z) { }", letStmt([{ id: ident("x"), init: null }, 1.875 + { id: ident("y"), init: null }, 1.876 + { id: ident("z"), init: null }], 1.877 + blockStmt([]))); 1.878 +assertStmt("let (x = 1, y = x) { }", letStmt([{ id: ident("x"), init: lit(1) }, 1.879 + { id: ident("y"), init: ident("x") }], 1.880 + blockStmt([]))); 1.881 +assertError("let (x = 1, x = 2) { }", TypeError); 1.882 + 1.883 + 1.884 +// Bug 632024: no crashing on stack overflow 1.885 +try { 1.886 + Reflect.parse(Array(3000).join("x + y - ") + "z") 1.887 +} catch (e) { } 1.888 + 1.889 + 1.890 +// Source location information 1.891 + 1.892 + 1.893 +var withoutFileOrLine = Reflect.parse("42"); 1.894 +var withFile = Reflect.parse("42", {source:"foo.js"}); 1.895 +var withFileAndLine = Reflect.parse("42", {source:"foo.js", line:111}); 1.896 + 1.897 +Pattern({ source: null, start: { line: 1, column: 0 }, end: { line: 1, column: 2 } }).match(withoutFileOrLine.loc); 1.898 +Pattern({ source: "foo.js", start: { line: 1, column: 0 }, end: { line: 1, column: 2 } }).match(withFile.loc); 1.899 +Pattern({ source: "foo.js", start: { line: 111, column: 0 }, end: { line: 111, column: 2 } }).match(withFileAndLine.loc); 1.900 + 1.901 +var withoutFileOrLine2 = Reflect.parse("foo +\nbar"); 1.902 +var withFile2 = Reflect.parse("foo +\nbar", {source:"foo.js"}); 1.903 +var withFileAndLine2 = Reflect.parse("foo +\nbar", {source:"foo.js", line:111}); 1.904 + 1.905 +Pattern({ source: null, start: { line: 1, column: 0 }, end: { line: 2, column: 3 } }).match(withoutFileOrLine2.loc); 1.906 +Pattern({ source: "foo.js", start: { line: 1, column: 0 }, end: { line: 2, column: 3 } }).match(withFile2.loc); 1.907 +Pattern({ source: "foo.js", start: { line: 111, column: 0 }, end: { line: 112, column: 3 } }).match(withFileAndLine2.loc); 1.908 + 1.909 +var nested = Reflect.parse("(-b + sqrt(sqr(b) - 4 * a * c)) / (2 * a)", {source:"quad.js"}); 1.910 +var fourAC = nested.body[0].expression.left.right.arguments[0].right; 1.911 + 1.912 +Pattern({ source: "quad.js", start: { line: 1, column: 20 }, end: { line: 1, column: 29 } }).match(fourAC.loc); 1.913 + 1.914 + 1.915 +// No source location 1.916 + 1.917 +assertEq(Reflect.parse("42", {loc:false}).loc, null); 1.918 +program([exprStmt(lit(42))]).assert(Reflect.parse("42", {loc:false})); 1.919 + 1.920 + 1.921 +// Builder tests 1.922 + 1.923 +Pattern("program").match(Reflect.parse("42", {builder:{program:function()"program"}})); 1.924 + 1.925 +assertGlobalStmt("throw 42", 1, { throwStatement: function() 1 }); 1.926 +assertGlobalStmt("for (;;);", 2, { forStatement: function() 2 }); 1.927 +assertGlobalStmt("for (x in y);", 3, { forInStatement: function() 3 }); 1.928 +assertGlobalStmt("{ }", 4, { blockStatement: function() 4 }); 1.929 +assertGlobalStmt("foo: { }", 5, { labeledStatement: function() 5 }); 1.930 +assertGlobalStmt("with (o) { }", 6, { withStatement: function() 6 }); 1.931 +assertGlobalStmt("while (x) { }", 7, { whileStatement: function() 7 }); 1.932 +assertGlobalStmt("do { } while(false);", 8, { doWhileStatement: function() 8 }); 1.933 +assertGlobalStmt("switch (x) { }", 9, { switchStatement: function() 9 }); 1.934 +assertGlobalStmt("try { } catch(e) { }", 10, { tryStatement: function() 10 }); 1.935 +assertGlobalStmt(";", 11, { emptyStatement: function() 11 }); 1.936 +assertGlobalStmt("debugger;", 12, { debuggerStatement: function() 12 }); 1.937 +assertGlobalStmt("42;", 13, { expressionStatement: function() 13 }); 1.938 +assertGlobalStmt("for (;;) break", forStmt(null, null, null, 14), { breakStatement: function() 14 }); 1.939 +assertGlobalStmt("for (;;) continue", forStmt(null, null, null, 15), { continueStatement: function() 15 }); 1.940 + 1.941 +assertBlockDecl("var x", "var", { variableDeclaration: function(kind) kind }); 1.942 +assertBlockDecl("let x", "let", { variableDeclaration: function(kind) kind }); 1.943 +assertBlockDecl("const x", "const", { variableDeclaration: function(kind) kind }); 1.944 +assertBlockDecl("function f() { }", "function", { functionDeclaration: function() "function" }); 1.945 + 1.946 +assertGlobalExpr("(x,y,z)", 1, { sequenceExpression: function() 1 }); 1.947 +assertGlobalExpr("(x ? y : z)", 2, { conditionalExpression: function() 2 }); 1.948 +assertGlobalExpr("x + y", 3, { binaryExpression: function() 3 }); 1.949 +assertGlobalExpr("delete x", 4, { unaryExpression: function() 4 }); 1.950 +assertGlobalExpr("x = y", 5, { assignmentExpression: function() 5 }); 1.951 +assertGlobalExpr("x || y", 6, { logicalExpression: function() 6 }); 1.952 +assertGlobalExpr("x++", 7, { updateExpression: function() 7 }); 1.953 +assertGlobalExpr("new x", 8, { newExpression: function() 8 }); 1.954 +assertGlobalExpr("x()", 9, { callExpression: function() 9 }); 1.955 +assertGlobalExpr("x.y", 10, { memberExpression: function() 10 }); 1.956 +assertGlobalExpr("(function() { })", 11, { functionExpression: function() 11 }); 1.957 +assertGlobalExpr("[1,2,3]", 12, { arrayExpression: function() 12 }); 1.958 +assertGlobalExpr("({ x: y })", 13, { objectExpression: function() 13 }); 1.959 +assertGlobalExpr("this", 14, { thisExpression: function() 14 }); 1.960 +assertGlobalExpr("[x for (x in y)]", 17, { comprehensionExpression: function() 17 }); 1.961 +assertGlobalExpr("(x for (x in y))", 18, { generatorExpression: function() 18 }); 1.962 +assertGlobalExpr("(function() { yield 42 })", genFunExpr(null, [], blockStmt([exprStmt(19)])), { yieldExpression: function() 19 }); 1.963 +assertGlobalExpr("(let (x) x)", 20, { letExpression: function() 20 }); 1.964 + 1.965 +assertGlobalStmt("switch (x) { case y: }", switchStmt(ident("x"), [1]), { switchCase: function() 1 }); 1.966 +assertGlobalStmt("try { } catch (e) { }", 2, { tryStatement: (function(b, g, u, f) u), catchClause: function() 2 }); 1.967 +assertGlobalStmt("try { } catch (e if e instanceof A) { } catch (e if e instanceof B) { }", [2, 2], { tryStatement: (function(b, g, u, f) g), catchClause: function() 2 }); 1.968 +assertGlobalStmt("try { } catch (e) { }", tryStmt(blockStmt([]), [], 2, null), { catchClause: function() 2 }); 1.969 +assertGlobalStmt("try { } catch (e if e instanceof A) { } catch (e if e instanceof B) { }", 1.970 + tryStmt(blockStmt([]), [2, 2], null, null), 1.971 + { catchClause: function() 2 }); 1.972 +assertGlobalExpr("[x for (y in z) for (x in y)]", compExpr(ident("x"), [3, 3], null), { comprehensionBlock: function() 3 }); 1.973 + 1.974 +assertGlobalExpr("({ x: y } = z)", aExpr("=", 1, ident("z")), { objectPattern: function() 1 }); 1.975 +assertGlobalExpr("({ x: y } = z)", aExpr("=", objPatt([2]), ident("z")), { propertyPattern: function() 2 }); 1.976 +assertGlobalExpr("[ x ] = y", aExpr("=", 3, ident("y")), { arrayPattern: function() 3 }); 1.977 + 1.978 +// Ensure that exceptions thrown by builder methods propagate. 1.979 +var thrown = false; 1.980 +try { 1.981 + Reflect.parse("42", { builder: { program: function() { throw "expected" } } }); 1.982 +} catch (e if e === "expected") { 1.983 + thrown = true; 1.984 +} 1.985 +if (!thrown) 1.986 + throw new Error("builder exception not propagated"); 1.987 + 1.988 +// Missing property RHS's in an object literal should throw. 1.989 +try { 1.990 + Reflect.parse("({foo})"); 1.991 + throw new Error("object literal missing property RHS didn't throw"); 1.992 +} catch (e if e instanceof SyntaxError) { } 1.993 + 1.994 + 1.995 +// A simple proof-of-concept that the builder API can be used to generate other 1.996 +// formats, such as JsonMLAst: 1.997 +// 1.998 +// http://code.google.com/p/es-lab/wiki/JsonMLASTFormat 1.999 +// 1.1000 +// It's incomplete (e.g., it doesn't convert source-location information and 1.1001 +// doesn't use all the direct-eval rules), but I think it proves the point. 1.1002 + 1.1003 +var JsonMLAst = (function() { 1.1004 +function reject() { 1.1005 + throw new SyntaxError("node type not supported"); 1.1006 +} 1.1007 + 1.1008 +function isDirectEval(expr) { 1.1009 + // an approximation to the actual rules. you get the idea 1.1010 + return (expr[0] === "IdExpr" && expr[1].name === "eval"); 1.1011 +} 1.1012 + 1.1013 +function functionNode(type) { 1.1014 + return function(id, args, body, isGenerator, isExpression) { 1.1015 + if (isExpression) 1.1016 + body = ["ReturnStmt", {}, body]; 1.1017 + 1.1018 + if (!id) 1.1019 + id = ["Empty"]; 1.1020 + 1.1021 + // Patch up the argument node types: s/IdExpr/IdPatt/g 1.1022 + for (var i = 0; i < args.length; i++) { 1.1023 + args[i][0] = "IdPatt"; 1.1024 + } 1.1025 + 1.1026 + args.unshift("ParamDecl", {}); 1.1027 + 1.1028 + return [type, {}, id, args, body]; 1.1029 + } 1.1030 +} 1.1031 + 1.1032 +return { 1.1033 + program: function(stmts) { 1.1034 + stmts.unshift("Program", {}); 1.1035 + return stmts; 1.1036 + }, 1.1037 + identifier: function(name) { 1.1038 + return ["IdExpr", { name: name }]; 1.1039 + }, 1.1040 + literal: function(val) { 1.1041 + return ["LiteralExpr", { value: val }]; 1.1042 + }, 1.1043 + expressionStatement: function(expr) expr, 1.1044 + conditionalExpression: function(test, cons, alt) { 1.1045 + return ["ConditionalExpr", {}, test, cons, alt]; 1.1046 + }, 1.1047 + unaryExpression: function(op, expr) { 1.1048 + return ["UnaryExpr", {op: op}, expr]; 1.1049 + }, 1.1050 + binaryExpression: function(op, left, right) { 1.1051 + return ["BinaryExpr", {op: op}, left, right]; 1.1052 + }, 1.1053 + property: function(kind, key, val) { 1.1054 + return [kind === "init" 1.1055 + ? "DataProp" 1.1056 + : kind === "get" 1.1057 + ? "GetterProp" 1.1058 + : "SetterProp", 1.1059 + {name: key[1].name}, val]; 1.1060 + }, 1.1061 + functionDeclaration: functionNode("FunctionDecl"), 1.1062 + variableDeclaration: function(kind, elts) { 1.1063 + if (kind === "let" || kind === "const") 1.1064 + throw new SyntaxError("let and const not supported"); 1.1065 + elts.unshift("VarDecl", {}); 1.1066 + return elts; 1.1067 + }, 1.1068 + variableDeclarator: function(id, init) { 1.1069 + id[0] = "IdPatt"; 1.1070 + if (!init) 1.1071 + return id; 1.1072 + return ["InitPatt", {}, id, init]; 1.1073 + }, 1.1074 + sequenceExpression: function(exprs) { 1.1075 + var length = exprs.length; 1.1076 + var result = ["BinaryExpr", {op:","}, exprs[exprs.length - 2], exprs[exprs.length - 1]]; 1.1077 + for (var i = exprs.length - 3; i >= 0; i--) { 1.1078 + result = ["BinaryExpr", {op:","}, exprs[i], result]; 1.1079 + } 1.1080 + return result; 1.1081 + }, 1.1082 + assignmentExpression: function(op, lhs, expr) { 1.1083 + return ["AssignExpr", {op: op}, lhs, expr]; 1.1084 + }, 1.1085 + logicalExpression: function(op, left, right) { 1.1086 + return [op === "&&" ? "LogicalAndExpr" : "LogicalOrExpr", {}, left, right]; 1.1087 + }, 1.1088 + updateExpression: function(expr, op, isPrefix) { 1.1089 + return ["CountExpr", {isPrefix:isPrefix, op:op}, expr]; 1.1090 + }, 1.1091 + newExpression: function(callee, args) { 1.1092 + args.unshift("NewExpr", {}, callee); 1.1093 + return args; 1.1094 + }, 1.1095 + callExpression: function(callee, args) { 1.1096 + args.unshift(isDirectEval(callee) ? "EvalExpr" : "CallExpr", {}, callee); 1.1097 + return args; 1.1098 + }, 1.1099 + memberExpression: function(isComputed, expr, member) { 1.1100 + return ["MemberExpr", {}, expr, isComputed ? member : ["LiteralExpr", {type: "string", value: member[1].name}]]; 1.1101 + }, 1.1102 + functionExpression: functionNode("FunctionExpr"), 1.1103 + arrayExpression: function(elts) { 1.1104 + for (var i = 0; i < elts.length; i++) { 1.1105 + if (!elts[i]) 1.1106 + elts[i] = ["Empty"]; 1.1107 + } 1.1108 + elts.unshift("ArrayExpr", {}); 1.1109 + return elts; 1.1110 + }, 1.1111 + objectExpression: function(props) { 1.1112 + props.unshift("ObjectExpr", {}); 1.1113 + return props; 1.1114 + }, 1.1115 + thisExpression: function() { 1.1116 + return ["ThisExpr", {}]; 1.1117 + }, 1.1118 + 1.1119 + graphExpression: reject, 1.1120 + graphIndexExpression: reject, 1.1121 + comprehensionExpression: reject, 1.1122 + generatorExpression: reject, 1.1123 + yieldExpression: reject, 1.1124 + letExpression: reject, 1.1125 + 1.1126 + emptyStatement: function() ["EmptyStmt", {}], 1.1127 + blockStatement: function(stmts) { 1.1128 + stmts.unshift("BlockStmt", {}); 1.1129 + return stmts; 1.1130 + }, 1.1131 + labeledStatement: function(lab, stmt) { 1.1132 + return ["LabelledStmt", {label: lab}, stmt]; 1.1133 + }, 1.1134 + ifStatement: function(test, cons, alt) { 1.1135 + return ["IfStmt", {}, test, cons, alt || ["EmptyStmt", {}]]; 1.1136 + }, 1.1137 + switchStatement: function(test, clauses, isLexical) { 1.1138 + clauses.unshift("SwitchStmt", {}, test); 1.1139 + return clauses; 1.1140 + }, 1.1141 + whileStatement: function(expr, stmt) { 1.1142 + return ["WhileStmt", {}, expr, stmt]; 1.1143 + }, 1.1144 + doWhileStatement: function(stmt, expr) { 1.1145 + return ["DoWhileStmt", {}, stmt, expr]; 1.1146 + }, 1.1147 + forStatement: function(init, test, update, body) { 1.1148 + return ["ForStmt", {}, init || ["Empty"], test || ["Empty"], update || ["Empty"], body]; 1.1149 + }, 1.1150 + forInStatement: function(lhs, rhs, body) { 1.1151 + return ["ForInStmt", {}, lhs, rhs, body]; 1.1152 + }, 1.1153 + breakStatement: function(lab) { 1.1154 + return lab ? ["BreakStmt", {}, lab] : ["BreakStmt", {}]; 1.1155 + }, 1.1156 + continueStatement: function(lab) { 1.1157 + return lab ? ["ContinueStmt", {}, lab] : ["ContinueStmt", {}]; 1.1158 + }, 1.1159 + withStatement: function(expr, stmt) { 1.1160 + return ["WithStmt", {}, expr, stmt]; 1.1161 + }, 1.1162 + returnStatement: function(expr) { 1.1163 + return expr ? ["ReturnStmt", {}, expr] : ["ReturnStmt", {}]; 1.1164 + }, 1.1165 + tryStatement: function(body, catches, fin) { 1.1166 + if (catches.length > 1) 1.1167 + throw new SyntaxError("multiple catch clauses not supported"); 1.1168 + var node = ["TryStmt", body, catches[0] || ["Empty"]]; 1.1169 + if (fin) 1.1170 + node.push(fin); 1.1171 + return node; 1.1172 + }, 1.1173 + throwStatement: function(expr) { 1.1174 + return ["ThrowStmt", {}, expr]; 1.1175 + }, 1.1176 + debuggerStatement: function() ["DebuggerStmt", {}], 1.1177 + letStatement: reject, 1.1178 + switchCase: function(expr, stmts) { 1.1179 + if (expr) 1.1180 + stmts.unshift("SwitchCase", {}, expr); 1.1181 + else 1.1182 + stmts.unshift("DefaultCase", {}); 1.1183 + return stmts; 1.1184 + }, 1.1185 + catchClause: function(param, guard, body) { 1.1186 + if (guard) 1.1187 + throw new SyntaxError("catch guards not supported"); 1.1188 + param[0] = "IdPatt"; 1.1189 + return ["CatchClause", {}, param, body]; 1.1190 + }, 1.1191 + comprehensionBlock: reject, 1.1192 + 1.1193 + arrayPattern: reject, 1.1194 + objectPattern: reject, 1.1195 + propertyPattern: reject, 1.1196 +}; 1.1197 +})(); 1.1198 + 1.1199 +Pattern(["Program", {}, 1.1200 + ["BinaryExpr", {op: "+"}, 1.1201 + ["LiteralExpr", {value: 2}], 1.1202 + ["BinaryExpr", {op: "*"}, 1.1203 + ["UnaryExpr", {op: "-"}, ["IdExpr", {name: "x"}]], 1.1204 + ["IdExpr", {name: "y"}]]]]).match(Reflect.parse("2 + (-x * y)", {loc: false, builder: JsonMLAst})); 1.1205 + 1.1206 +reportCompare(true, true); 1.1207 + 1.1208 +});