зеркало из https://github.com/mozilla/gecko-dev.git
Bug 725702: support for of loops in Reflect.parse r=dherman
This commit is contained in:
Родитель
46b8734135
Коммит
f480ac0a64
|
@ -48,6 +48,7 @@ ASTDEF(AST_WHILE_STMT, "WhileStatement", "whileStatem
|
|||
ASTDEF(AST_DO_STMT, "DoWhileStatement", "doWhileStatement")
|
||||
ASTDEF(AST_FOR_STMT, "ForStatement", "forStatement")
|
||||
ASTDEF(AST_FOR_IN_STMT, "ForInStatement", "forInStatement")
|
||||
ASTDEF(AST_FOR_OF_STMT, "ForOfStatement", "forOfStatement")
|
||||
ASTDEF(AST_BREAK_STMT, "BreakStatement", "breakStatement")
|
||||
ASTDEF(AST_CONTINUE_STMT, "ContinueStatement", "continueStatement")
|
||||
ASTDEF(AST_WITH_STMT, "WithStatement", "withStatement")
|
||||
|
|
|
@ -496,6 +496,9 @@ class NodeBuilder
|
|||
bool forInStatement(Value var, Value expr, Value stmt,
|
||||
bool isForEach, TokenPos *pos, Value *dst);
|
||||
|
||||
bool forOfStatement(Value var, Value expr, Value stmt, TokenPos *pos, Value *dst);
|
||||
|
||||
|
||||
bool withStatement(Value expr, Value stmt, TokenPos *pos, Value *dst);
|
||||
|
||||
bool whileStatement(Value test, Value stmt, TokenPos *pos, Value *dst);
|
||||
|
@ -839,6 +842,20 @@ NodeBuilder::forInStatement(Value var, Value expr, Value stmt, bool isForEach,
|
|||
dst);
|
||||
}
|
||||
|
||||
bool
|
||||
NodeBuilder::forOfStatement(Value var, Value expr, Value stmt, TokenPos *pos, Value *dst)
|
||||
{
|
||||
Value cb = callbacks[AST_FOR_OF_STMT];
|
||||
if (!cb.isNull())
|
||||
return callback(cb, var, expr, stmt, pos, dst);
|
||||
|
||||
return newNode(AST_FOR_OF_STMT, pos,
|
||||
"left", var,
|
||||
"right", expr,
|
||||
"body", stmt,
|
||||
dst);
|
||||
}
|
||||
|
||||
bool
|
||||
NodeBuilder::withStatement(Value expr, Value stmt, TokenPos *pos, Value *dst)
|
||||
{
|
||||
|
@ -1612,6 +1629,7 @@ class ASTSerializer
|
|||
}
|
||||
|
||||
bool forInit(ParseNode *pn, Value *dst);
|
||||
bool forOfOrIn(ParseNode *loop, ParseNode *head, Value var, Value stmt, Value *dst);
|
||||
bool statement(ParseNode *pn, Value *dst);
|
||||
bool blockStatement(ParseNode *pn, Value *dst);
|
||||
bool switchStatement(ParseNode *pn, Value *dst);
|
||||
|
@ -2072,6 +2090,19 @@ ASTSerializer::forInit(ParseNode *pn, Value *dst)
|
|||
: expression(pn, dst);
|
||||
}
|
||||
|
||||
bool
|
||||
ASTSerializer::forOfOrIn(ParseNode *loop, ParseNode *head, Value var, Value stmt, Value *dst)
|
||||
{
|
||||
Value expr;
|
||||
bool isForEach = loop->pn_iflags & JSITER_FOREACH;
|
||||
bool isForOf = loop->pn_iflags & JSITER_FOR_OF;
|
||||
JS_ASSERT(!isForOf || !isForEach);
|
||||
|
||||
return expression(head->pn_kid3, &expr) &&
|
||||
(isForOf ? builder.forOfStatement(var, expr, stmt, &loop->pn_pos, dst) :
|
||||
builder.forInStatement(var, expr, stmt, isForEach, &loop->pn_pos, dst));
|
||||
}
|
||||
|
||||
bool
|
||||
ASTSerializer::statement(ParseNode *pn, Value *dst)
|
||||
{
|
||||
|
@ -2153,18 +2184,14 @@ ASTSerializer::statement(ParseNode *pn, Value *dst)
|
|||
if (!statement(pn->pn_right, &stmt))
|
||||
return false;
|
||||
|
||||
bool isForEach = pn->pn_iflags & JSITER_FOREACH;
|
||||
|
||||
if (head->isKind(PNK_FORIN)) {
|
||||
Value var, expr;
|
||||
|
||||
Value var;
|
||||
return (!head->pn_kid1
|
||||
? pattern(head->pn_kid2, NULL, &var)
|
||||
: head->pn_kid1->isKind(PNK_LEXICALSCOPE)
|
||||
? variableDeclaration(head->pn_kid1->pn_expr, true, &var)
|
||||
: variableDeclaration(head->pn_kid1, false, &var)) &&
|
||||
expression(head->pn_kid3, &expr) &&
|
||||
builder.forInStatement(var, expr, stmt, isForEach, &pn->pn_pos, dst);
|
||||
? variableDeclaration(head->pn_kid1->pn_expr, true, &var)
|
||||
: variableDeclaration(head->pn_kid1, false, &var)) &&
|
||||
forOfOrIn(pn, head, var, stmt, dst);
|
||||
}
|
||||
|
||||
Value init, test, update;
|
||||
|
@ -2192,13 +2219,9 @@ ASTSerializer::statement(ParseNode *pn, Value *dst)
|
|||
ParseNode *head = loop->pn_left;
|
||||
JS_ASSERT(head->isKind(PNK_FORIN));
|
||||
|
||||
bool isForEach = loop->pn_iflags & JSITER_FOREACH;
|
||||
Value stmt;
|
||||
|
||||
Value expr, stmt;
|
||||
|
||||
return expression(head->pn_kid3, &expr) &&
|
||||
statement(loop->pn_right, &stmt) &&
|
||||
builder.forInStatement(var, expr, stmt, isForEach, &pn->pn_pos, dst);
|
||||
return statement(loop->pn_right, &stmt) && forOfOrIn(loop, head, var, stmt, dst);
|
||||
}
|
||||
|
||||
case PNK_BREAK:
|
||||
|
|
|
@ -47,6 +47,7 @@ function ident(name) Pattern({ type: "Identifier", name: name })
|
|||
function dotExpr(obj, id) Pattern({ type: "MemberExpression", computed: false, object: obj, property: id })
|
||||
function memExpr(obj, id) Pattern({ type: "MemberExpression", computed: true, object: obj, property: id })
|
||||
function forStmt(init, test, update, body) Pattern({ type: "ForStatement", init: init, test: test, update: update, body: body })
|
||||
function forOfStmt(lhs, rhs, body) Pattern({ type: "ForOfStatement", left: lhs, right: rhs, body: body })
|
||||
function forInStmt(lhs, rhs, body) Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: false })
|
||||
function forEachInStmt(lhs, rhs, body) Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: true })
|
||||
function breakStmt(lab) Pattern({ type: "BreakStatement", label: lab })
|
||||
|
@ -648,6 +649,12 @@ assertStmt("for ({a:x,b:y,c:z} in foo);", forInStmt(axbycz, ident("foo"), emptyS
|
|||
assertStmt("for (var [x,y,z] in foo);", forInStmt(varDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for (let [x,y,z] in foo);", forInStmt(letDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for ([x,y,z] in foo);", forInStmt(xyz, ident("foo"), emptyStmt));
|
||||
assertStmt("for (var {a:x,b:y,c:z} of foo);", forOfStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for (let {a:x,b:y,c:z} of foo);", forOfStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for ({a:x,b:y,c:z} of foo);", forOfStmt(axbycz, ident("foo"), emptyStmt));
|
||||
assertStmt("for (var [x,y,z] of foo);", forOfStmt(varDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for (let [x,y,z] of foo);", forOfStmt(letDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for ([x,y,z] of foo);", forOfStmt(xyz, ident("foo"), emptyStmt));
|
||||
assertStmt("for each (var {a:x,b:y,c:z} in foo);", forEachInStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for each (let {a:x,b:y,c:z} in foo);", forEachInStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for each ({a:x,b:y,c:z} in foo);", forEachInStmt(axbycz, ident("foo"), emptyStmt));
|
||||
|
@ -657,6 +664,9 @@ assertStmt("for each ([x,y,z] in foo);", forEachInStmt(xyz, ident("foo"), emptyS
|
|||
assertError("for (const x in foo);", SyntaxError);
|
||||
assertError("for (const {a:x,b:y,c:z} in foo);", SyntaxError);
|
||||
assertError("for (const [x,y,z] in foo);", SyntaxError);
|
||||
assertError("for (const x of foo);", SyntaxError);
|
||||
assertError("for (const {a:x,b:y,c:z} of foo);", SyntaxError);
|
||||
assertError("for (const [x,y,z] of foo);", SyntaxError);
|
||||
assertError("for each (const x in foo);", SyntaxError);
|
||||
assertError("for each (const {a:x,b:y,c:z} in foo);", SyntaxError);
|
||||
assertError("for each (const [x,y,z] in foo);", SyntaxError);
|
||||
|
@ -665,6 +675,8 @@ assertError("for each (const [x,y,z] in foo);", SyntaxError);
|
|||
|
||||
assertStmt("for (var {a:x,b:y,c:z} = 22 in foo);", forInStmt(varDecl([{ id: axbycz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for (var [x,y,z] = 22 in foo);", forInStmt(varDecl([{ id: xyz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for (var {a:x,b:y,c:z} = 22 of foo);", forOfStmt(varDecl([{ id: axbycz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for (var [x,y,z] = 22 of foo);", forOfStmt(varDecl([{ id: xyz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for each (var {a:x,b:y,c:z} = 22 in foo);", forEachInStmt(varDecl([{ id: axbycz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertStmt("for each (var [x,y,z] = 22 in foo);", forEachInStmt(varDecl([{ id: xyz, init: lit(22) }]), ident("foo"), emptyStmt));
|
||||
assertError("for (x = 22 in foo);", SyntaxError);
|
||||
|
|
Загрузка…
Ссылка в новой задаче