mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1065450 - Make Reflect.parse properly handle new-style array comprehensions and generator expressions. r=Waldo.
--HG-- extra : rebase_source : 07009c087b787880d147d362ddebdbd1f88453c4 extra : source : a37b8adef57b541329674f41720d3c0c71a46d54
This commit is contained in:
parent
fb845401b2
commit
79882186b4
@ -773,8 +773,8 @@ class ParseNode
|
||||
MOZ_ASSERT(isKind(PNK_GENEXP));
|
||||
ParseNode *callee = this->pn_head;
|
||||
ParseNode *body = callee->pn_body;
|
||||
MOZ_ASSERT(body->isKind(PNK_LEXICALSCOPE));
|
||||
return body->pn_expr;
|
||||
MOZ_ASSERT(body->isKind(PNK_LEXICALSCOPE) || body->isKind(PNK_FOR));
|
||||
return body;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -670,10 +670,10 @@ class NodeBuilder
|
||||
MutableHandleValue dst);
|
||||
|
||||
bool comprehensionExpression(HandleValue body, NodeVector &blocks, HandleValue filter,
|
||||
TokenPos *pos, MutableHandleValue dst);
|
||||
bool isLegacy, TokenPos *pos, MutableHandleValue dst);
|
||||
|
||||
bool generatorExpression(HandleValue body, NodeVector &blocks, HandleValue filter,
|
||||
TokenPos *pos, MutableHandleValue dst);
|
||||
bool isLegacy, TokenPos *pos, MutableHandleValue dst);
|
||||
|
||||
bool letExpression(NodeVector &head, HandleValue expr, TokenPos *pos, MutableHandleValue dst);
|
||||
|
||||
@ -1411,39 +1411,49 @@ NodeBuilder::comprehensionBlock(HandleValue patt, HandleValue src, bool isForEac
|
||||
|
||||
bool
|
||||
NodeBuilder::comprehensionExpression(HandleValue body, NodeVector &blocks, HandleValue filter,
|
||||
TokenPos *pos, MutableHandleValue dst)
|
||||
bool isLegacy, TokenPos *pos, MutableHandleValue dst)
|
||||
{
|
||||
RootedValue array(cx);
|
||||
if (!newArray(blocks, &array))
|
||||
return false;
|
||||
|
||||
RootedValue style(cx);
|
||||
if (!atomValue(isLegacy ? "legacy" : "modern", &style))
|
||||
return false;
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_COMP_EXPR]);
|
||||
if (!cb.isNull())
|
||||
return callback(cb, body, array, opt(filter), pos, dst);
|
||||
return callback(cb, body, array, opt(filter), style, pos, dst);
|
||||
|
||||
return newNode(AST_COMP_EXPR, pos,
|
||||
"body", body,
|
||||
"blocks", array,
|
||||
"filter", filter,
|
||||
"style", style,
|
||||
dst);
|
||||
}
|
||||
|
||||
bool
|
||||
NodeBuilder::generatorExpression(HandleValue body, NodeVector &blocks, HandleValue filter,
|
||||
TokenPos *pos, MutableHandleValue dst)
|
||||
bool isLegacy, TokenPos *pos, MutableHandleValue dst)
|
||||
{
|
||||
RootedValue array(cx);
|
||||
if (!newArray(blocks, &array))
|
||||
return false;
|
||||
|
||||
RootedValue style(cx);
|
||||
if (!atomValue(isLegacy ? "legacy" : "modern", &style))
|
||||
return false;
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_GENERATOR_EXPR]);
|
||||
if (!cb.isNull())
|
||||
return callback(cb, body, array, opt(filter), pos, dst);
|
||||
return callback(cb, body, array, opt(filter), style, pos, dst);
|
||||
|
||||
return newNode(AST_GENERATOR_EXPR, pos,
|
||||
"body", body,
|
||||
"blocks", array,
|
||||
"filter", filter,
|
||||
"style", style,
|
||||
dst);
|
||||
}
|
||||
|
||||
@ -2577,7 +2587,7 @@ ASTSerializer::comprehensionBlock(ParseNode *pn, MutableHandleValue dst)
|
||||
|
||||
LOCAL_ASSERT(in && (in->isKind(PNK_FORIN) || in->isKind(PNK_FOROF)));
|
||||
|
||||
bool isForEach = pn->pn_iflags & JSITER_FOREACH;
|
||||
bool isForEach = in->isKind(PNK_FORIN) && (pn->pn_iflags & JSITER_FOREACH);
|
||||
bool isForOf = in->isKind(PNK_FOROF);
|
||||
|
||||
RootedValue patt(cx), src(cx);
|
||||
@ -2589,11 +2599,16 @@ ASTSerializer::comprehensionBlock(ParseNode *pn, MutableHandleValue dst)
|
||||
bool
|
||||
ASTSerializer::comprehension(ParseNode *pn, MutableHandleValue dst)
|
||||
{
|
||||
LOCAL_ASSERT(pn->isKind(PNK_FOR));
|
||||
// There are two array comprehension flavors.
|
||||
// 1. The kind that was in ES4 for a while: [z for (x in y)]
|
||||
// 2. The kind that was in ES6 for a while: [for (x of y) z]
|
||||
// They have slightly different parse trees and scoping.
|
||||
bool isLegacy = pn->isKind(PNK_LEXICALSCOPE);
|
||||
ParseNode *next = isLegacy ? pn->pn_expr : pn;
|
||||
LOCAL_ASSERT(next->isKind(PNK_FOR));
|
||||
|
||||
NodeVector blocks(cx);
|
||||
|
||||
ParseNode *next = pn;
|
||||
while (next->isKind(PNK_FOR)) {
|
||||
RootedValue block(cx);
|
||||
if (!comprehensionBlock(next, &block) || !blocks.append(block))
|
||||
@ -2618,17 +2633,21 @@ ASTSerializer::comprehension(ParseNode *pn, MutableHandleValue dst)
|
||||
RootedValue body(cx);
|
||||
|
||||
return expression(next->pn_kid, &body) &&
|
||||
builder.comprehensionExpression(body, blocks, filter, &pn->pn_pos, dst);
|
||||
builder.comprehensionExpression(body, blocks, filter, isLegacy, &pn->pn_pos, dst);
|
||||
}
|
||||
|
||||
bool
|
||||
ASTSerializer::generatorExpression(ParseNode *pn, MutableHandleValue dst)
|
||||
{
|
||||
LOCAL_ASSERT(pn->isKind(PNK_FOR));
|
||||
// Just as there are two kinds of array comprehension (see
|
||||
// ASTSerializer::comprehension), there are legacy and modern generator
|
||||
// expression.
|
||||
bool isLegacy = pn->isKind(PNK_LEXICALSCOPE);
|
||||
ParseNode *next = isLegacy ? pn->pn_expr : pn;
|
||||
LOCAL_ASSERT(next->isKind(PNK_FOR));
|
||||
|
||||
NodeVector blocks(cx);
|
||||
|
||||
ParseNode *next = pn;
|
||||
while (next->isKind(PNK_FOR)) {
|
||||
RootedValue block(cx);
|
||||
if (!comprehensionBlock(next, &block) || !blocks.append(block))
|
||||
@ -2651,7 +2670,7 @@ ASTSerializer::generatorExpression(ParseNode *pn, MutableHandleValue dst)
|
||||
RootedValue body(cx);
|
||||
|
||||
return expression(next->pn_kid->pn_kid, &body) &&
|
||||
builder.generatorExpression(body, blocks, filter, &pn->pn_pos, dst);
|
||||
builder.generatorExpression(body, blocks, filter, isLegacy, &pn->pn_pos, dst);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2998,9 +3017,7 @@ ASTSerializer::expression(ParseNode *pn, MutableHandleValue dst)
|
||||
|
||||
/* NB: it's no longer the case that pn_count could be 2. */
|
||||
LOCAL_ASSERT(pn->pn_count == 1);
|
||||
LOCAL_ASSERT(pn->pn_head->isKind(PNK_LEXICALSCOPE));
|
||||
|
||||
return comprehension(pn->pn_head->pn_expr, dst);
|
||||
return comprehension(pn->pn_head, dst);
|
||||
|
||||
case PNK_LET:
|
||||
return let(pn, true, dst);
|
||||
|
@ -99,8 +99,8 @@ function taggedTemplate(tagPart, templatePart) Pattern({ type: "TaggedTemplate",
|
||||
arguments : templatePart })
|
||||
function template(raw, cooked, ...args) Pattern([{ type: "CallSiteObject", raw: raw, cooked:
|
||||
cooked}, ...args])
|
||||
function compExpr(body, blocks, filter) Pattern({ type: "ComprehensionExpression", body: body, blocks: blocks, filter: filter })
|
||||
function genExpr(body, blocks, filter) Pattern({ type: "GeneratorExpression", body: body, blocks: blocks, filter: filter })
|
||||
function compExpr(body, blocks, filter, style) Pattern({ type: "ComprehensionExpression", body, blocks, filter, style })
|
||||
function genExpr(body, blocks, filter, style) Pattern({ type: "GeneratorExpression", body, blocks, filter, style })
|
||||
function graphExpr(idx, body) Pattern({ type: "GraphExpression", index: idx, expression: body })
|
||||
function letExpr(head, body) Pattern({ type: "LetExpression", head: head, body: body })
|
||||
function idxExpr(idx) Pattern({ type: "GraphIndexExpression", index: idx })
|
||||
@ -381,7 +381,7 @@ assertExpr("2 + 3", binExpr("+", lit(2), lit(3)));
|
||||
assertExpr("typeof(0?0:a)", unExpr("typeof", condExpr(lit(0), lit(0), ident("a"))));
|
||||
|
||||
// Bug 632029: constant-folding
|
||||
assertExpr("[x for each (x in y) if (false)]", compExpr(ident("x"), [compEachBlock(ident("x"), ident("y"))], lit(false)));
|
||||
assertExpr("[x for each (x in y) if (false)]", compExpr(ident("x"), [compEachBlock(ident("x"), ident("y"))], lit(false), "legacy"));
|
||||
|
||||
// Bug 632056: constant-folding
|
||||
program([exprStmt(ident("f")),
|
||||
@ -814,114 +814,146 @@ assertExpr("({ set x(v) { return 42 } })",
|
||||
// comprehensions
|
||||
|
||||
assertExpr("[ x for (x in foo)]",
|
||||
compExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], null));
|
||||
compExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], null, "legacy"));
|
||||
assertExpr("[ [x,y] for (x in foo) for (y in bar)]",
|
||||
compExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], null));
|
||||
compExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], null, "legacy"));
|
||||
assertExpr("[ [x,y,z] for (x in foo) for (y in bar) for (z in baz)]",
|
||||
compExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))],
|
||||
null));
|
||||
null,
|
||||
"legacy"));
|
||||
|
||||
assertExpr("[ x for (x in foo) if (p)]",
|
||||
compExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], ident("p")));
|
||||
compExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], ident("p"), "legacy"));
|
||||
assertExpr("[ [x,y] for (x in foo) for (y in bar) if (p)]",
|
||||
compExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], ident("p")));
|
||||
compExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], ident("p"), "legacy"));
|
||||
assertExpr("[ [x,y,z] for (x in foo) for (y in bar) for (z in baz) if (p) ]",
|
||||
compExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))],
|
||||
ident("p")));
|
||||
ident("p"),
|
||||
"legacy"));
|
||||
|
||||
assertExpr("[ x for each (x in foo)]",
|
||||
compExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], null));
|
||||
compExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], null, "legacy"));
|
||||
assertExpr("[ [x,y] for each (x in foo) for each (y in bar)]",
|
||||
compExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], null));
|
||||
compExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], null, "legacy"));
|
||||
assertExpr("[ [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz)]",
|
||||
compExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))],
|
||||
null));
|
||||
null,
|
||||
"legacy"));
|
||||
|
||||
assertExpr("[ x for each (x in foo) if (p)]",
|
||||
compExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], ident("p")));
|
||||
compExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], ident("p"), "legacy"));
|
||||
assertExpr("[ [x,y] for each (x in foo) for each (y in bar) if (p)]",
|
||||
compExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], ident("p")));
|
||||
compExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], ident("p"), "legacy"));
|
||||
assertExpr("[ [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz) if (p) ]",
|
||||
compExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))],
|
||||
ident("p")));
|
||||
ident("p"),
|
||||
"legacy"));
|
||||
|
||||
assertExpr("[ x for (x of foo)]",
|
||||
compExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], null));
|
||||
assertExpr("[ [x,y] for (x of foo) for (y of bar)]",
|
||||
compExpr(arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], null));
|
||||
assertExpr("[ [x,y,z] for (x of foo) for (y of bar) for (z of baz)]",
|
||||
compExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
|
||||
null));
|
||||
// Comprehension expressions using for-of can be written in two different styles.
|
||||
function assertLegacyAndModernArrayComp(expr, body, blocks, filter) {
|
||||
assertExpr(expr, compExpr(body, blocks, filter, "legacy"));
|
||||
|
||||
assertExpr("[ x for (x of foo) if (p)]",
|
||||
compExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], ident("p")));
|
||||
assertExpr("[ [x,y] for (x of foo) for (y of bar) if (p)]",
|
||||
compExpr(arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], ident("p")));
|
||||
assertExpr("[ [x,y,z] for (x of foo) for (y of bar) for (z of baz) if (p) ]",
|
||||
compExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
|
||||
ident("p")));
|
||||
// Transform the legacy comprehension to a modern comprehension and test it
|
||||
// that way too.
|
||||
let match = expr.match(/^\[(.*?) for (.*)\]$/);
|
||||
assertEq(match !== null, true);
|
||||
let expr2 = "[for " + match[2] + " " + match[1] + "]";
|
||||
assertExpr(expr2, compExpr(body, blocks, filter, "modern"));
|
||||
}
|
||||
|
||||
assertLegacyAndModernArrayComp("[ x for (x of foo)]",
|
||||
ident("x"), [compOfBlock(ident("x"), ident("foo"))], null);
|
||||
assertLegacyAndModernArrayComp("[ [x,y] for (x of foo) for (y of bar)]",
|
||||
arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], null);
|
||||
assertLegacyAndModernArrayComp("[ [x,y,z] for (x of foo) for (y of bar) for (z of baz)]",
|
||||
arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
|
||||
null);
|
||||
|
||||
assertLegacyAndModernArrayComp("[ x for (x of foo) if (p)]",
|
||||
ident("x"), [compOfBlock(ident("x"), ident("foo"))], ident("p"));
|
||||
assertLegacyAndModernArrayComp("[ [x,y] for (x of foo) for (y of bar) if (p)]",
|
||||
arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], ident("p"));
|
||||
assertLegacyAndModernArrayComp("[ [x,y,z] for (x of foo) for (y of bar) for (z of baz) if (p) ]",
|
||||
arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
|
||||
ident("p"));
|
||||
|
||||
// generator expressions
|
||||
|
||||
assertExpr("( x for (x in foo))",
|
||||
genExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], null));
|
||||
genExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], null, "legacy"));
|
||||
assertExpr("( [x,y] for (x in foo) for (y in bar))",
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], null));
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], null, "legacy"));
|
||||
assertExpr("( [x,y,z] for (x in foo) for (y in bar) for (z in baz))",
|
||||
genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))],
|
||||
null));
|
||||
null,
|
||||
"legacy"));
|
||||
|
||||
assertExpr("( x for (x in foo) if (p))",
|
||||
genExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], ident("p")));
|
||||
genExpr(ident("x"), [compBlock(ident("x"), ident("foo"))], ident("p"), "legacy"));
|
||||
assertExpr("( [x,y] for (x in foo) for (y in bar) if (p))",
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], ident("p")));
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar"))], ident("p"), "legacy"));
|
||||
assertExpr("( [x,y,z] for (x in foo) for (y in bar) for (z in baz) if (p) )",
|
||||
genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compBlock(ident("x"), ident("foo")), compBlock(ident("y"), ident("bar")), compBlock(ident("z"), ident("baz"))],
|
||||
ident("p")));
|
||||
ident("p"),
|
||||
"legacy"));
|
||||
|
||||
assertExpr("( x for each (x in foo))",
|
||||
genExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], null));
|
||||
genExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], null, "legacy"));
|
||||
assertExpr("( [x,y] for each (x in foo) for each (y in bar))",
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], null));
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], null, "legacy"));
|
||||
assertExpr("( [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz))",
|
||||
genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))],
|
||||
null));
|
||||
null,
|
||||
"legacy"));
|
||||
|
||||
assertExpr("( x for each (x in foo) if (p))",
|
||||
genExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], ident("p")));
|
||||
genExpr(ident("x"), [compEachBlock(ident("x"), ident("foo"))], ident("p"), "legacy"));
|
||||
assertExpr("( [x,y] for each (x in foo) for each (y in bar) if (p))",
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], ident("p")));
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar"))], ident("p"), "legacy"));
|
||||
assertExpr("( [x,y,z] for each (x in foo) for each (y in bar) for each (z in baz) if (p) )",
|
||||
genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compEachBlock(ident("x"), ident("foo")), compEachBlock(ident("y"), ident("bar")), compEachBlock(ident("z"), ident("baz"))],
|
||||
ident("p")));
|
||||
ident("p"),
|
||||
"legacy"));
|
||||
|
||||
assertExpr("( x for (x of foo))",
|
||||
genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], null));
|
||||
assertExpr("( [x,y] for (x of foo) for (y of bar))",
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], null));
|
||||
assertExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz))",
|
||||
genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
|
||||
null));
|
||||
// Generator expressions using for-of can be written in two different styles.
|
||||
function assertLegacyAndModernGenExpr(expr, body, blocks, filter) {
|
||||
assertExpr(expr, genExpr(body, blocks, filter, "legacy"));
|
||||
|
||||
assertExpr("( x for (x of foo) if (p))",
|
||||
genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], ident("p")));
|
||||
assertExpr("( [x,y] for (x of foo) for (y of bar) if (p))",
|
||||
genExpr(arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], ident("p")));
|
||||
assertExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz) if (p) )",
|
||||
genExpr(arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
|
||||
ident("p")));
|
||||
// Transform the legacy genexpr to a modern genexpr and test it that way
|
||||
// too.
|
||||
let match = expr.match(/^\((.*?) for (.*)\)$/);
|
||||
assertEq(match !== null, true);
|
||||
let expr2 = "(for " + match[2] + " " + match[1] + ")";
|
||||
assertExpr(expr2, genExpr(body, blocks, filter, "modern"));
|
||||
}
|
||||
|
||||
assertLegacyAndModernGenExpr("( x for (x of foo))",
|
||||
ident("x"), [compOfBlock(ident("x"), ident("foo"))], null);
|
||||
assertLegacyAndModernGenExpr("( [x,y] for (x of foo) for (y of bar))",
|
||||
arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], null);
|
||||
assertLegacyAndModernGenExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz))",
|
||||
arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
|
||||
null);
|
||||
|
||||
assertLegacyAndModernGenExpr("( x for (x of foo) if (p))",
|
||||
ident("x"), [compOfBlock(ident("x"), ident("foo"))], ident("p"));
|
||||
assertLegacyAndModernGenExpr("( [x,y] for (x of foo) for (y of bar) if (p))",
|
||||
arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], ident("p"));
|
||||
assertLegacyAndModernGenExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz) if (p) )",
|
||||
arrExpr([ident("x"), ident("y"), ident("z")]),
|
||||
[compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))],
|
||||
ident("p"));
|
||||
|
||||
// NOTE: it would be good to test generator expressions both with and without upvars, just like functions above.
|
||||
|
||||
@ -1061,7 +1093,9 @@ assertGlobalStmt("try { } catch (e) { }", tryStmt(blockStmt([]), [], 2, null), {
|
||||
assertGlobalStmt("try { } catch (e if e instanceof A) { } catch (e if e instanceof B) { }",
|
||||
tryStmt(blockStmt([]), [2, 2], null, null),
|
||||
{ catchClause: function() 2 });
|
||||
assertGlobalExpr("[x for (y in z) for (x in y)]", compExpr(ident("x"), [3, 3], null), { comprehensionBlock: function() 3 });
|
||||
assertGlobalExpr("[x for (y in z) for (x in y)]",
|
||||
compExpr(ident("x"), [3, 3], null, "legacy"),
|
||||
{ comprehensionBlock: function() 3 });
|
||||
|
||||
assertGlobalExpr("({ x: y } = z)", aExpr("=", 1, ident("z")), { objectPattern: function() 1 });
|
||||
assertGlobalExpr("({ x: y } = z)", aExpr("=", objPatt([2]), ident("z")), { propertyPattern: function() 2 });
|
||||
|
Loading…
Reference in New Issue
Block a user