From d9f31784a51db420d8b1fbe411f0dac58a86fe9e Mon Sep 17 00:00:00 2001 From: Eddy Bruel Date: Wed, 6 Nov 2013 20:04:45 +0100 Subject: [PATCH] Bug 927116 - Implement reflect support for import declarations; r=jorendorff --- js/src/jsast.tbl | 2 ++ js/src/jsreflect.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/js/src/jsast.tbl b/js/src/jsast.tbl index bcfb6907b634..4e2aa4daedb6 100644 --- a/js/src/jsast.tbl +++ b/js/src/jsast.tbl @@ -57,6 +57,8 @@ ASTDEF(AST_TRY_STMT, "TryStatement", "tryStatemen ASTDEF(AST_THROW_STMT, "ThrowStatement", "throwStatement") ASTDEF(AST_DEBUGGER_STMT, "DebuggerStatement", "debuggerStatement") ASTDEF(AST_LET_STMT, "LetStatement", "letStatement") +ASTDEF(AST_IMPORT_DECL, "ImportDeclaration", "importDeclaration") +ASTDEF(AST_IMPORT_SPEC, "ImportSpecifier", "importSpecifier") ASTDEF(AST_CASE, "SwitchCase", "switchCase") ASTDEF(AST_CATCH, "CatchClause", "catchClause") diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp index 34baac115ca4..7cf7f2fd0a79 100644 --- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -562,6 +562,10 @@ class NodeBuilder bool letStatement(NodeVector &head, HandleValue stmt, TokenPos *pos, MutableHandleValue dst); + bool importDeclaration(NodeVector &elts, HandleValue moduleSpec, TokenPos *pos, MutableHandleValue dst); + + bool importSpecifier(HandleValue importName, HandleValue bindingName, TokenPos *pos, MutableHandleValue dst); + /* * expressions */ @@ -1353,6 +1357,38 @@ NodeBuilder::letStatement(NodeVector &head, HandleValue stmt, TokenPos *pos, Mut dst); } +bool +NodeBuilder::importDeclaration(NodeVector &elts, HandleValue moduleSpec, TokenPos *pos, + MutableHandleValue dst) +{ + RootedValue array(cx); + if (!newArray(elts, &array)) + return false; + + RootedValue cb(cx, callbacks[AST_IMPORT_DECL]); + if (!cb.isNull()) + return callback(cb, array, moduleSpec, pos, dst); + + return newNode(AST_IMPORT_DECL, pos, + "specifiers", array, + "source", moduleSpec, + dst); +} + +bool +NodeBuilder::importSpecifier(HandleValue importName, HandleValue bindingName, TokenPos *pos, + MutableHandleValue dst) +{ + RootedValue cb(cx, callbacks[AST_IMPORT_SPEC]); + if (!cb.isNull()) + return callback(cb, importName, bindingName, pos, dst); + + return newNode(AST_IMPORT_SPEC, pos, + "id", importName, + "name", bindingName, + dst); +} + bool NodeBuilder::variableDeclaration(NodeVector &elts, VarDeclKind kind, TokenPos *pos, MutableHandleValue dst) @@ -1520,6 +1556,8 @@ class ASTSerializer bool variableDeclaration(ParseNode *pn, bool let, MutableHandleValue dst); bool variableDeclarator(ParseNode *pn, VarDeclKind *pkind, MutableHandleValue dst); bool let(ParseNode *pn, bool expr, MutableHandleValue dst); + bool importDeclaration(ParseNode *pn, MutableHandleValue dst); + bool importSpecifier(ParseNode *pn, MutableHandleValue dst); bool optStatement(ParseNode *pn, MutableHandleValue dst) { if (!pn) { @@ -1883,6 +1921,41 @@ ASTSerializer::let(ParseNode *pn, bool expr, MutableHandleValue dst) builder.letStatement(dtors, v, &pn->pn_pos, dst); } +bool +ASTSerializer::importDeclaration(ParseNode *pn, MutableHandleValue dst) +{ + JS_ASSERT(pn->isKind(PNK_IMPORT)); + JS_ASSERT(pn->pn_left->isKind(PNK_IMPORT_SPEC_LIST)); + JS_ASSERT(pn->pn_right->isKind(PNK_STRING)); + + NodeVector elts(cx); + if (!elts.reserve(pn->pn_count)) + return false; + + for (ParseNode *next = pn->pn_left->pn_head; next; next = next->pn_next) { + RootedValue elt(cx); + if (!importSpecifier(next, &elt)) + return false; + elts.infallibleAppend(elt); + } + + RootedValue moduleSpec(cx); + return literal(pn->pn_right, &moduleSpec) && + builder.importDeclaration(elts, moduleSpec, &pn->pn_pos, dst); +} + +bool +ASTSerializer::importSpecifier(ParseNode *pn, MutableHandleValue dst) +{ + JS_ASSERT(pn->isKind(PNK_IMPORT_SPEC)); + + RootedValue importName(cx); + RootedValue bindingName(cx); + return identifier(pn->pn_left, &importName) && + identifier(pn->pn_right, &bindingName) && + builder.importSpecifier(importName, bindingName, &pn->pn_pos, dst); +} + bool ASTSerializer::switchCase(ParseNode *pn, MutableHandleValue dst) { @@ -2038,6 +2111,9 @@ ASTSerializer::statement(ParseNode *pn, MutableHandleValue dst) ? let(pn, false, dst) : declaration(pn, dst); + case PNK_IMPORT: + return importDeclaration(pn, dst); + case PNK_NAME: LOCAL_ASSERT(pn->isUsed()); return statement(pn->pn_lexdef, dst);