зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1048384 - Getter/setter syntax should work with computed property names. r=jorendorff
This commit is contained in:
Родитель
eb93e16fa1
Коммит
0f8ce911a5
|
@ -7086,6 +7086,22 @@ DoubleToAtom(ExclusiveContext *cx, double value)
|
|||
return ToAtom<CanGC>(cx, HandleValue::fromMarkedLocation(&tmp));
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::computedPropertyName(Node literal)
|
||||
{
|
||||
uint32_t begin = pos().begin;
|
||||
Node assignNode = assignExpr();
|
||||
if (!assignNode)
|
||||
return null();
|
||||
MUST_MATCH_TOKEN(TOK_RB, JSMSG_COMP_PROP_UNTERM_EXPR);
|
||||
Node propname = handler.newComputedName(assignNode, begin, pos().end);
|
||||
if (!propname)
|
||||
return null();
|
||||
handler.setListFlag(literal, PNX_NONCONST);
|
||||
return propname;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::objectLiteral()
|
||||
|
@ -7121,16 +7137,9 @@ Parser<ParseHandler>::objectLiteral()
|
|||
break;
|
||||
|
||||
case TOK_LB: {
|
||||
// Computed property name.
|
||||
uint32_t begin = pos().begin;
|
||||
Node assignNode = assignExpr();
|
||||
if (!assignNode)
|
||||
return null();
|
||||
MUST_MATCH_TOKEN(TOK_RB, JSMSG_COMP_PROP_UNTERM_EXPR);
|
||||
propname = handler.newComputedName(assignNode, begin, pos().end);
|
||||
propname = computedPropertyName(literal);
|
||||
if (!propname)
|
||||
return null();
|
||||
handler.setListFlag(literal, PNX_NONCONST);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -7186,6 +7195,10 @@ Parser<ParseHandler>::objectLiteral()
|
|||
propname = newNumber(tokenStream.currentToken());
|
||||
if (!propname)
|
||||
return null();
|
||||
} else if (tt == TOK_LB) {
|
||||
propname = computedPropertyName(literal);
|
||||
if (!propname)
|
||||
return null();
|
||||
} else {
|
||||
// Not an accessor property after all.
|
||||
tokenStream.ungetToken();
|
||||
|
|
|
@ -624,6 +624,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
|||
Node pushLetScope(Handle<StaticBlockObject*> blockObj, StmtInfoPC *stmt);
|
||||
bool noteNameUse(HandlePropertyName name, Node pn);
|
||||
Node objectLiteral();
|
||||
Node computedPropertyName(Node literal);
|
||||
Node arrayInitializer();
|
||||
Node newRegExp();
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ assertEq(a.foo1, 1);
|
|||
assertEq(a.foo2, 2);
|
||||
assertEq(a.foo3, 3);
|
||||
|
||||
var expr = "abc";
|
||||
syntaxError("({[");
|
||||
syntaxError("({[expr");
|
||||
syntaxError("({[expr]");
|
||||
|
@ -174,8 +175,69 @@ assertEq(next.done, true);
|
|||
assertEq(next.value.hello, 2);
|
||||
assertEq(next.value.world, 3);
|
||||
|
||||
syntaxError("a = {get [expr]() { return 3; }, set[expr](v) { return 2; }}");
|
||||
// get and set.
|
||||
expr = "abc";
|
||||
syntaxError("({get [");
|
||||
syntaxError("({get [expr()");
|
||||
syntaxError("({get [expr]()");
|
||||
syntaxError("({get [expr]()})");
|
||||
syntaxError("({get [expr] 0 ()})");
|
||||
syntaxError("({get [expr], 0(})");
|
||||
syntaxError("[get [expr]: 0()]");
|
||||
syntaxError("({get [expr](: name: 0})");
|
||||
syntaxError("({get [1, 2](): 3})");
|
||||
syntaxError("({get [1;](): 1})");
|
||||
syntaxError("({get [if (0) 0;](){}})");
|
||||
syntaxError("({set [(a)");
|
||||
syntaxError("({set [expr(a)");
|
||||
syntaxError("({set [expr](a){}");
|
||||
syntaxError("({set [expr]}(a)");
|
||||
syntaxError("({set [expr](a), 0})");
|
||||
syntaxError("[set [expr](a): 0]");
|
||||
syntaxError("({set [expr](a): name: 0})");
|
||||
syntaxError("({set [1, 2](a) {return 3;}})");
|
||||
syntaxError("({set [1;](a) {return 1}})");
|
||||
syntaxError("({set [if (0) 0;](a){}})");
|
||||
syntaxError("function f() { {get [x](): 1} }");
|
||||
syntaxError("function f() { get [x](): 1 }");
|
||||
syntaxError("function f() { {set [x](a): 1} }");
|
||||
syntaxError("function f() { set [x](a): 1 }");
|
||||
f1 = "abc";
|
||||
syntaxError('a = {get [f1@](){}, set [f1](a){}}'); // unexpected symbol at end of AssignmentExpression
|
||||
syntaxError('a = {get@ [f1](){}, set [f1](a){}}'); // unexpected symbol after get
|
||||
syntaxError('a = {get [f1](){}, set@ [f1](a){}}'); // unexpected symbol after set
|
||||
|
||||
expr = "hey";
|
||||
a = {get [expr]() { return 3; }, set[expr](v) { throw 2; }};
|
||||
assertEq(a.hey, 3);
|
||||
assertThrowsValue(() => { a.hey = 5; }, 2);
|
||||
|
||||
// Symbols with duplicate get and set.
|
||||
expr = Symbol("hey");
|
||||
a = {get [expr]() { return 3; }, set[expr](v) { throw 2; },
|
||||
set [expr] (w) { throw 4; }, get[expr](){return 5; }};
|
||||
assertEq(a[expr], 5);
|
||||
assertThrowsValue(() => { a[expr] = 7; }, 4);
|
||||
|
||||
// expressions with side effects are called in the right order
|
||||
log = "";
|
||||
obj = {
|
||||
"a": log += 'a',
|
||||
get [log += 'b']() {},
|
||||
[log += 'c']: log += 'd',
|
||||
set [log += 'e'](a) {}
|
||||
};
|
||||
assertEq(log, "abcde");
|
||||
|
||||
// assignment expressions, objects and regex in computed names
|
||||
obj = {
|
||||
get [a = "hey"]() { return 1; },
|
||||
get [a = {b : 4}.b]() { return 2; },
|
||||
set [/x/.source](a) { throw 3; }
|
||||
}
|
||||
assertEq(obj.hey, 1);
|
||||
assertEq(obj[4], 2);
|
||||
assertThrowsValue(() => { obj.x = 7; }, 3);
|
||||
|
||||
|
||||
reportCompare(0, 0, "ok");
|
||||
|
|
|
@ -402,6 +402,13 @@ var node = Reflect.parse("a = {[field1]: 5}");
|
|||
Pattern({ body: [ { expression: { right: { properties: [ {key: { loc:
|
||||
{ start: { line: 1, column: 5 }, end: { line: 1, column: 13 }}}}]}}}]}).match(node);
|
||||
|
||||
// Bug 1048384 - Getter/setter syntax with computed names
|
||||
assertExpr("b = { get [meth]() { } }", aExpr("=", ident("b"),
|
||||
objExpr([{ key: computedName(ident("meth")), value: funExpr(null, [], blockStmt([])),
|
||||
method: false, kind: "get"}])));
|
||||
assertExpr("b = { set [meth](a) { } }", aExpr("=", ident("b"),
|
||||
objExpr([{ key: computedName(ident("meth")), value: funExpr(null, [ident("a")],
|
||||
blockStmt([])), method: false, kind: "set"}])));
|
||||
|
||||
// statements
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче