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