Bug 568953 - Added reflection support for module declarations; r=jorendorff

This commit is contained in:
Eddy Bruel 2013-04-02 18:00:49 +02:00
parent fa52f2ac48
commit b72bc01b64
3 changed files with 68 additions and 3 deletions

View File

@ -0,0 +1,34 @@
load(libdir + "asserts.js");
assertThrowsInstanceOf(function () {
Reflect.parse("module foo { }");
}, SyntaxError);
assertThrowsInstanceOf(function () {
Reflect.parse("function foo() { module 'bar' {} }");
}, SyntaxError);
assertThrowsInstanceOf(function () {
Reflect.parse("if (true) { module 'foo' {} }");
}, SyntaxError);
assertThrowsInstanceOf(function () {
Reflect.parse("module 'foo' { if (true) { module 'bar' {} } }");
}, SyntaxError);
var node = Reflect.parse("module 'foo' {}");
assertEq(typeof node == "object" && node != null, true);
assertEq(node.type, "Program");
node = node.body;
assertEq(typeof node == "object" && node != null, true);
assertEq(node.length, 1);
node = node[0];
assertEq(typeof node == "object" && node != null, true);
assertEq(node.type, "ModuleDeclaration");
assertEq(node.name, "foo");
node = node.body;
assertEq(typeof node == "object" && node != null, true);
assertEq(node.type, "BlockStatement");
node = node.body;
assertEq(typeof node == "object" && node != null, true);
assertEq(node.length, 0);

View File

@ -12,6 +12,7 @@ ASTDEF(AST_IDENTIFIER, "Identifier", "identifier"
ASTDEF(AST_LITERAL, "Literal", "literal")
ASTDEF(AST_PROPERTY, "Property", "property")
ASTDEF(AST_MODULE_DECL, "ModuleDeclaration", "moduleDeclaration")
ASTDEF(AST_FUNC_DECL, "FunctionDeclaration", "functionDeclaration")
ASTDEF(AST_VAR_DECL, "VariableDeclaration", "variableDeclaration")
ASTDEF(AST_VAR_DTOR, "VariableDeclarator", "variableDeclarator")

View File

@ -25,6 +25,7 @@
#include "jsnum.h"
#include "frontend/Parser.h"
#include "frontend/ParseNode-inl.h"
#include "frontend/TokenStream.h"
#include "js/CharacterEncoding.h"
#include "vm/RegExpObject.h"
@ -480,6 +481,8 @@ class NodeBuilder
bool identifier(HandleValue name, TokenPos *pos, MutableHandleValue dst);
bool module(TokenPos *pos, HandleValue name, HandleValue body, MutableHandleValue dst);
bool function(ASTType type, TokenPos *pos,
HandleValue id, NodeVector &args, NodeVector &defaults,
HandleValue body, HandleValue rest, bool isGenerator, bool isExpression,
@ -1427,6 +1430,20 @@ NodeBuilder::arrayPattern(NodeVector &elts, TokenPos *pos, MutableHandleValue ds
return listNode(AST_ARRAY_PATT, "elements", elts, pos, dst);
}
bool
NodeBuilder::module(TokenPos *pos, HandleValue name, HandleValue body, MutableHandleValue dst)
{
RootedValue cb(cx, callbacks[AST_MODULE_DECL]);
if (!cb.isNull()) {
return callback(cb, name, body, pos, dst);
}
return newNode(AST_MODULE_DECL, pos,
"name", name,
"body", body,
dst);
}
bool
NodeBuilder::function(ASTType type, TokenPos *pos,
HandleValue id, NodeVector &args, NodeVector &defaults,
@ -1539,10 +1556,11 @@ class ASTSerializer
bool arrayPattern(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst);
bool objectPattern(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst);
bool module(ParseNode *pn, MutableHandleValue dst);
bool function(ParseNode *pn, ASTType type, MutableHandleValue dst);
bool functionArgsAndBody(ParseNode *pn, NodeVector &args, NodeVector &defaults,
MutableHandleValue body, MutableHandleValue rest);
bool functionBody(ParseNode *pn, TokenPos *pos, MutableHandleValue dst);
bool moduleOrFunctionBody(ParseNode *pn, TokenPos *pos, MutableHandleValue dst);
bool comprehensionBlock(ParseNode *pn, MutableHandleValue dst);
bool comprehension(ParseNode *pn, MutableHandleValue dst);
@ -2000,6 +2018,9 @@ ASTSerializer::statement(ParseNode *pn, MutableHandleValue dst)
{
JS_CHECK_RECURSION(cx, return false);
switch (pn->getKind()) {
case PNK_MODULE:
return module(pn, dst);
case PNK_FUNCTION:
case PNK_VAR:
case PNK_CONST:
@ -2772,6 +2793,15 @@ ASTSerializer::identifier(ParseNode *pn, MutableHandleValue dst)
return identifier(pnAtom, &pn->pn_pos, dst);
}
bool
ASTSerializer::module(ParseNode *pn, MutableHandleValue dst)
{
RootedValue name(cx, StringValue(pn->atom()));
RootedValue body(cx);
return moduleOrFunctionBody(pn->pn_body->pn_head, &pn->pn_body->pn_pos, &body) &&
builder.module(&pn->pn_pos, name, body, dst);
}
bool
ASTSerializer::function(ParseNode *pn, ASTType type, MutableHandleValue dst)
{
@ -2861,7 +2891,7 @@ ASTSerializer::functionArgsAndBody(ParseNode *pn, NodeVector &args, NodeVector &
: pnbody->pn_head;
return functionArgs(pn, pnargs, pndestruct, pnbody, args, defaults, rest) &&
functionBody(pnstart, &pnbody->pn_pos, body);
moduleOrFunctionBody(pnstart, &pnbody->pn_pos, body);
}
default:
@ -2930,7 +2960,7 @@ ASTSerializer::functionArgs(ParseNode *pn, ParseNode *pnargs, ParseNode *pndestr
}
bool
ASTSerializer::functionBody(ParseNode *pn, TokenPos *pos, MutableHandleValue dst)
ASTSerializer::moduleOrFunctionBody(ParseNode *pn, TokenPos *pos, MutableHandleValue dst)
{
NodeVector elts(cx);