js/src/tests/js1_8_5/extensions/reflect-parse.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 // |reftest| skip-if(!xulRuntime.shell)
     2 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     3 /*
     4  * Any copyright is dedicated to the Public Domain.
     5  * http://creativecommons.org/licenses/publicdomain/
     6  */
     8 (function runtest(main) {
     9     try {
    10         main();
    11     } catch (exc) {
    12         print(exc.stack);
    13         throw exc;
    14     }
    15 })(function main() {
    17 var { Pattern, MatchError } = Match;
    19 var _ = Pattern.ANY;
    21 function program(elts) Pattern({ type: "Program", body: elts })
    22 function exprStmt(expr) Pattern({ type: "ExpressionStatement", expression: expr })
    23 function throwStmt(expr) Pattern({ type: "ThrowStatement", argument: expr })
    24 function returnStmt(expr) Pattern({ type: "ReturnStatement", argument: expr })
    25 function yieldExpr(expr) Pattern({ type: "YieldExpression", argument: expr })
    26 function lit(val) Pattern({ type: "Literal", value: val })
    27 function spread(val) Pattern({ type: "SpreadExpression", expression: val})
    28 var thisExpr = Pattern({ type: "ThisExpression" });
    29 function funDecl(id, params, body, defaults=[], rest=null) Pattern(
    30     { type: "FunctionDeclaration",
    31       id: id,
    32       params: params,
    33       defaults: defaults,
    34       body: body,
    35       rest: rest,
    36       generator: false })
    37 function genFunDecl(id, params, body) Pattern({ type: "FunctionDeclaration",
    38                                                 id: id,
    39                                                 params: params,
    40                                                 defaults: [],
    41                                                 body: body,
    42                                                 generator: true })
    43 function varDecl(decls) Pattern({ type: "VariableDeclaration", declarations: decls, kind: "var" })
    44 function letDecl(decls) Pattern({ type: "VariableDeclaration", declarations: decls, kind: "let" })
    45 function constDecl(decls) Pattern({ type: "VariableDeclaration", declarations: decls, kind: "const" })
    46 function ident(name) Pattern({ type: "Identifier", name: name })
    47 function dotExpr(obj, id) Pattern({ type: "MemberExpression", computed: false, object: obj, property: id })
    48 function memExpr(obj, id) Pattern({ type: "MemberExpression", computed: true, object: obj, property: id })
    49 function forStmt(init, test, update, body) Pattern({ type: "ForStatement", init: init, test: test, update: update, body: body })
    50 function forOfStmt(lhs, rhs, body) Pattern({ type: "ForOfStatement", left: lhs, right: rhs, body: body })
    51 function forInStmt(lhs, rhs, body) Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: false })
    52 function forEachInStmt(lhs, rhs, body) Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: true })
    53 function breakStmt(lab) Pattern({ type: "BreakStatement", label: lab })
    54 function continueStmt(lab) Pattern({ type: "ContinueStatement", label: lab })
    55 function blockStmt(body) Pattern({ type: "BlockStatement", body: body })
    56 var emptyStmt = Pattern({ type: "EmptyStatement" })
    57 function ifStmt(test, cons, alt) Pattern({ type: "IfStatement", test: test, alternate: alt, consequent: cons })
    58 function labStmt(lab, stmt) Pattern({ type: "LabeledStatement", label: lab, body: stmt })
    59 function withStmt(obj, stmt) Pattern({ type: "WithStatement", object: obj, body: stmt })
    60 function whileStmt(test, stmt) Pattern({ type: "WhileStatement", test: test, body: stmt })
    61 function doStmt(stmt, test) Pattern({ type: "DoWhileStatement", test: test, body: stmt })
    62 function switchStmt(disc, cases) Pattern({ type: "SwitchStatement", discriminant: disc, cases: cases })
    63 function caseClause(test, stmts) Pattern({ type: "SwitchCase", test: test, consequent: stmts })
    64 function defaultClause(stmts) Pattern({ type: "SwitchCase", test: null, consequent: stmts })
    65 function catchClause(id, guard, body) Pattern({ type: "CatchClause", param: id, guard: guard, body: body })
    66 function tryStmt(body, guarded, unguarded, fin) Pattern({ type: "TryStatement", block: body, guardedHandlers: guarded, handler: unguarded, finalizer: fin })
    67 function letStmt(head, body) Pattern({ type: "LetStatement", head: head, body: body })
    68 function funExpr(id, args, body, gen) Pattern({ type: "FunctionExpression",
    69                                                 id: id,
    70                                                 params: args,
    71                                                 body: body,
    72                                                 generator: false })
    73 function genFunExpr(id, args, body) Pattern({ type: "FunctionExpression",
    74                                               id: id,
    75                                               params: args,
    76                                               body: body,
    77                                               generator: true })
    78 function arrowExpr(args, body) Pattern({ type: "ArrowExpression",
    79                                          params: args,
    80                                          body: body })
    82 function unExpr(op, arg) Pattern({ type: "UnaryExpression", operator: op, argument: arg })
    83 function binExpr(op, left, right) Pattern({ type: "BinaryExpression", operator: op, left: left, right: right })
    84 function aExpr(op, left, right) Pattern({ type: "AssignmentExpression", operator: op, left: left, right: right })
    85 function updExpr(op, arg, prefix) Pattern({ type: "UpdateExpression", operator: op, argument: arg, prefix: prefix })
    86 function logExpr(op, left, right) Pattern({ type: "LogicalExpression", operator: op, left: left, right: right })
    88 function condExpr(test, cons, alt) Pattern({ type: "ConditionalExpression", test: test, consequent: cons, alternate: alt })
    89 function seqExpr(exprs) Pattern({ type: "SequenceExpression", expressions: exprs })
    90 function newExpr(callee, args) Pattern({ type: "NewExpression", callee: callee, arguments: args })
    91 function callExpr(callee, args) Pattern({ type: "CallExpression", callee: callee, arguments: args })
    92 function arrExpr(elts) Pattern({ type: "ArrayExpression", elements: elts })
    93 function objExpr(elts) Pattern({ type: "ObjectExpression", properties: elts })
    94 function compExpr(body, blocks, filter) Pattern({ type: "ComprehensionExpression", body: body, blocks: blocks, filter: filter })
    95 function genExpr(body, blocks, filter) Pattern({ type: "GeneratorExpression", body: body, blocks: blocks, filter: filter })
    96 function graphExpr(idx, body) Pattern({ type: "GraphExpression", index: idx, expression: body })
    97 function letExpr(head, body) Pattern({ type: "LetExpression", head: head, body: body })
    98 function idxExpr(idx) Pattern({ type: "GraphIndexExpression", index: idx })
   100 function compBlock(left, right) Pattern({ type: "ComprehensionBlock", left: left, right: right, each: false, of: false })
   101 function compEachBlock(left, right) Pattern({ type: "ComprehensionBlock", left: left, right: right, each: true, of: false })
   102 function compOfBlock(left, right) Pattern({ type: "ComprehensionBlock", left: left, right: right, each: false, of: true })
   104 function arrPatt(elts) Pattern({ type: "ArrayPattern", elements: elts })
   105 function objPatt(elts) Pattern({ type: "ObjectPattern", properties: elts })
   107 function localSrc(src) "(function(){ " + src + " })"
   108 function localPatt(patt) program([exprStmt(funExpr(null, [], blockStmt([patt])))])
   109 function blockSrc(src) "(function(){ { " + src + " } })"
   110 function blockPatt(patt) program([exprStmt(funExpr(null, [], blockStmt([blockStmt([patt])])))])
   112 function assertBlockStmt(src, patt) {
   113     blockPatt(patt).assert(Reflect.parse(blockSrc(src)));
   114 }
   116 function assertBlockExpr(src, patt) {
   117     assertBlockStmt(src, exprStmt(patt));
   118 }
   120 function assertBlockDecl(src, patt, builder) {
   121     blockPatt(patt).assert(Reflect.parse(blockSrc(src), {builder: builder}));
   122 }
   124 function assertLocalStmt(src, patt) {
   125     localPatt(patt).assert(Reflect.parse(localSrc(src)));
   126 }
   128 function assertLocalExpr(src, patt) {
   129     assertLocalStmt(src, exprStmt(patt));
   130 }
   132 function assertLocalDecl(src, patt) {
   133     localPatt(patt).assert(Reflect.parse(localSrc(src)));
   134 }
   136 function assertGlobalStmt(src, patt, builder) {
   137     program([patt]).assert(Reflect.parse(src, {builder: builder}));
   138 }
   140 function assertGlobalExpr(src, patt, builder) {
   141     program([exprStmt(patt)]).assert(Reflect.parse(src, {builder: builder}));
   142     //assertStmt(src, exprStmt(patt));
   143 }
   145 function assertGlobalDecl(src, patt) {
   146     program([patt]).assert(Reflect.parse(src));
   147 }
   149 function assertProg(src, patt) {
   150     program(patt).assert(Reflect.parse(src));
   151 }
   153 function assertStmt(src, patt) {
   154     assertLocalStmt(src, patt);
   155     assertGlobalStmt(src, patt);
   156     assertBlockStmt(src, patt);
   157 }
   159 function assertExpr(src, patt) {
   160     assertLocalExpr(src, patt);
   161     assertGlobalExpr(src, patt);
   162     assertBlockExpr(src, patt);
   163 }
   165 function assertDecl(src, patt) {
   166     assertLocalDecl(src, patt);
   167     assertGlobalDecl(src, patt);
   168     assertBlockDecl(src, patt);
   169 }
   171 function assertError(src, errorType) {
   172     try {
   173         Reflect.parse(src);
   174     } catch (expected if expected instanceof errorType) {
   175         return;
   176     }
   177     throw new Error("expected " + errorType.name + " for " + uneval(src));
   178 }
   181 // general tests
   183 // NB: These are useful but for now jit-test doesn't do I/O reliably.
   185 //program(_).assert(Reflect.parse(snarf('data/flapjax.txt')));
   186 //program(_).assert(Reflect.parse(snarf('data/jquery-1.4.2.txt')));
   187 //program(_).assert(Reflect.parse(snarf('data/prototype.js')));
   188 //program(_).assert(Reflect.parse(snarf('data/dojo.js.uncompressed.js')));
   189 //program(_).assert(Reflect.parse(snarf('data/mootools-1.2.4-core-nc.js')));
   192 // declarations
   194 assertDecl("var x = 1, y = 2, z = 3",
   195            varDecl([{ id: ident("x"), init: lit(1) },
   196                     { id: ident("y"), init: lit(2) },
   197                     { id: ident("z"), init: lit(3) }]));
   198 assertDecl("var x, y, z",
   199            varDecl([{ id: ident("x"), init: null },
   200                     { id: ident("y"), init: null },
   201                     { id: ident("z"), init: null }]));
   202 assertDecl("function foo() { }",
   203            funDecl(ident("foo"), [], blockStmt([])));
   204 assertDecl("function foo() { return 42 }",
   205            funDecl(ident("foo"), [], blockStmt([returnStmt(lit(42))])));
   207 assertDecl("function foo(...rest) { }",
   208            funDecl(ident("foo"), [], blockStmt([]), [], ident("rest")));
   210 assertDecl("function foo(a=4) { }", funDecl(ident("foo"), [ident("a")], blockStmt([]), [lit(4)]));
   211 assertDecl("function foo(a, b=4) { }", funDecl(ident("foo"), [ident("a"), ident("b")], blockStmt([]), [lit(4)]));
   212 assertDecl("function foo(a, b=4, ...rest) { }",
   213            funDecl(ident("foo"), [ident("a"), ident("b")], blockStmt([]), [lit(4)], ident("rest")));
   214 assertDecl("function foo(a=(function () {})) { function a() {} }",
   215            funDecl(ident("foo"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))]),
   216                    [funExpr(ident("a"), [], blockStmt([]))]));
   219 // Bug 591437: rebound args have their defs turned into uses
   220 assertDecl("function f(a) { function a() { } }",
   221            funDecl(ident("f"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))])));
   222 assertDecl("function f(a,b,c) { function b() { } }",
   223            funDecl(ident("f"), [ident("a"),ident("b"),ident("c")], blockStmt([funDecl(ident("b"), [], blockStmt([]))])));
   224 assertDecl("function f(a,[x,y]) { function a() { } }",
   225            funDecl(ident("f"),
   226                    [ident("a"), arrPatt([ident("x"), ident("y")])],
   227                    blockStmt([funDecl(ident("a"), [], blockStmt([]))])));
   229 // Bug 632027: array holes should reflect as null
   230 assertExpr("[,]=[,]", aExpr("=", arrPatt([null]), arrExpr([null])));
   232 // Bug 591450: this test currently crashes because of a bug in jsparse
   233 // assertDecl("function f(a,[x,y],b,[w,z],c) { function b() { } }",
   234 //            funDecl(ident("f"),
   235 //                    [ident("a"), arrPatt([ident("x"), ident("y")]), ident("b"), arrPatt([ident("w"), ident("z")]), ident("c")],
   236 //                    blockStmt([funDecl(ident("b"), [], blockStmt([]))])));
   239 // expressions
   241 assertExpr("true", lit(true));
   242 assertExpr("false", lit(false));
   243 assertExpr("42", lit(42));
   244 assertExpr("(/asdf/)", lit(/asdf/));
   245 assertExpr("this", thisExpr);
   246 assertExpr("foo", ident("foo"));
   247 assertExpr("foo.bar", dotExpr(ident("foo"), ident("bar")));
   248 assertExpr("foo[bar]", memExpr(ident("foo"), ident("bar")));
   249 assertExpr("foo['bar']", memExpr(ident("foo"), lit("bar")));
   250 assertExpr("foo[42]", memExpr(ident("foo"), lit(42)));
   251 assertExpr("(function(){})", funExpr(null, [], blockStmt([])));
   252 assertExpr("(function f() {})", funExpr(ident("f"), [], blockStmt([])));
   253 assertExpr("(function f(x,y,z) {})", funExpr(ident("f"), [ident("x"),ident("y"),ident("z")], blockStmt([])));
   254 assertExpr("a => a", arrowExpr([ident("a")], ident("a")));
   255 assertExpr("(a) => a", arrowExpr([ident("a")], ident("a")));
   256 assertExpr("a => b => a", arrowExpr([ident("a")], arrowExpr([ident("b")], ident("a"))));
   257 assertExpr("a => {}", arrowExpr([ident("a")], blockStmt([])));
   258 assertExpr("a => ({})", arrowExpr([ident("a")], objExpr([])));
   259 assertExpr("(a, b, c) => {}", arrowExpr([ident("a"), ident("b"), ident("c")], blockStmt([])));
   260 assertExpr("([a, b]) => {}", arrowExpr([arrPatt([ident("a"), ident("b")])], blockStmt([])));
   261 assertExpr("(++x)", updExpr("++", ident("x"), true));
   262 assertExpr("(x++)", updExpr("++", ident("x"), false));
   263 assertExpr("(+x)", unExpr("+", ident("x")));
   264 assertExpr("(-x)", unExpr("-", ident("x")));
   265 assertExpr("(!x)", unExpr("!", ident("x")));
   266 assertExpr("(~x)", unExpr("~", ident("x")));
   267 assertExpr("(delete x)", unExpr("delete", ident("x")));
   268 assertExpr("(typeof x)", unExpr("typeof", ident("x")));
   269 assertExpr("(void x)", unExpr("void", ident("x")));
   270 assertExpr("(x == y)", binExpr("==", ident("x"), ident("y")));
   271 assertExpr("(x != y)", binExpr("!=", ident("x"), ident("y")));
   272 assertExpr("(x === y)", binExpr("===", ident("x"), ident("y")));
   273 assertExpr("(x !== y)", binExpr("!==", ident("x"), ident("y")));
   274 assertExpr("(x < y)", binExpr("<", ident("x"), ident("y")));
   275 assertExpr("(x <= y)", binExpr("<=", ident("x"), ident("y")));
   276 assertExpr("(x > y)", binExpr(">", ident("x"), ident("y")));
   277 assertExpr("(x >= y)", binExpr(">=", ident("x"), ident("y")));
   278 assertExpr("(x << y)", binExpr("<<", ident("x"), ident("y")));
   279 assertExpr("(x >> y)", binExpr(">>", ident("x"), ident("y")));
   280 assertExpr("(x >>> y)", binExpr(">>>", ident("x"), ident("y")));
   281 assertExpr("(x + y)", binExpr("+", ident("x"), ident("y")));
   282 assertExpr("(w + x + y + z)", binExpr("+", binExpr("+", binExpr("+", ident("w"), ident("x")), ident("y")), ident("z")));
   283 assertExpr("(x - y)", binExpr("-", ident("x"), ident("y")));
   284 assertExpr("(w - x - y - z)", binExpr("-", binExpr("-", binExpr("-", ident("w"), ident("x")), ident("y")), ident("z")));
   285 assertExpr("(x * y)", binExpr("*", ident("x"), ident("y")));
   286 assertExpr("(x / y)", binExpr("/", ident("x"), ident("y")));
   287 assertExpr("(x % y)", binExpr("%", ident("x"), ident("y")));
   288 assertExpr("(x | y)", binExpr("|", ident("x"), ident("y")));
   289 assertExpr("(x ^ y)", binExpr("^", ident("x"), ident("y")));
   290 assertExpr("(x & y)", binExpr("&", ident("x"), ident("y")));
   291 assertExpr("(x in y)", binExpr("in", ident("x"), ident("y")));
   292 assertExpr("(x instanceof y)", binExpr("instanceof", ident("x"), ident("y")));
   293 assertExpr("(x = y)", aExpr("=", ident("x"), ident("y")));
   294 assertExpr("(x += y)", aExpr("+=", ident("x"), ident("y")));
   295 assertExpr("(x -= y)", aExpr("-=", ident("x"), ident("y")));
   296 assertExpr("(x *= y)", aExpr("*=", ident("x"), ident("y")));
   297 assertExpr("(x /= y)", aExpr("/=", ident("x"), ident("y")));
   298 assertExpr("(x %= y)", aExpr("%=", ident("x"), ident("y")));
   299 assertExpr("(x <<= y)", aExpr("<<=", ident("x"), ident("y")));
   300 assertExpr("(x >>= y)", aExpr(">>=", ident("x"), ident("y")));
   301 assertExpr("(x >>>= y)", aExpr(">>>=", ident("x"), ident("y")));
   302 assertExpr("(x |= y)", aExpr("|=", ident("x"), ident("y")));
   303 assertExpr("(x ^= y)", aExpr("^=", ident("x"), ident("y")));
   304 assertExpr("(x &= y)", aExpr("&=", ident("x"), ident("y")));
   305 assertExpr("(x || y)", logExpr("||", ident("x"), ident("y")));
   306 assertExpr("(x && y)", logExpr("&&", ident("x"), ident("y")));
   307 assertExpr("(w || x || y || z)", logExpr("||", logExpr("||", logExpr("||", ident("w"), ident("x")), ident("y")), ident("z")))
   308 assertExpr("(x ? y : z)", condExpr(ident("x"), ident("y"), ident("z")));
   309 assertExpr("(x,y)", seqExpr([ident("x"),ident("y")]))
   310 assertExpr("(x,y,z)", seqExpr([ident("x"),ident("y"),ident("z")]))
   311 assertExpr("(a,b,c,d,e,f,g)", seqExpr([ident("a"),ident("b"),ident("c"),ident("d"),ident("e"),ident("f"),ident("g")]));
   312 assertExpr("(new Object)", newExpr(ident("Object"), []));
   313 assertExpr("(new Object())", newExpr(ident("Object"), []));
   314 assertExpr("(new Object(42))", newExpr(ident("Object"), [lit(42)]));
   315 assertExpr("(new Object(1,2,3))", newExpr(ident("Object"), [lit(1),lit(2),lit(3)]));
   316 assertExpr("(String())", callExpr(ident("String"), []));
   317 assertExpr("(String(42))", callExpr(ident("String"), [lit(42)]));
   318 assertExpr("(String(1,2,3))", callExpr(ident("String"), [lit(1),lit(2),lit(3)]));
   319 assertExpr("[]", arrExpr([]));
   320 assertExpr("[1]", arrExpr([lit(1)]));
   321 assertExpr("[1,2]", arrExpr([lit(1),lit(2)]));
   322 assertExpr("[1,2,3]", arrExpr([lit(1),lit(2),lit(3)]));
   323 assertExpr("[1,,2,3]", arrExpr([lit(1),null,lit(2),lit(3)]));
   324 assertExpr("[1,,,2,3]", arrExpr([lit(1),null,null,lit(2),lit(3)]));
   325 assertExpr("[1,,,2,,3]", arrExpr([lit(1),null,null,lit(2),null,lit(3)]));
   326 assertExpr("[1,,,2,,,3]", arrExpr([lit(1),null,null,lit(2),null,null,lit(3)]));
   327 assertExpr("[,1,2,3]", arrExpr([null,lit(1),lit(2),lit(3)]));
   328 assertExpr("[,,1,2,3]", arrExpr([null,null,lit(1),lit(2),lit(3)]));
   329 assertExpr("[,,,1,2,3]", arrExpr([null,null,null,lit(1),lit(2),lit(3)]));
   330 assertExpr("[,,,1,2,3,]", arrExpr([null,null,null,lit(1),lit(2),lit(3)]));
   331 assertExpr("[,,,1,2,3,,]", arrExpr([null,null,null,lit(1),lit(2),lit(3),null]));
   332 assertExpr("[,,,1,2,3,,,]", arrExpr([null,null,null,lit(1),lit(2),lit(3),null,null]));
   333 assertExpr("[,,,,,]", arrExpr([null,null,null,null,null]));
   334 assertExpr("[1, ...a, 2]", arrExpr([lit(1), spread(ident("a")), lit(2)]));
   335 assertExpr("[,, ...a,, ...b, 42]", arrExpr([null,null, spread(ident("a")),, spread(ident("b")), lit(42)]));
   336 assertExpr("[1,(2,3)]", arrExpr([lit(1),seqExpr([lit(2),lit(3)])]));
   337 assertExpr("[,(2,3)]", arrExpr([null,seqExpr([lit(2),lit(3)])]));
   338 assertExpr("({})", objExpr([]));
   339 assertExpr("({x:1})", objExpr([{ key: ident("x"), value: lit(1) }]));
   340 assertExpr("({x:1, y:2})", objExpr([{ key: ident("x"), value: lit(1) },
   341                                     { key: ident("y"), value: lit(2) } ]));
   342 assertExpr("({x:1, y:2, z:3})", objExpr([{ key: ident("x"), value: lit(1) },
   343                                          { key: ident("y"), value: lit(2) },
   344                                          { key: ident("z"), value: lit(3) } ]));
   345 assertExpr("({x:1, 'y':2, z:3})", objExpr([{ key: ident("x"), value: lit(1) },
   346                                            { key: lit("y"), value: lit(2) },
   347                                            { key: ident("z"), value: lit(3) } ]));
   348 assertExpr("({'x':1, 'y':2, z:3})", objExpr([{ key: lit("x"), value: lit(1) },
   349                                              { key: lit("y"), value: lit(2) },
   350                                              { key: ident("z"), value: lit(3) } ]));
   351 assertExpr("({'x':1, 'y':2, 3:3})", objExpr([{ key: lit("x"), value: lit(1) },
   352                                              { key: lit("y"), value: lit(2) },
   353                                              { key: lit(3), value: lit(3) } ]));
   355 // Bug 571617: eliminate constant-folding
   356 assertExpr("2 + 3", binExpr("+", lit(2), lit(3)));
   358 // Bug 632026: constant-folding
   359 assertExpr("typeof(0?0:a)", unExpr("typeof", condExpr(lit(0), lit(0), ident("a"))));
   361 // Bug 632029: constant-folding
   362 assertExpr("[x for each (x in y) if (false)]", compExpr(ident("x"), [compEachBlock(ident("x"), ident("y"))], lit(false)));
   364 // Bug 632056: constant-folding
   365 program([exprStmt(ident("f")),
   366          ifStmt(lit(1),
   367                 funDecl(ident("f"), [], blockStmt([])),
   368                 null)]).assert(Reflect.parse("f; if (1) function f(){}"));
   370 // statements
   372 assertStmt("throw 42", throwStmt(lit(42)));
   373 assertStmt("for (;;) break", forStmt(null, null, null, breakStmt(null)));
   374 assertStmt("for (x; y; z) break", forStmt(ident("x"), ident("y"), ident("z"), breakStmt(null)));
   375 assertStmt("for (var x; y; z) break", forStmt(varDecl([{ id: ident("x"), init: null }]), ident("y"), ident("z")));
   376 assertStmt("for (var x = 42; y; z) break", forStmt(varDecl([{ id: ident("x"), init: lit(42) }]), ident("y"), ident("z")));
   377 assertStmt("for (x; ; z) break", forStmt(ident("x"), null, ident("z"), breakStmt(null)));
   378 assertStmt("for (var x; ; z) break", forStmt(varDecl([{ id: ident("x"), init: null }]), null, ident("z")));
   379 assertStmt("for (var x = 42; ; z) break", forStmt(varDecl([{ id: ident("x"), init: lit(42) }]), null, ident("z")));
   380 assertStmt("for (x; y; ) break", forStmt(ident("x"), ident("y"), null, breakStmt(null)));
   381 assertStmt("for (var x; y; ) break", forStmt(varDecl([{ id: ident("x"), init: null }]), ident("y"), null, breakStmt(null)));
   382 assertStmt("for (var x = 42; y; ) break", forStmt(varDecl([{ id: ident("x"), init: lit(42) }]), ident("y"), null, breakStmt(null)));
   383 assertStmt("for (var x in y) break", forInStmt(varDecl([{ id: ident("x"), init: null }]), ident("y"), breakStmt(null)));
   384 assertStmt("for (x in y) break", forInStmt(ident("x"), ident("y"), breakStmt(null)));
   385 assertStmt("{ }", blockStmt([]));
   386 assertStmt("{ throw 1; throw 2; throw 3; }", blockStmt([ throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]));
   387 assertStmt(";", emptyStmt);
   388 assertStmt("if (foo) throw 42;", ifStmt(ident("foo"), throwStmt(lit(42)), null));
   389 assertStmt("if (foo) throw 42; else true;", ifStmt(ident("foo"), throwStmt(lit(42)), exprStmt(lit(true))));
   390 assertStmt("if (foo) { throw 1; throw 2; throw 3; }",
   391            ifStmt(ident("foo"),
   392                   blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]),
   393                   null));
   394 assertStmt("if (foo) { throw 1; throw 2; throw 3; } else true;",
   395            ifStmt(ident("foo"),
   396                   blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]),
   397                   exprStmt(lit(true))));
   398 assertStmt("foo: for(;;) break foo;", labStmt(ident("foo"), forStmt(null, null, null, breakStmt(ident("foo")))));
   399 assertStmt("foo: for(;;) continue foo;", labStmt(ident("foo"), forStmt(null, null, null, continueStmt(ident("foo")))));
   400 assertStmt("with (obj) { }", withStmt(ident("obj"), blockStmt([])));
   401 assertStmt("with (obj) { obj; }", withStmt(ident("obj"), blockStmt([exprStmt(ident("obj"))])));
   402 assertStmt("while (foo) { }", whileStmt(ident("foo"), blockStmt([])));
   403 assertStmt("while (foo) { foo; }", whileStmt(ident("foo"), blockStmt([exprStmt(ident("foo"))])));
   404 assertStmt("do { } while (foo);", doStmt(blockStmt([]), ident("foo")));
   405 assertStmt("do { foo; } while (foo)", doStmt(blockStmt([exprStmt(ident("foo"))]), ident("foo")));
   406 assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; }",
   407            switchStmt(ident("foo"),
   408                       [ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]),
   409                         caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]),
   410                         defaultClause([ exprStmt(lit(3)) ]) ]));
   411 assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; case 42: 42; }",
   412            switchStmt(ident("foo"),
   413                       [ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]),
   414                         caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]),
   415                         defaultClause([ exprStmt(lit(3)) ]),
   416                         caseClause(lit(42), [ exprStmt(lit(42)) ]) ]));
   417 assertStmt("try { } catch (e) { }",
   418            tryStmt(blockStmt([]),
   419                    [],
   420 		   catchClause(ident("e"), null, blockStmt([])),
   421                    null));
   422 assertStmt("try { } catch (e) { } finally { }",
   423            tryStmt(blockStmt([]),
   424                    [],
   425 		   catchClause(ident("e"), null, blockStmt([])),
   426                    blockStmt([])));
   427 assertStmt("try { } finally { }",
   428            tryStmt(blockStmt([]),
   429                    [],
   430 		   null,
   431                    blockStmt([])));
   432 assertStmt("try { } catch (e if foo) { } catch (e if bar) { } finally { }",
   433            tryStmt(blockStmt([]),
   434                    [ catchClause(ident("e"), ident("foo"), blockStmt([])),
   435                      catchClause(ident("e"), ident("bar"), blockStmt([])) ],
   436 		   null,
   437                    blockStmt([])));
   438 assertStmt("try { } catch (e if foo) { } catch (e if bar) { } catch (e) { } finally { }",
   439            tryStmt(blockStmt([]),
   440                    [ catchClause(ident("e"), ident("foo"), blockStmt([])),
   441                      catchClause(ident("e"), ident("bar"), blockStmt([])) ],
   442                    catchClause(ident("e"), null, blockStmt([])),
   443                    blockStmt([])));
   445 // Bug 632028: yield outside of a function should throw
   446 (function() {
   447     var threw = false;
   448     try {
   449         Reflect.parse("yield 0");
   450     } catch (expected) {
   451         threw = true;
   452     }
   453     assertEq(threw, true);
   454 })();
   456 // redeclarations (TOK_NAME nodes with lexdef)
   458 assertStmt("function f() { function g() { } function g() { } }",
   459            funDecl(ident("f"), [], blockStmt([emptyStmt,
   460                                               funDecl(ident("g"), [], blockStmt([]))])));
   462 // Fails due to parser quirks (bug 638577)
   463 //assertStmt("function f() { function g() { } function g() { return 42 } }",
   464 //           funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])),
   465 //                                              funDecl(ident("g"), [], blockStmt([returnStmt(lit(42))]))])));
   467 assertStmt("function f() { var x = 42; var x = 43; }",
   468            funDecl(ident("f"), [], blockStmt([varDecl([{ id: ident("x"), init: lit(42) }]),
   469                                               varDecl([{ id: ident("x"), init: lit(43) }])])));
   472 assertDecl("var {x:y} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]),
   473                                           init: ident("foo") }]));
   475 // Bug 632030: redeclarations between var and funargs, var and function
   476 assertStmt("function g(x) { var x }",
   477            funDecl(ident("g"), [ident("x")], blockStmt([varDecl[{ id: ident("x"), init: null }]])));
   478 assertProg("f.p = 1; var f; f.p; function f(){}",
   479            [exprStmt(aExpr("=", dotExpr(ident("f"), ident("p")), lit(1))),
   480             varDecl([{ id: ident("f"), init: null }]),
   481             exprStmt(dotExpr(ident("f"), ident("p"))),
   482             funDecl(ident("f"), [], blockStmt([]))]);
   484 // global let is var
   485 assertGlobalDecl("let {x:y} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]),
   486                                                 init: ident("foo") }]));
   487 // function-global let is var
   488 assertLocalDecl("let {x:y} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]),
   489                                                init: ident("foo") }]));
   490 // block-local let is let
   491 assertBlockDecl("let {x:y} = foo;", letDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]),
   492                                                init: ident("foo") }]));
   494 assertDecl("const {x:y} = foo;", constDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]),
   495                                               init: ident("foo") }]));
   498 // various combinations of identifiers and destructuring patterns:
   499 function makePatternCombinations(id, destr)
   500     [
   501       [ id(1)                                            ],
   502       [ id(1),    id(2)                                  ],
   503       [ id(1),    id(2),    id(3)                        ],
   504       [ id(1),    id(2),    id(3),    id(4)              ],
   505       [ id(1),    id(2),    id(3),    id(4),    id(5)    ],
   507       [ destr(1)                                         ],
   508       [ destr(1), destr(2)                               ],
   509       [ destr(1), destr(2), destr(3)                     ],
   510       [ destr(1), destr(2), destr(3), destr(4)           ],
   511       [ destr(1), destr(2), destr(3), destr(4), destr(5) ],
   513       [ destr(1), id(2)                                  ],
   515       [ destr(1), id(2),    id(3)                        ],
   516       [ destr(1), id(2),    id(3),    id(4)              ],
   517       [ destr(1), id(2),    id(3),    id(4),    id(5)    ],
   518       [ destr(1), id(2),    id(3),    id(4),    destr(5) ],
   519       [ destr(1), id(2),    id(3),    destr(4)           ],
   520       [ destr(1), id(2),    id(3),    destr(4), id(5)    ],
   521       [ destr(1), id(2),    id(3),    destr(4), destr(5) ],
   523       [ destr(1), id(2),    destr(3)                     ],
   524       [ destr(1), id(2),    destr(3), id(4)              ],
   525       [ destr(1), id(2),    destr(3), id(4),    id(5)    ],
   526       [ destr(1), id(2),    destr(3), id(4),    destr(5) ],
   527       [ destr(1), id(2),    destr(3), destr(4)           ],
   528       [ destr(1), id(2),    destr(3), destr(4), id(5)    ],
   529       [ destr(1), id(2),    destr(3), destr(4), destr(5) ],
   531       [ id(1),    destr(2)                               ],
   533       [ id(1),    destr(2), id(3)                        ],
   534       [ id(1),    destr(2), id(3),    id(4)              ],
   535       [ id(1),    destr(2), id(3),    id(4),    id(5)    ],
   536       [ id(1),    destr(2), id(3),    id(4),    destr(5) ],
   537       [ id(1),    destr(2), id(3),    destr(4)           ],
   538       [ id(1),    destr(2), id(3),    destr(4), id(5)    ],
   539       [ id(1),    destr(2), id(3),    destr(4), destr(5) ],
   541       [ id(1),    destr(2), destr(3)                     ],
   542       [ id(1),    destr(2), destr(3), id(4)              ],
   543       [ id(1),    destr(2), destr(3), id(4),    id(5)    ],
   544       [ id(1),    destr(2), destr(3), id(4),    destr(5) ],
   545       [ id(1),    destr(2), destr(3), destr(4)           ],
   546       [ id(1),    destr(2), destr(3), destr(4), id(5)    ],
   547       [ id(1),    destr(2), destr(3), destr(4), destr(5) ]
   548     ]
   550 // destructuring function parameters
   552 function testParamPatternCombinations(makePattSrc, makePattPatt) {
   553     var pattSrcs = makePatternCombinations(function(n) ("x" + n), makePattSrc);
   554     var pattPatts = makePatternCombinations(function(n) (ident("x" + n)), makePattPatt);
   556     for (var i = 0; i < pattSrcs.length; i++) {
   557         function makeSrc(body) ("(function(" + pattSrcs[i].join(",") + ") " + body + ")")
   558         function makePatt(body) (funExpr(null, pattPatts[i], body))
   560         // no upvars, block body
   561         assertExpr(makeSrc("{ }", makePatt(blockStmt([]))));
   562         // upvars, block body
   563         assertExpr(makeSrc("{ return [x1,x2,x3,x4,x5]; }"),
   564                    makePatt(blockStmt([returnStmt(arrExpr([ident("x1"), ident("x2"), ident("x3"), ident("x4"), ident("x5")]))])));
   565         // no upvars, expression body
   566         assertExpr(makeSrc("(0)"), makePatt(lit(0)));
   567         // upvars, expression body
   568         assertExpr(makeSrc("[x1,x2,x3,x4,x5]"),
   569                    makePatt(arrExpr([ident("x1"), ident("x2"), ident("x3"), ident("x4"), ident("x5")])));
   570     }
   571 }
   573 testParamPatternCombinations(function(n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "}"),
   574                              function(n) (objPatt([{ key: ident("a" + n), value: ident("x" + n) },
   575                                                    { key: ident("b" + n), value: ident("y" + n) },
   576                                                    { key: ident("c" + n), value: ident("z" + n) }])));
   578 testParamPatternCombinations(function(n) ("[x" + n + "," + "y" + n + "," + "z" + n + "]"),
   579                              function(n) (arrPatt([ident("x" + n), ident("y" + n), ident("z" + n)])));
   582 // destructuring variable declarations
   584 function testVarPatternCombinations(makePattSrc, makePattPatt) {
   585     var pattSrcs = makePatternCombinations(function(n) ("x" + n), makePattSrc);
   586     var pattPatts = makePatternCombinations(function(n) ({ id: ident("x" + n), init: null }), makePattPatt);
   588     for (var i = 0; i < pattSrcs.length; i++) {
   589         // variable declarations in blocks
   590         assertDecl("var " + pattSrcs[i].join(",") + ";", varDecl(pattPatts[i]));
   592         assertGlobalDecl("let " + pattSrcs[i].join(",") + ";", varDecl(pattPatts[i]));
   593         assertLocalDecl("let " + pattSrcs[i].join(",") + ";", varDecl(pattPatts[i]));
   594         assertBlockDecl("let " + pattSrcs[i].join(",") + ";", letDecl(pattPatts[i]));
   596         assertDecl("const " + pattSrcs[i].join(",") + ";", constDecl(pattPatts[i]));
   598         // variable declarations in for-loop heads
   599         assertStmt("for (var " + pattSrcs[i].join(",") + "; foo; bar);",
   600                    forStmt(varDecl(pattPatts[i]), ident("foo"), ident("bar"), emptyStmt));
   601         assertStmt("for (let " + pattSrcs[i].join(",") + "; foo; bar);",
   602                    letStmt(pattPatts[i], forStmt(null, ident("foo"), ident("bar"), emptyStmt)));
   603         assertStmt("for (const " + pattSrcs[i].join(",") + "; foo; bar);",
   604                    forStmt(constDecl(pattPatts[i]), ident("foo"), ident("bar"), emptyStmt));
   605     }
   606 }
   608 testVarPatternCombinations(function (n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "} = 0"),
   609                            function (n) ({ id: objPatt([{ key: ident("a" + n), value: ident("x" + n) },
   610                                                         { key: ident("b" + n), value: ident("y" + n) },
   611                                                         { key: ident("c" + n), value: ident("z" + n) }]),
   612                                            init: lit(0) }));
   614 testVarPatternCombinations(function(n) ("[x" + n + "," + "y" + n + "," + "z" + n + "] = 0"),
   615                            function(n) ({ id: arrPatt([ident("x" + n), ident("y" + n), ident("z" + n)]),
   616                                           init: lit(0) }));
   618 // destructuring assignment
   620 function testAssignmentCombinations(makePattSrc, makePattPatt) {
   621     var pattSrcs = makePatternCombinations(function(n) ("x" + n + " = 0"), makePattSrc);
   622     var pattPatts = makePatternCombinations(function(n) (aExpr("=", ident("x" + n), lit(0))), makePattPatt);
   624     for (var i = 0; i < pattSrcs.length; i++) {
   625         var src = pattSrcs[i].join(",");
   626         var patt = pattPatts[i].length === 1 ? pattPatts[i][0] : seqExpr(pattPatts[i]);
   628         // assignment expression statement
   629         assertExpr("(" + src + ")", patt);
   631         // for-loop head assignment
   632         assertStmt("for (" + src + "; foo; bar);",
   633                    forStmt(patt, ident("foo"), ident("bar"), emptyStmt));
   634     }
   635 }
   637 testAssignmentCombinations(function (n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "} = 0"),
   638                            function (n) (aExpr("=",
   639                                                objPatt([{ key: ident("a" + n), value: ident("x" + n) },
   640                                                         { key: ident("b" + n), value: ident("y" + n) },
   641                                                         { key: ident("c" + n), value: ident("z" + n) }]),
   642                                                lit(0))));
   645 // destructuring in for-in and for-each-in loop heads
   647 var axbycz = objPatt([{ key: ident("a"), value: ident("x") },
   648                       { key: ident("b"), value: ident("y") },
   649                       { key: ident("c"), value: ident("z") }]);
   650 var xyz = arrPatt([ident("x"), ident("y"), ident("z")]);
   652 assertStmt("for (var {a:x,b:y,c:z} in foo);", forInStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt));
   653 assertStmt("for (let {a:x,b:y,c:z} in foo);", forInStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt));
   654 assertStmt("for ({a:x,b:y,c:z} in foo);", forInStmt(axbycz, ident("foo"), emptyStmt));
   655 assertStmt("for (var [x,y,z] in foo);", forInStmt(varDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt));
   656 assertStmt("for (let [x,y,z] in foo);", forInStmt(letDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt));
   657 assertStmt("for ([x,y,z] in foo);", forInStmt(xyz, ident("foo"), emptyStmt));
   658 assertStmt("for (var {a:x,b:y,c:z} of foo);", forOfStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt));
   659 assertStmt("for (let {a:x,b:y,c:z} of foo);", forOfStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt));
   660 assertStmt("for ({a:x,b:y,c:z} of foo);", forOfStmt(axbycz, ident("foo"), emptyStmt));
   661 assertStmt("for (var [x,y,z] of foo);", forOfStmt(varDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt));
   662 assertStmt("for (let [x,y,z] of foo);", forOfStmt(letDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt));
   663 assertStmt("for ([x,y,z] of foo);", forOfStmt(xyz, ident("foo"), emptyStmt));
   664 assertStmt("for each (var {a:x,b:y,c:z} in foo);", forEachInStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt));
   665 assertStmt("for each (let {a:x,b:y,c:z} in foo);", forEachInStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt));
   666 assertStmt("for each ({a:x,b:y,c:z} in foo);", forEachInStmt(axbycz, ident("foo"), emptyStmt));
   667 assertStmt("for each (var [x,y,z] in foo);", forEachInStmt(varDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt));
   668 assertStmt("for each (let [x,y,z] in foo);", forEachInStmt(letDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt));
   669 assertStmt("for each ([x,y,z] in foo);", forEachInStmt(xyz, ident("foo"), emptyStmt));
   670 assertError("for (const x in foo);", SyntaxError);
   671 assertError("for (const {a:x,b:y,c:z} in foo);", SyntaxError);
   672 assertError("for (const [x,y,z] in foo);", SyntaxError);
   673 assertError("for (const x of foo);", SyntaxError);
   674 assertError("for (const {a:x,b:y,c:z} of foo);", SyntaxError);
   675 assertError("for (const [x,y,z] of foo);", SyntaxError);
   676 assertError("for each (const x in foo);", SyntaxError);
   677 assertError("for each (const {a:x,b:y,c:z} in foo);", SyntaxError);
   678 assertError("for each (const [x,y,z] in foo);", SyntaxError);
   680 // destructuring in for-in and for-each-in loop heads with initializers
   682 assertStmt("for (var {a:x,b:y,c:z} = 22 in foo);", forInStmt(varDecl([{ id: axbycz, init: lit(22) }]), ident("foo"), emptyStmt));
   683 assertStmt("for (var [x,y,z] = 22 in foo);", forInStmt(varDecl([{ id: xyz, init: lit(22) }]), ident("foo"), emptyStmt));
   684 assertStmt("for each (var {a:x,b:y,c:z} = 22 in foo);", forEachInStmt(varDecl([{ id: axbycz, init: lit(22) }]), ident("foo"), emptyStmt));
   685 assertStmt("for each (var [x,y,z] = 22 in foo);", forEachInStmt(varDecl([{ id: xyz, init: lit(22) }]), ident("foo"), emptyStmt));
   686 assertError("for (x = 22 in foo);", SyntaxError);
   687 assertError("for ({a:x,b:y,c:z} = 22 in foo);", SyntaxError);
   688 assertError("for ([x,y,z] = 22 in foo);", SyntaxError);
   689 assertError("for (const x = 22 in foo);", SyntaxError);
   690 assertError("for (const {a:x,b:y,c:z} = 22 in foo);", SyntaxError);
   691 assertError("for (const [x,y,z] = 22 in foo);", SyntaxError);
   692 assertError("for each (const x = 22 in foo);", SyntaxError);
   693 assertError("for each (const {a:x,b:y,c:z} = 22 in foo);", SyntaxError);
   694 assertError("for each (const [x,y,z] = 22 in foo);", SyntaxError);
   696 // expression closures
   698 assertDecl("function inc(x) (x + 1)", funDecl(ident("inc"), [ident("x")], binExpr("+", ident("x"), lit(1))));
   699 assertExpr("(function(x) (x+1))", funExpr(null, [ident("x")], binExpr("+"), ident("x"), lit(1)));
   701 // generators
   703 assertDecl("function gen(x) { yield }", genFunDecl(ident("gen"), [ident("x")], blockStmt([exprStmt(yieldExpr(null))])));
   704 assertExpr("(function(x) { yield })", genFunExpr(null, [ident("x")], blockStmt([exprStmt(yieldExpr(null))])));
   705 assertDecl("function gen(x) { yield 42 }", genFunDecl(ident("gen"), [ident("x")], blockStmt([exprStmt(yieldExpr(lit(42)))])));
   706 assertExpr("(function(x) { yield 42 })", genFunExpr(null, [ident("x")], blockStmt([exprStmt(yieldExpr(lit(42)))])));
   708 // getters and setters
   710 assertExpr("({ get x() { return 42 } })",
   711            objExpr([ { key: ident("x"),
   712                        value: funExpr(null, [], blockStmt([returnStmt(lit(42))])),
   713                        kind: "get" } ]));
   714 assertExpr("({ set x(v) { return 42 } })",
   715            objExpr([ { key: ident("x"),
   716                        value: funExpr(null, [ident("v")], blockStmt([returnStmt(lit(42))])),
   717                        kind: "set" } ]));
   719 // comprehensions
   721 assertExpr("[ x         for (x in foo)]",
   722            compExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], null));
   723 assertExpr("[ [x,y]     for (x in foo) for (y in bar)]",
   724            compExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], null));
   725 assertExpr("[ [x,y,z] for (x in foo) for (y in bar) for (z in baz)]",
   726            compExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
   727                     [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))],
   728                     null));
   730 assertExpr("[ x         for (x in foo) if (p)]",
   731            compExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], ident("p")));
   732 assertExpr("[ [x,y]     for (x in foo) for (y in bar) if (p)]",
   733            compExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], ident("p")));
   734 assertExpr("[ [x,y,z] for (x in foo) for (y in bar) for (z in baz) if (p) ]",
   735            compExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
   736                     [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))],
   737                     ident("p")));
   739 assertExpr("[ x         for each (x in foo)]",
   740            compExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], null));
   741 assertExpr("[ [x,y]     for each (x in foo) for each (y in bar)]",
   742            compExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], null));
   743 assertExpr("[ [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz)]",
   744            compExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
   745                     [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))],
   746                     null));
   748 assertExpr("[ x         for each (x in foo) if (p)]",
   749            compExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], ident("p")));
   750 assertExpr("[ [x,y]     for each (x in foo) for each (y in bar) if (p)]",
   751            compExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], ident("p")));
   752 assertExpr("[ [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz) if (p) ]",
   753            compExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
   754                     [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))],
   755                     ident("p")));
   757 assertExpr("[ x         for (x of foo)]",
   758            compExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], null));
   759 assertExpr("[ [x,y]     for (x of foo) for (y of bar)]",
   760            compExpr(arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], null));
   761 assertExpr("[ [x,y,z] for (x of foo) for (y of bar) for (z of baz)]",
   762            compExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
   763                     [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
   764                     null));
   766 assertExpr("[ x         for (x of foo) if (p)]",
   767            compExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], ident("p")));
   768 assertExpr("[ [x,y]     for (x of foo) for (y of bar) if (p)]",
   769            compExpr(arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], ident("p")));
   770 assertExpr("[ [x,y,z] for (x of foo) for (y of bar) for (z of baz) if (p) ]",
   771            compExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
   772                     [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
   773                     ident("p")));
   775 // generator expressions
   777 assertExpr("( x         for (x in foo))",
   778            genExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], null));
   779 assertExpr("( [x,y]     for (x in foo) for (y in bar))",
   780            genExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], null));
   781 assertExpr("( [x,y,z] for (x in foo) for (y in bar) for (z in baz))",
   782            genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
   783                    [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))],
   784                    null));
   786 assertExpr("( x         for (x in foo) if (p))",
   787            genExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], ident("p")));
   788 assertExpr("( [x,y]     for (x in foo) for (y in bar) if (p))",
   789            genExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], ident("p")));
   790 assertExpr("( [x,y,z] for (x in foo) for (y in bar) for (z in baz) if (p) )",
   791            genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
   792                    [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))],
   793                    ident("p")));
   795 assertExpr("( x         for each (x in foo))",
   796            genExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], null));
   797 assertExpr("( [x,y]     for each (x in foo) for each (y in bar))",
   798            genExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], null));
   799 assertExpr("( [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz))",
   800            genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
   801                    [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))],
   802                    null));
   804 assertExpr("( x         for each (x in foo) if (p))",
   805            genExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], ident("p")));
   806 assertExpr("( [x,y]     for each (x in foo) for each (y in bar) if (p))",
   807            genExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], ident("p")));
   808 assertExpr("( [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz) if (p) )",
   809            genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
   810                    [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))],
   811                    ident("p")));
   813 assertExpr("( x         for (x of foo))",
   814            genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], null));
   815 assertExpr("( [x,y]     for (x of foo) for (y of bar))",
   816            genExpr(arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], null));
   817 assertExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz))",
   818            genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
   819                    [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
   820                    null));
   822 assertExpr("( x         for (x of foo) if (p))",
   823            genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], ident("p")));
   824 assertExpr("( [x,y]     for (x of foo) for (y of bar) if (p))",
   825            genExpr(arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], ident("p")));
   826 assertExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz) if (p) )",
   827            genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
   828                    [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
   829                    ident("p")));
   831 // NOTE: it would be good to test generator expressions both with and without upvars, just like functions above.
   834 // let expressions
   836 assertExpr("(let (x=1) x)", letExpr([{ id: ident("x"), init: lit(1) }], ident("x")));
   837 assertExpr("(let (x=1,y=2) y)", letExpr([{ id: ident("x"), init: lit(1) },
   838                                          { id: ident("y"), init: lit(2) }],
   839                                         ident("y")));
   840 assertExpr("(let (x=1,y=2,z=3) z)", letExpr([{ id: ident("x"), init: lit(1) },
   841                                              { id: ident("y"), init: lit(2) },
   842                                              { id: ident("z"), init: lit(3) }],
   843                                             ident("z")));
   844 assertExpr("(let (x) x)", letExpr([{ id: ident("x"), init: null }], ident("x")));
   845 assertExpr("(let (x,y) y)", letExpr([{ id: ident("x"), init: null },
   846                                      { id: ident("y"), init: null }],
   847                                     ident("y")));
   848 assertExpr("(let (x,y,z) z)", letExpr([{ id: ident("x"), init: null },
   849                                        { id: ident("y"), init: null },
   850                                        { id: ident("z"), init: null }],
   851                                       ident("z")));
   852 assertExpr("(let (x = 1, y = x) y)", letExpr([{ id: ident("x"), init: lit(1) },
   853                                               { id: ident("y"), init: ident("x") }],
   854                                              ident("y")));
   855 assertError("(let (x = 1, x = 2) x)", TypeError);
   857 // let statements
   859 assertStmt("let (x=1) { }", letStmt([{ id: ident("x"), init: lit(1) }], blockStmt([])));
   860 assertStmt("let (x=1,y=2) { }", letStmt([{ id: ident("x"), init: lit(1) },
   861                                          { id: ident("y"), init: lit(2) }],
   862                                         blockStmt([])));
   863 assertStmt("let (x=1,y=2,z=3) { }", letStmt([{ id: ident("x"), init: lit(1) },
   864                                              { id: ident("y"), init: lit(2) },
   865                                              { id: ident("z"), init: lit(3) }],
   866                                             blockStmt([])));
   867 assertStmt("let (x) { }", letStmt([{ id: ident("x"), init: null }], blockStmt([])));
   868 assertStmt("let (x,y) { }", letStmt([{ id: ident("x"), init: null },
   869                                      { id: ident("y"), init: null }],
   870                                     blockStmt([])));
   871 assertStmt("let (x,y,z) { }", letStmt([{ id: ident("x"), init: null },
   872                                        { id: ident("y"), init: null },
   873                                        { id: ident("z"), init: null }],
   874                                       blockStmt([])));
   875 assertStmt("let (x = 1, y = x) { }", letStmt([{ id: ident("x"), init: lit(1) },
   876                                               { id: ident("y"), init: ident("x") }],
   877                                              blockStmt([])));
   878 assertError("let (x = 1, x = 2) { }", TypeError);
   881 // Bug 632024: no crashing on stack overflow
   882 try {
   883     Reflect.parse(Array(3000).join("x + y - ") + "z")
   884 } catch (e) { }
   887 // Source location information
   890 var withoutFileOrLine = Reflect.parse("42");
   891 var withFile = Reflect.parse("42", {source:"foo.js"});
   892 var withFileAndLine = Reflect.parse("42", {source:"foo.js", line:111});
   894 Pattern({ source: null, start: { line: 1, column: 0 }, end: { line: 1, column: 2 } }).match(withoutFileOrLine.loc);
   895 Pattern({ source: "foo.js", start: { line: 1, column: 0 }, end: { line: 1, column: 2 } }).match(withFile.loc);
   896 Pattern({ source: "foo.js", start: { line: 111, column: 0 }, end: { line: 111, column: 2 } }).match(withFileAndLine.loc);
   898 var withoutFileOrLine2 = Reflect.parse("foo +\nbar");
   899 var withFile2 = Reflect.parse("foo +\nbar", {source:"foo.js"});
   900 var withFileAndLine2 = Reflect.parse("foo +\nbar", {source:"foo.js", line:111});
   902 Pattern({ source: null, start: { line: 1, column: 0 }, end: { line: 2, column: 3 } }).match(withoutFileOrLine2.loc);
   903 Pattern({ source: "foo.js", start: { line: 1, column: 0 }, end: { line: 2, column: 3 } }).match(withFile2.loc);
   904 Pattern({ source: "foo.js", start: { line: 111, column: 0 }, end: { line: 112, column: 3 } }).match(withFileAndLine2.loc);
   906 var nested = Reflect.parse("(-b + sqrt(sqr(b) - 4 * a * c)) / (2 * a)", {source:"quad.js"});
   907 var fourAC = nested.body[0].expression.left.right.arguments[0].right;
   909 Pattern({ source: "quad.js", start: { line: 1, column: 20 }, end: { line: 1, column: 29 } }).match(fourAC.loc);
   912 // No source location
   914 assertEq(Reflect.parse("42", {loc:false}).loc, null);
   915 program([exprStmt(lit(42))]).assert(Reflect.parse("42", {loc:false}));
   918 // Builder tests
   920 Pattern("program").match(Reflect.parse("42", {builder:{program:function()"program"}}));
   922 assertGlobalStmt("throw 42", 1, { throwStatement: function() 1 });
   923 assertGlobalStmt("for (;;);", 2, { forStatement: function() 2 });
   924 assertGlobalStmt("for (x in y);", 3, { forInStatement: function() 3 });
   925 assertGlobalStmt("{ }", 4, { blockStatement: function() 4 });
   926 assertGlobalStmt("foo: { }", 5, { labeledStatement: function() 5 });
   927 assertGlobalStmt("with (o) { }", 6, { withStatement: function() 6 });
   928 assertGlobalStmt("while (x) { }", 7, { whileStatement: function() 7 });
   929 assertGlobalStmt("do { } while(false);", 8, { doWhileStatement: function() 8 });
   930 assertGlobalStmt("switch (x) { }", 9, { switchStatement: function() 9 });
   931 assertGlobalStmt("try { } catch(e) { }", 10, { tryStatement: function() 10 });
   932 assertGlobalStmt(";", 11, { emptyStatement: function() 11 });
   933 assertGlobalStmt("debugger;", 12, { debuggerStatement: function() 12 });
   934 assertGlobalStmt("42;", 13, { expressionStatement: function() 13 });
   935 assertGlobalStmt("for (;;) break", forStmt(null, null, null, 14), { breakStatement: function() 14 });
   936 assertGlobalStmt("for (;;) continue", forStmt(null, null, null, 15), { continueStatement: function() 15 });
   938 assertBlockDecl("var x", "var", { variableDeclaration: function(kind) kind });
   939 assertBlockDecl("let x", "let", { variableDeclaration: function(kind) kind });
   940 assertBlockDecl("const x", "const", { variableDeclaration: function(kind) kind });
   941 assertBlockDecl("function f() { }", "function", { functionDeclaration: function() "function" });
   943 assertGlobalExpr("(x,y,z)", 1, { sequenceExpression: function() 1 });
   944 assertGlobalExpr("(x ? y : z)", 2, { conditionalExpression: function() 2 });
   945 assertGlobalExpr("x + y", 3, { binaryExpression: function() 3 });
   946 assertGlobalExpr("delete x", 4, { unaryExpression: function() 4 });
   947 assertGlobalExpr("x = y", 5, { assignmentExpression: function() 5 });
   948 assertGlobalExpr("x || y", 6, { logicalExpression: function() 6 });
   949 assertGlobalExpr("x++", 7, { updateExpression: function() 7 });
   950 assertGlobalExpr("new x", 8, { newExpression: function() 8 });
   951 assertGlobalExpr("x()", 9, { callExpression: function() 9 });
   952 assertGlobalExpr("x.y", 10, { memberExpression: function() 10 });
   953 assertGlobalExpr("(function() { })", 11, { functionExpression: function() 11 });
   954 assertGlobalExpr("[1,2,3]", 12, { arrayExpression: function() 12 });
   955 assertGlobalExpr("({ x: y })", 13, { objectExpression: function() 13 });
   956 assertGlobalExpr("this", 14, { thisExpression: function() 14 });
   957 assertGlobalExpr("[x for (x in y)]", 17, { comprehensionExpression: function() 17 });
   958 assertGlobalExpr("(x for (x in y))", 18, { generatorExpression: function() 18 });
   959 assertGlobalExpr("(function() { yield 42 })", genFunExpr(null, [], blockStmt([exprStmt(19)])), { yieldExpression: function() 19 });
   960 assertGlobalExpr("(let (x) x)", 20, { letExpression: function() 20 });
   962 assertGlobalStmt("switch (x) { case y: }", switchStmt(ident("x"), [1]), { switchCase: function() 1 });
   963 assertGlobalStmt("try { } catch (e) { }", 2, { tryStatement: (function(b, g, u, f) u), catchClause: function() 2 });
   964 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 });
   965 assertGlobalStmt("try { } catch (e) { }", tryStmt(blockStmt([]), [], 2, null), { catchClause: function() 2 });
   966 assertGlobalStmt("try { } catch (e if e instanceof A) { } catch (e if e instanceof B) { }",
   967                  tryStmt(blockStmt([]), [2, 2], null, null),
   968                  { catchClause: function() 2 });
   969 assertGlobalExpr("[x for (y in z) for (x in y)]", compExpr(ident("x"), [3, 3], null), { comprehensionBlock: function() 3 });
   971 assertGlobalExpr("({ x: y } = z)", aExpr("=", 1, ident("z")), { objectPattern: function() 1 });
   972 assertGlobalExpr("({ x: y } = z)", aExpr("=", objPatt([2]), ident("z")), { propertyPattern: function() 2 });
   973 assertGlobalExpr("[ x ] = y", aExpr("=", 3, ident("y")), { arrayPattern: function() 3 });
   975 // Ensure that exceptions thrown by builder methods propagate.
   976 var thrown = false;
   977 try {
   978     Reflect.parse("42", { builder: { program: function() { throw "expected" } } });
   979 } catch (e if e === "expected") {
   980     thrown = true;
   981 }
   982 if (!thrown)
   983     throw new Error("builder exception not propagated");
   985 // Missing property RHS's in an object literal should throw.
   986 try {
   987     Reflect.parse("({foo})");
   988     throw new Error("object literal missing property RHS didn't throw");
   989 } catch (e if e instanceof SyntaxError) { }
   992 // A simple proof-of-concept that the builder API can be used to generate other
   993 // formats, such as JsonMLAst:
   994 // 
   995 //     http://code.google.com/p/es-lab/wiki/JsonMLASTFormat
   996 // 
   997 // It's incomplete (e.g., it doesn't convert source-location information and
   998 // doesn't use all the direct-eval rules), but I think it proves the point.
  1000 var JsonMLAst = (function() {
  1001 function reject() {
  1002     throw new SyntaxError("node type not supported");
  1005 function isDirectEval(expr) {
  1006     // an approximation to the actual rules. you get the idea
  1007     return (expr[0] === "IdExpr" && expr[1].name === "eval");
  1010 function functionNode(type) {
  1011     return function(id, args, body, isGenerator, isExpression) {
  1012         if (isExpression)
  1013             body = ["ReturnStmt", {}, body];
  1015         if (!id)
  1016             id = ["Empty"];
  1018         // Patch up the argument node types: s/IdExpr/IdPatt/g
  1019         for (var i = 0; i < args.length; i++) {
  1020             args[i][0] = "IdPatt";
  1023         args.unshift("ParamDecl", {});
  1025         return [type, {}, id, args, body];
  1029 return {
  1030     program: function(stmts) {
  1031         stmts.unshift("Program", {});
  1032         return stmts;
  1033     },
  1034     identifier: function(name) {
  1035         return ["IdExpr", { name: name }];
  1036     },
  1037     literal: function(val) {
  1038         return ["LiteralExpr", { value: val }];
  1039     },
  1040     expressionStatement: function(expr) expr,
  1041     conditionalExpression: function(test, cons, alt) {
  1042         return ["ConditionalExpr", {}, test, cons, alt];
  1043     },
  1044     unaryExpression: function(op, expr) {
  1045         return ["UnaryExpr", {op: op}, expr];
  1046     },
  1047     binaryExpression: function(op, left, right) {
  1048         return ["BinaryExpr", {op: op}, left, right];
  1049     },
  1050     property: function(kind, key, val) {
  1051         return [kind === "init"
  1052                 ? "DataProp"
  1053                 : kind === "get"
  1054                 ? "GetterProp"
  1055                 : "SetterProp",
  1056                 {name: key[1].name}, val];
  1057     },
  1058     functionDeclaration: functionNode("FunctionDecl"),
  1059     variableDeclaration: function(kind, elts) {
  1060         if (kind === "let" || kind === "const")
  1061             throw new SyntaxError("let and const not supported");
  1062         elts.unshift("VarDecl", {});
  1063         return elts;
  1064     },
  1065     variableDeclarator: function(id, init) {
  1066         id[0] = "IdPatt";
  1067         if (!init)
  1068             return id;
  1069         return ["InitPatt", {}, id, init];
  1070     },
  1071     sequenceExpression: function(exprs) {
  1072         var length = exprs.length;
  1073         var result = ["BinaryExpr", {op:","}, exprs[exprs.length - 2], exprs[exprs.length - 1]];
  1074         for (var i = exprs.length - 3; i >= 0; i--) {
  1075             result = ["BinaryExpr", {op:","}, exprs[i], result];
  1077         return result;
  1078     },
  1079     assignmentExpression: function(op, lhs, expr) {
  1080         return ["AssignExpr", {op: op}, lhs, expr];
  1081     },
  1082     logicalExpression: function(op, left, right) {
  1083         return [op === "&&" ? "LogicalAndExpr" : "LogicalOrExpr", {}, left, right];
  1084     },
  1085     updateExpression: function(expr, op, isPrefix) {
  1086         return ["CountExpr", {isPrefix:isPrefix, op:op}, expr];
  1087     },
  1088     newExpression: function(callee, args) {
  1089         args.unshift("NewExpr", {}, callee);
  1090         return args;
  1091     },
  1092     callExpression: function(callee, args) {
  1093         args.unshift(isDirectEval(callee) ? "EvalExpr" : "CallExpr", {}, callee);
  1094         return args;
  1095     },
  1096     memberExpression: function(isComputed, expr, member) {
  1097         return ["MemberExpr", {}, expr, isComputed ? member : ["LiteralExpr", {type: "string", value: member[1].name}]];
  1098     },
  1099     functionExpression: functionNode("FunctionExpr"),
  1100     arrayExpression: function(elts) {
  1101         for (var i = 0; i < elts.length; i++) {
  1102             if (!elts[i])
  1103                 elts[i] = ["Empty"];
  1105         elts.unshift("ArrayExpr", {});
  1106         return elts;
  1107     },
  1108     objectExpression: function(props) {
  1109         props.unshift("ObjectExpr", {});
  1110         return props;
  1111     },
  1112     thisExpression: function() {
  1113         return ["ThisExpr", {}];
  1114     },
  1116     graphExpression: reject,
  1117     graphIndexExpression: reject,
  1118     comprehensionExpression: reject,
  1119     generatorExpression: reject,
  1120     yieldExpression: reject,
  1121     letExpression: reject,
  1123     emptyStatement: function() ["EmptyStmt", {}],
  1124     blockStatement: function(stmts) {
  1125         stmts.unshift("BlockStmt", {});
  1126         return stmts;
  1127     },
  1128     labeledStatement: function(lab, stmt) {
  1129         return ["LabelledStmt", {label: lab}, stmt];
  1130     },
  1131     ifStatement: function(test, cons, alt) {
  1132         return ["IfStmt", {}, test, cons, alt || ["EmptyStmt", {}]];
  1133     },
  1134     switchStatement: function(test, clauses, isLexical) {
  1135         clauses.unshift("SwitchStmt", {}, test);
  1136         return clauses;
  1137     },
  1138     whileStatement: function(expr, stmt) {
  1139         return ["WhileStmt", {}, expr, stmt];
  1140     },
  1141     doWhileStatement: function(stmt, expr) {
  1142         return ["DoWhileStmt", {}, stmt, expr];
  1143     },
  1144     forStatement: function(init, test, update, body) {
  1145         return ["ForStmt", {}, init || ["Empty"], test || ["Empty"], update || ["Empty"], body];
  1146     },
  1147     forInStatement: function(lhs, rhs, body) {
  1148         return ["ForInStmt", {}, lhs, rhs, body];
  1149     },
  1150     breakStatement: function(lab) {
  1151         return lab ? ["BreakStmt", {}, lab] : ["BreakStmt", {}];
  1152     },
  1153     continueStatement: function(lab) {
  1154         return lab ? ["ContinueStmt", {}, lab] : ["ContinueStmt", {}];
  1155     },
  1156     withStatement: function(expr, stmt) {
  1157         return ["WithStmt", {}, expr, stmt];
  1158     },
  1159     returnStatement: function(expr) {
  1160         return expr ? ["ReturnStmt", {}, expr] : ["ReturnStmt", {}];
  1161     },
  1162     tryStatement: function(body, catches, fin) {
  1163         if (catches.length > 1)
  1164             throw new SyntaxError("multiple catch clauses not supported");
  1165         var node = ["TryStmt", body, catches[0] || ["Empty"]];
  1166         if (fin)
  1167             node.push(fin);
  1168         return node;
  1169     },
  1170     throwStatement: function(expr) {
  1171         return ["ThrowStmt", {}, expr];
  1172     },
  1173     debuggerStatement: function() ["DebuggerStmt", {}],
  1174     letStatement: reject,
  1175     switchCase: function(expr, stmts) {
  1176         if (expr)
  1177             stmts.unshift("SwitchCase", {}, expr);
  1178         else
  1179             stmts.unshift("DefaultCase", {});
  1180         return stmts;
  1181     },
  1182     catchClause: function(param, guard, body) {
  1183         if (guard)
  1184             throw new SyntaxError("catch guards not supported");
  1185         param[0] = "IdPatt";
  1186         return ["CatchClause", {}, param, body];
  1187     },
  1188     comprehensionBlock: reject,
  1190     arrayPattern: reject,
  1191     objectPattern: reject,
  1192     propertyPattern: reject,
  1193 };
  1194 })();
  1196 Pattern(["Program", {},
  1197          ["BinaryExpr", {op: "+"},
  1198           ["LiteralExpr", {value: 2}],
  1199           ["BinaryExpr", {op: "*"},
  1200            ["UnaryExpr", {op: "-"}, ["IdExpr", {name: "x"}]],
  1201            ["IdExpr", {name: "y"}]]]]).match(Reflect.parse("2 + (-x * y)", {loc: false, builder: JsonMLAst}));
  1203 reportCompare(true, true);
  1205 });

mercurial