Bug 1712138 - Implement Reflect.parse for static class blocks r=arai

Differential Revision: https://phabricator.services.mozilla.com/D115629
This commit is contained in:
Matthew Gaudet 2021-05-27 15:01:35 +00:00
Родитель 610d1267bb
Коммит eec7e9fd19
5 изменённых файлов: 57 добавлений и 1 удалений

Просмотреть файл

@ -635,6 +635,8 @@ class NodeBuilder {
MutableHandleValue dst);
[[nodiscard]] bool classField(HandleValue name, HandleValue initializer,
TokenPos* pos, MutableHandleValue dst);
[[nodiscard]] bool staticClassBlock(HandleValue body, TokenPos* pos,
MutableHandleValue dst);
/*
* expressions
@ -1625,6 +1627,16 @@ bool NodeBuilder::classField(HandleValue name, HandleValue initializer,
return newNode(AST_CLASS_FIELD, pos, "name", name, "init", initializer, dst);
}
bool NodeBuilder::staticClassBlock(HandleValue body, TokenPos* pos,
MutableHandleValue dst) {
RootedValue cb(cx, callbacks[AST_STATIC_CLASS_BLOCK]);
if (!cb.isNull()) {
return callback(cb, body, pos, dst);
}
return newNode(AST_STATIC_CLASS_BLOCK, pos, "body", body, dst);
}
bool NodeBuilder::classMembers(NodeVector& members, MutableHandleValue dst) {
return newArray(members, dst);
}
@ -1749,6 +1761,8 @@ class ASTSerializer {
bool classMethod(ClassMethod* classMethod, MutableHandleValue dst);
bool classField(ClassField* classField, MutableHandleValue dst);
bool staticClassBlock(StaticClassBlock* staticClassBlock,
MutableHandleValue dst);
bool optIdentifier(HandleAtom atom, TokenPos* pos, MutableHandleValue dst) {
if (!atom) {
@ -2621,7 +2635,13 @@ bool ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst) {
members.infallibleAppend(prop);
} else if (item->is<StaticClassBlock>()) {
// StaticClassBlock* block = &item->as<StaticClassBlock>();
MOZ_CRASH("MG:XXX: Still have to write reflect.parse for this");
StaticClassBlock* scb = &item->as<StaticClassBlock>();
MOZ_ASSERT(memberList->pn_pos.encloses(scb->pn_pos));
RootedValue prop(cx);
if (!staticClassBlock(scb, &prop)) {
return false;
}
members.infallibleAppend(prop);
} else if (!item->isKind(ParseNodeKind::DefaultConstructor)) {
ClassMethod* method = &item->as<ClassMethod>();
MOZ_ASSERT(memberList->pn_pos.encloses(method->pn_pos));
@ -2699,6 +2719,20 @@ bool ASTSerializer::classField(ClassField* classField, MutableHandleValue dst) {
builder.classField(key, val, &classField->pn_pos, dst);
}
bool ASTSerializer::staticClassBlock(StaticClassBlock* staticClassBlock,
MutableHandleValue dst) {
FunctionNode* fun = staticClassBlock->function();
NodeVector args(cx);
NodeVector defaults(cx);
RootedValue body(cx), rest(cx);
rest.setNull();
return functionArgsAndBody(fun->body(), args, defaults, false, false, &body,
&rest) &&
builder.staticClassBlock(body, &staticClassBlock->pn_pos, dst);
}
bool ASTSerializer::leftAssociate(ListNode* node, MutableHandleValue dst) {
MOZ_ASSERT(!node->empty());

Просмотреть файл

@ -0,0 +1,10 @@
// |jit-test| --enable-class-static-blocks;
Reflect.parse(`class A {
static { print('hi'); }
}`)
Reflect.parse(`class A {
static x = 10;
static { this.x++ }
}`);

Просмотреть файл

@ -85,4 +85,5 @@ ASTDEF(AST_COMPUTED_NAME, "ComputedName", "computedNam
ASTDEF(AST_CLASS_STMT, "ClassStatement", "classStatement")
ASTDEF(AST_CLASS_METHOD, "ClassMethod", "classMethod")
ASTDEF(AST_CLASS_FIELD, "ClassField", "classField")
ASTDEF(AST_STATIC_CLASS_BLOCK, "StaticClassBlock", "staticClassBlock")
/* AST_LIMIT = last + 1 */

Просмотреть файл

@ -170,6 +170,9 @@ function classField(id, init) {
name: id,
init: init });
}
function staticClassBlock(body) {
return Pattern({ type: "StaticClassBlock", body: body });
}
function funExpr(id, args, body, gen) {
return Pattern({ type: "FunctionExpression",

Просмотреть файл

@ -0,0 +1,8 @@
// |reftest| skip-if(!xulRuntime.shell) shell-option(--enable-class-static-blocks)
// Classes
function testClassStaticBlock() {
assertExpr("(class C { static { 2; } })", classExpr(ident("C"), null, [staticClassBlock(blockStmt([exprStmt(lit(2))]))]));
}
runtest(testClassStaticBlock);