зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1124480: fix destructuring defaults inside for-in loops; r=jorendorff
--HG-- extra : rebase_source : ed77c5ff4ff7859c15e6d099706c35f9acbfe628
This commit is contained in:
Родитель
ba5bfc9e79
Коммит
628c7a579f
|
@ -423,6 +423,31 @@ Parser<FullParseHandler>::cloneParseTree(ParseNode *opn)
|
|||
return pn;
|
||||
}
|
||||
|
||||
template <>
|
||||
ParseNode *
|
||||
Parser<FullParseHandler>::cloneLeftHandSide(ParseNode *opn);
|
||||
|
||||
/*
|
||||
* Used by Parser::cloneLeftHandSide to clone a default expression
|
||||
* in the form of
|
||||
* [a = default] or {a: b = default}
|
||||
*/
|
||||
template <>
|
||||
ParseNode *
|
||||
Parser<FullParseHandler>::cloneDestructuringDefault(ParseNode *opn)
|
||||
{
|
||||
MOZ_ASSERT(opn->isKind(PNK_ASSIGN));
|
||||
|
||||
ParseNode *target = cloneLeftHandSide(opn->pn_left);
|
||||
if (!target)
|
||||
return nullptr;
|
||||
ParseNode *defaultNode = cloneParseTree(opn->pn_right);
|
||||
if (!defaultNode)
|
||||
return nullptr;
|
||||
|
||||
return handler.new_<BinaryNode>(opn->getKind(), JSOP_NOP, opn->pn_pos, target, defaultNode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Used by Parser::forStatement and comprehensionTail to clone the TARGET in
|
||||
* for (var/const/let TARGET in EXPR)
|
||||
|
@ -463,7 +488,12 @@ Parser<FullParseHandler>::cloneLeftHandSide(ParseNode *opn)
|
|||
ParseNode *tag = cloneParseTree(opn2->pn_left);
|
||||
if (!tag)
|
||||
return nullptr;
|
||||
ParseNode *target = cloneLeftHandSide(opn2->pn_right);
|
||||
ParseNode *target;
|
||||
if (opn2->pn_right->isKind(PNK_ASSIGN)) {
|
||||
target = cloneDestructuringDefault(opn2->pn_right);
|
||||
} else {
|
||||
target = cloneLeftHandSide(opn2->pn_right);
|
||||
}
|
||||
if (!target)
|
||||
return nullptr;
|
||||
|
||||
|
@ -477,6 +507,8 @@ Parser<FullParseHandler>::cloneLeftHandSide(ParseNode *opn)
|
|||
if (!target)
|
||||
return nullptr;
|
||||
pn2 = handler.new_<UnaryNode>(PNK_SPREAD, JSOP_NOP, opn2->pn_pos, target);
|
||||
} else if (opn2->isKind(PNK_ASSIGN)) {
|
||||
pn2 = cloneDestructuringDefault(opn2);
|
||||
} else {
|
||||
pn2 = cloneLeftHandSide(opn2);
|
||||
}
|
||||
|
|
|
@ -672,6 +672,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
|||
bool bindDestructuringVar(BindData<ParseHandler> *data, Node pn);
|
||||
bool bindDestructuringLHS(Node pn);
|
||||
bool makeSetCall(Node pn, unsigned msg);
|
||||
Node cloneDestructuringDefault(Node opn);
|
||||
Node cloneLeftHandSide(Node opn);
|
||||
Node cloneParseTree(Node opn);
|
||||
|
||||
|
|
|
@ -164,3 +164,20 @@ assertThrowsInstanceOf(() => { [[] = (evaled = true, 2)] = [] }, TypeError);
|
|||
assertEq(evaled, true);
|
||||
|
||||
assertThrowsInstanceOf(() => new Function('var [...rest = defaults] = [];'), SyntaxError);
|
||||
|
||||
// bug 1124480: destructuring defaults should work correctly as part of for-in
|
||||
b = undefined;
|
||||
for (var [a, b = 10] in " ") {}
|
||||
assertEq(b, 10);
|
||||
|
||||
b = undefined;
|
||||
for (let [a, c = 10] in " ") { b = c; }
|
||||
assertEq(b, 10);
|
||||
|
||||
b = undefined;
|
||||
for (var {1: b = 10} in " ") {}
|
||||
assertEq(b, 10);
|
||||
|
||||
b = undefined;
|
||||
for (let {1: c = 10} in " ") { b = c; }
|
||||
assertEq(b, 10);
|
||||
|
|
Загрузка…
Ссылка в новой задаче