Bug 1670044 - Part 7: Add separate ImportNamespaceSpec and ExportNamespaceSpec parse nodes. r=yulia,tcampbell

The approach to use "*" for namespace imports/exports no longer works with
module export names. As an alternative add separate ImportNamespaceSpec and
ExportNamespaceSpec parse nodes. They're currently still implemented as binary
nodes, but the next part will change this.

Differential Revision: https://phabricator.services.mozilla.com/D101012
This commit is contained in:
André Bargull 2021-02-09 19:05:35 +00:00
parent 38e8e4ba47
commit 96e2220bd1
14 changed files with 212 additions and 30 deletions

View File

@ -1545,7 +1545,8 @@ bool ModuleBuilder::processImport(frontend::BinaryNode* importNode) {
for (ParseNode* item : specList->contents()) { for (ParseNode* item : specList->contents()) {
BinaryNode* spec = &item->as<BinaryNode>(); BinaryNode* spec = &item->as<BinaryNode>();
MOZ_ASSERT(spec->isKind(ParseNodeKind::ImportSpec)); MOZ_ASSERT(spec->isKind(ParseNodeKind::ImportSpec) ||
spec->isKind(ParseNodeKind::ImportNamespaceSpec));
NameNode* importNameNode = &spec->left()->as<NameNode>(); NameNode* importNameNode = &spec->left()->as<NameNode>();
NameNode* localNameNode = &spec->right()->as<NameNode>(); NameNode* localNameNode = &spec->right()->as<NameNode>();
@ -1561,8 +1562,16 @@ bool ModuleBuilder::processImport(frontend::BinaryNode* importNode) {
markUsedByStencil(module); markUsedByStencil(module);
markUsedByStencil(localName); markUsedByStencil(localName);
markUsedByStencil(importName); markUsedByStencil(importName);
auto entry = frontend::StencilModuleEntry::importEntry(
module, localName, importName, line, column); StencilModuleEntry entry;
if (spec->isKind(ParseNodeKind::ImportSpec)) {
entry = StencilModuleEntry::importEntry(module, localName, importName,
line, column);
} else {
entry = StencilModuleEntry::importNamespaceEntry(
module, localName, importName, line, column);
}
if (!importEntries_.put(localName, entry)) { if (!importEntries_.put(localName, entry)) {
return false; return false;
} }
@ -1768,35 +1777,48 @@ bool ModuleBuilder::processExportFrom(frontend::BinaryNode* exportNode) {
eitherParser_.computeLineAndColumn(spec->pn_pos.begin, &line, &column); eitherParser_.computeLineAndColumn(spec->pn_pos.begin, &line, &column);
StencilModuleEntry entry; StencilModuleEntry entry;
TaggedParserAtomIndex exportName;
if (spec->isKind(ParseNodeKind::ExportSpec)) { if (spec->isKind(ParseNodeKind::ExportSpec)) {
auto* importNameNode = &spec->as<BinaryNode>().left()->as<NameNode>(); auto* importNameNode = &spec->as<BinaryNode>().left()->as<NameNode>();
auto* exportNameNode = &spec->as<BinaryNode>().right()->as<NameNode>(); auto* exportNameNode = &spec->as<BinaryNode>().right()->as<NameNode>();
auto importName = importNameNode->atom(); auto importName = importNameNode->atom();
auto exportName = exportNameNode->atom(); exportName = exportNameNode->atom();
markUsedByStencil(module); markUsedByStencil(module);
markUsedByStencil(importName); markUsedByStencil(importName);
markUsedByStencil(exportName); markUsedByStencil(exportName);
entry = StencilModuleEntry::exportFromEntry(module, importName, entry = StencilModuleEntry::exportFromEntry(module, importName,
exportName, line, column); exportName, line, column);
} else if (spec->isKind(ParseNodeKind::ExportNamespaceSpec)) {
auto* importNameNode = &spec->as<BinaryNode>().left()->as<NameNode>();
auto* exportNameNode = &spec->as<BinaryNode>().right()->as<NameNode>();
if (!exportNames_.put(exportName)) { auto importName = importNameNode->atom();
return false; exportName = exportNameNode->atom();
}
markUsedByStencil(module);
markUsedByStencil(importName);
markUsedByStencil(exportName);
entry = StencilModuleEntry::exportNamespaceFromEntry(
module, importName, exportName, line, column);
} else { } else {
MOZ_ASSERT(spec->isKind(ParseNodeKind::ExportBatchSpecStmt)); MOZ_ASSERT(spec->isKind(ParseNodeKind::ExportBatchSpecStmt));
auto importName = TaggedParserAtomIndex::WellKnown::star(); auto importName = TaggedParserAtomIndex::WellKnown::star();
markUsedByStencil(module); markUsedByStencil(module);
markUsedByStencil(importName); markUsedByStencil(importName);
entry = StencilModuleEntry::exportFromEntry( entry = StencilModuleEntry::exportBatchFromEntry(module, importName, line,
module, importName, TaggedParserAtomIndex::null(), line, column); column);
} }
if (!exportEntries_.append(entry)) { if (!exportEntries_.append(entry)) {
return false; return false;
} }
if (exportName && !exportNames_.put(exportName)) {
return false;
}
} }
return true; return true;

View File

@ -690,14 +690,14 @@ bool js::obj_toString(JSContext* cx, unsigned argc, Value* vp) {
if (!tag.isString()) { if (!tag.isString()) {
if (!builtinTag) { if (!builtinTag) {
builtinTag = GetBuiltinTagFast(obj, clasp, cx); builtinTag = GetBuiltinTagFast(obj, clasp, cx);
#ifdef DEBUG #ifdef DEBUG
// Assert this fast path is correct and matches BuiltinTagSlow. // Assert this fast path is correct and matches BuiltinTagSlow.
JSString* builtinTagSlow = GetBuiltinTagSlow(cx, obj); JSString* builtinTagSlow = GetBuiltinTagSlow(cx, obj);
if (!builtinTagSlow) { if (!builtinTagSlow) {
return false; return false;
} }
MOZ_ASSERT(builtinTagSlow == builtinTag); MOZ_ASSERT(builtinTagSlow == builtinTag);
#endif #endif
} }
args.rval().setString(builtinTag); args.rval().setString(builtinTag);

View File

@ -608,6 +608,11 @@ class NodeBuilder {
HandleValue bindingName, TokenPos* pos, HandleValue bindingName, TokenPos* pos,
MutableHandleValue dst); MutableHandleValue dst);
MOZ_MUST_USE bool importNamespaceSpecifier(HandleValue importName,
HandleValue bindingName,
TokenPos* pos,
MutableHandleValue dst);
MOZ_MUST_USE bool exportDeclaration(HandleValue decl, NodeVector& elts, MOZ_MUST_USE bool exportDeclaration(HandleValue decl, NodeVector& elts,
HandleValue moduleSpec, HandleValue moduleSpec,
HandleValue isDefault, TokenPos* pos, HandleValue isDefault, TokenPos* pos,
@ -617,6 +622,11 @@ class NodeBuilder {
HandleValue exportName, TokenPos* pos, HandleValue exportName, TokenPos* pos,
MutableHandleValue dst); MutableHandleValue dst);
MOZ_MUST_USE bool exportNamespaceSpecifier(HandleValue bindingName,
HandleValue exportName,
TokenPos* pos,
MutableHandleValue dst);
MOZ_MUST_USE bool exportBatchSpecifier(TokenPos* pos, MutableHandleValue dst); MOZ_MUST_USE bool exportBatchSpecifier(TokenPos* pos, MutableHandleValue dst);
MOZ_MUST_USE bool classDefinition(bool expr, HandleValue name, MOZ_MUST_USE bool classDefinition(bool expr, HandleValue name,
@ -1395,6 +1405,19 @@ bool NodeBuilder::importSpecifier(HandleValue importName,
dst); dst);
} }
bool NodeBuilder::importNamespaceSpecifier(HandleValue importName,
HandleValue bindingName,
TokenPos* pos,
MutableHandleValue dst) {
RootedValue cb(cx, callbacks[AST_IMPORT_NAMESPACE_SPEC]);
if (!cb.isNull()) {
return callback(cb, importName, bindingName, pos, dst);
}
return newNode(AST_IMPORT_NAMESPACE_SPEC, pos, "id", importName, "name",
bindingName, dst);
}
bool NodeBuilder::exportDeclaration(HandleValue decl, NodeVector& elts, bool NodeBuilder::exportDeclaration(HandleValue decl, NodeVector& elts,
HandleValue moduleSpec, HandleValue moduleSpec,
HandleValue isDefault, TokenPos* pos, HandleValue isDefault, TokenPos* pos,
@ -1426,6 +1449,19 @@ bool NodeBuilder::exportSpecifier(HandleValue bindingName,
dst); dst);
} }
bool NodeBuilder::exportNamespaceSpecifier(HandleValue bindingName,
HandleValue exportName,
TokenPos* pos,
MutableHandleValue dst) {
RootedValue cb(cx, callbacks[AST_EXPORT_NAMESPACE_SPEC]);
if (!cb.isNull()) {
return callback(cb, bindingName, exportName, pos, dst);
}
return newNode(AST_EXPORT_NAMESPACE_SPEC, pos, "id", bindingName, "name",
exportName, dst);
}
bool NodeBuilder::exportBatchSpecifier(TokenPos* pos, MutableHandleValue dst) { bool NodeBuilder::exportBatchSpecifier(TokenPos* pos, MutableHandleValue dst) {
RootedValue cb(cx, callbacks[AST_EXPORT_BATCH_SPEC]); RootedValue cb(cx, callbacks[AST_EXPORT_BATCH_SPEC]);
if (!cb.isNull()) { if (!cb.isNull()) {
@ -1677,8 +1713,10 @@ class ASTSerializer {
bool variableDeclarator(ParseNode* pn, MutableHandleValue dst); bool variableDeclarator(ParseNode* pn, MutableHandleValue dst);
bool importDeclaration(BinaryNode* importNode, MutableHandleValue dst); bool importDeclaration(BinaryNode* importNode, MutableHandleValue dst);
bool importSpecifier(BinaryNode* importSpec, MutableHandleValue dst); bool importSpecifier(BinaryNode* importSpec, MutableHandleValue dst);
bool importNamespaceSpecifier(BinaryNode* importSpec, MutableHandleValue dst);
bool exportDeclaration(ParseNode* exportNode, MutableHandleValue dst); bool exportDeclaration(ParseNode* exportNode, MutableHandleValue dst);
bool exportSpecifier(BinaryNode* exportSpec, MutableHandleValue dst); bool exportSpecifier(BinaryNode* exportSpec, MutableHandleValue dst);
bool exportNamespaceSpecifier(BinaryNode* exportSpec, MutableHandleValue dst);
bool classDefinition(ClassNode* pn, bool expr, MutableHandleValue dst); bool classDefinition(ClassNode* pn, bool expr, MutableHandleValue dst);
bool optStatement(ParseNode* pn, MutableHandleValue dst) { bool optStatement(ParseNode* pn, MutableHandleValue dst) {
@ -2049,10 +2087,16 @@ bool ASTSerializer::importDeclaration(BinaryNode* importNode,
} }
for (ParseNode* item : specList->contents()) { for (ParseNode* item : specList->contents()) {
BinaryNode* spec = &item->as<BinaryNode>(); auto* spec = &item->as<BinaryNode>();
RootedValue elt(cx); RootedValue elt(cx);
if (!importSpecifier(spec, &elt)) { if (spec->isKind(ParseNodeKind::ImportNamespaceSpec)) {
return false; if (!importNamespaceSpecifier(spec, &elt)) {
return false;
}
} else {
if (!importSpecifier(spec, &elt)) {
return false;
}
} }
elts.infallibleAppend(elt); elts.infallibleAppend(elt);
} }
@ -2076,6 +2120,20 @@ bool ASTSerializer::importSpecifier(BinaryNode* importSpec,
dst); dst);
} }
bool ASTSerializer::importNamespaceSpecifier(BinaryNode* importSpec,
MutableHandleValue dst) {
MOZ_ASSERT(importSpec->isKind(ParseNodeKind::ImportNamespaceSpec));
NameNode* importNameNode = &importSpec->left()->as<NameNode>();
NameNode* bindingNameNode = &importSpec->right()->as<NameNode>();
RootedValue importName(cx);
RootedValue bindingName(cx);
return identifierOrLiteral(importNameNode, &importName) &&
identifier(bindingNameNode, &bindingName) &&
builder.importNamespaceSpecifier(importName, bindingName,
&importSpec->pn_pos, dst);
}
bool ASTSerializer::exportDeclaration(ParseNode* exportNode, bool ASTSerializer::exportDeclaration(ParseNode* exportNode,
MutableHandleValue dst) { MutableHandleValue dst) {
MOZ_ASSERT(exportNode->isKind(ParseNodeKind::ExportStmt) || MOZ_ASSERT(exportNode->isKind(ParseNodeKind::ExportStmt) ||
@ -2106,7 +2164,12 @@ bool ASTSerializer::exportDeclaration(ParseNode* exportNode,
if (!exportSpecifier(&spec->as<BinaryNode>(), &elt)) { if (!exportSpecifier(&spec->as<BinaryNode>(), &elt)) {
return false; return false;
} }
} else if (spec->isKind(ParseNodeKind::ExportNamespaceSpec)) {
if (!exportNamespaceSpecifier(&spec->as<BinaryNode>(), &elt)) {
return false;
}
} else { } else {
MOZ_ASSERT(spec->isKind(ParseNodeKind::ExportBatchSpecStmt));
if (!builder.exportBatchSpecifier(&exportNode->pn_pos, &elt)) { if (!builder.exportBatchSpecifier(&exportNode->pn_pos, &elt)) {
return false; return false;
} }
@ -2174,6 +2237,20 @@ bool ASTSerializer::exportSpecifier(BinaryNode* exportSpec,
dst); dst);
} }
bool ASTSerializer::exportNamespaceSpecifier(BinaryNode* exportSpec,
MutableHandleValue dst) {
MOZ_ASSERT(exportSpec->isKind(ParseNodeKind::ExportNamespaceSpec));
NameNode* bindingNameNode = &exportSpec->left()->as<NameNode>();
NameNode* exportNameNode = &exportSpec->right()->as<NameNode>();
RootedValue bindingName(cx);
RootedValue exportName(cx);
return identifierOrLiteral(bindingNameNode, &bindingName) &&
identifierOrLiteral(exportNameNode, &exportName) &&
builder.exportNamespaceSpecifier(bindingName, exportName,
&exportSpec->pn_pos, dst);
}
bool ASTSerializer::switchCase(CaseClause* caseClause, MutableHandleValue dst) { bool ASTSerializer::switchCase(CaseClause* caseClause, MutableHandleValue dst) {
MOZ_ASSERT_IF( MOZ_ASSERT_IF(
caseClause->caseExpression(), caseClause->caseExpression(),

View File

@ -1536,9 +1536,11 @@ restart:
case ParseNodeKind::ClassMemberList: // by ParseNodeKind::ClassDecl case ParseNodeKind::ClassMemberList: // by ParseNodeKind::ClassDecl
case ParseNodeKind::ImportSpecList: // by ParseNodeKind::Import case ParseNodeKind::ImportSpecList: // by ParseNodeKind::Import
case ParseNodeKind::ImportSpec: // by ParseNodeKind::Import case ParseNodeKind::ImportSpec: // by ParseNodeKind::Import
case ParseNodeKind::ImportNamespaceSpec: // by ParseNodeKind::Import
case ParseNodeKind::ExportBatchSpecStmt: // by ParseNodeKind::Export case ParseNodeKind::ExportBatchSpecStmt: // by ParseNodeKind::Export
case ParseNodeKind::ExportSpecList: // by ParseNodeKind::Export case ParseNodeKind::ExportSpecList: // by ParseNodeKind::Export
case ParseNodeKind::ExportSpec: // by ParseNodeKind::Export case ParseNodeKind::ExportSpec: // by ParseNodeKind::Export
case ParseNodeKind::ExportNamespaceSpec: // by ParseNodeKind::Export
case ParseNodeKind::CallSiteObj: // by ParseNodeKind::TaggedTemplate case ParseNodeKind::CallSiteObj: // by ParseNodeKind::TaggedTemplate
case ParseNodeKind::PosHolder: // by ParseNodeKind::NewTarget case ParseNodeKind::PosHolder: // by ParseNodeKind::NewTarget
case ParseNodeKind::SuperBase: // by ParseNodeKind::Elem and others case ParseNodeKind::SuperBase: // by ParseNodeKind::Elem and others

View File

@ -163,10 +163,12 @@ restart:
case ParseNodeKind::ImportDecl: case ParseNodeKind::ImportDecl:
case ParseNodeKind::ImportSpecList: case ParseNodeKind::ImportSpecList:
case ParseNodeKind::ImportSpec: case ParseNodeKind::ImportSpec:
case ParseNodeKind::ImportNamespaceSpec:
case ParseNodeKind::ExportFromStmt: case ParseNodeKind::ExportFromStmt:
case ParseNodeKind::ExportDefaultStmt: case ParseNodeKind::ExportDefaultStmt:
case ParseNodeKind::ExportSpecList: case ParseNodeKind::ExportSpecList:
case ParseNodeKind::ExportSpec: case ParseNodeKind::ExportSpec:
case ParseNodeKind::ExportNamespaceSpec:
case ParseNodeKind::ExportStmt: case ParseNodeKind::ExportStmt:
case ParseNodeKind::ExportBatchSpecStmt: case ParseNodeKind::ExportBatchSpecStmt:
case ParseNodeKind::CallImportExpr: case ParseNodeKind::CallImportExpr:

View File

@ -649,6 +649,11 @@ class FullParseHandler {
return newBinary(ParseNodeKind::ImportSpec, importNameNode, bindingName); return newBinary(ParseNodeKind::ImportSpec, importNameNode, bindingName);
} }
BinaryNodeType newImportNamespaceSpec(Node importNameNode, Node bindingName) {
return newBinary(ParseNodeKind::ImportNamespaceSpec, importNameNode,
bindingName);
}
UnaryNodeType newExportDeclaration(Node kid, const TokenPos& pos) { UnaryNodeType newExportDeclaration(Node kid, const TokenPos& pos) {
return new_<UnaryNode>(ParseNodeKind::ExportStmt, pos, kid); return new_<UnaryNode>(ParseNodeKind::ExportStmt, pos, kid);
} }
@ -681,6 +686,11 @@ class FullParseHandler {
return newBinary(ParseNodeKind::ExportSpec, bindingName, exportName); return newBinary(ParseNodeKind::ExportSpec, bindingName, exportName);
} }
BinaryNodeType newExportNamespaceSpec(Node bindingName, Node exportName) {
return newBinary(ParseNodeKind::ExportNamespaceSpec, bindingName,
exportName);
}
NullaryNodeType newExportBatchSpec(const TokenPos& pos) { NullaryNodeType newExportBatchSpec(const TokenPos& pos) {
return new_<NullaryNode>(ParseNodeKind::ExportBatchSpecStmt, pos); return new_<NullaryNode>(ParseNodeKind::ExportBatchSpecStmt, pos);
} }

View File

@ -421,9 +421,13 @@ class NameResolver : public ParseNodeVisitor<NameResolver> {
MOZ_ASSERT(item->is<NullaryNode>()); MOZ_ASSERT(item->is<NullaryNode>());
} else { } else {
for (ParseNode* item : pn->contents()) { for (ParseNode* item : pn->contents()) {
BinaryNode* spec = &item->as<BinaryNode>(); auto* spec = &item->as<BinaryNode>();
MOZ_ASSERT(spec->isKind(isImport ? ParseNodeKind::ImportSpec MOZ_ASSERT_IF(isImport,
: ParseNodeKind::ExportSpec)); spec->isKind(ParseNodeKind::ImportSpec) ||
spec->isKind(ParseNodeKind::ImportNamespaceSpec));
MOZ_ASSERT_IF(!isImport,
spec->isKind(ParseNodeKind::ExportSpec) ||
spec->isKind(ParseNodeKind::ExportNamespaceSpec));
MOZ_ASSERT(spec->left()->isKind(ParseNodeKind::Name) || MOZ_ASSERT(spec->left()->isKind(ParseNodeKind::Name) ||
spec->left()->isKind(ParseNodeKind::StringExpr)); spec->left()->isKind(ParseNodeKind::StringExpr));
MOZ_ASSERT(spec->right()->isKind(ParseNodeKind::Name) || MOZ_ASSERT(spec->right()->isKind(ParseNodeKind::Name) ||

View File

@ -145,11 +145,13 @@ class FunctionBox;
F(ImportDecl, BinaryNode) \ F(ImportDecl, BinaryNode) \
F(ImportSpecList, ListNode) \ F(ImportSpecList, ListNode) \
F(ImportSpec, BinaryNode) \ F(ImportSpec, BinaryNode) \
F(ImportNamespaceSpec, BinaryNode) \
F(ExportStmt, UnaryNode) \ F(ExportStmt, UnaryNode) \
F(ExportFromStmt, BinaryNode) \ F(ExportFromStmt, BinaryNode) \
F(ExportDefaultStmt, BinaryNode) \ F(ExportDefaultStmt, BinaryNode) \
F(ExportSpecList, ListNode) \ F(ExportSpecList, ListNode) \
F(ExportSpec, BinaryNode) \ F(ExportSpec, BinaryNode) \
F(ExportNamespaceSpec, BinaryNode) \
F(ExportBatchSpecStmt, NullaryNode) \ F(ExportBatchSpecStmt, NullaryNode) \
F(ForIn, TernaryNode) \ F(ForIn, TernaryNode) \
F(ForOf, TernaryNode) \ F(ForOf, TernaryNode) \
@ -401,6 +403,9 @@ inline bool IsTypeofKind(ParseNodeKind kind) {
* ImportSpec (BinaryNode) * ImportSpec (BinaryNode)
* left: import name * left: import name
* right: local binding name * right: local binding name
* ImportNamespaceSpec (BinaryNode)
* left: import name
* right: local binding name
* ExportStmt (UnaryNode) * ExportStmt (UnaryNode)
* kid: declaration expression * kid: declaration expression
* ExportFromStmt (BinaryNode) * ExportFromStmt (BinaryNode)
@ -412,6 +417,9 @@ inline bool IsTypeofKind(ParseNodeKind kind) {
* ExportSpec (BinaryNode) * ExportSpec (BinaryNode)
* left: local binding name * left: local binding name
* right: export name * right: export name
* ExportNamespaceSpec (BinaryNode)
* left: local binding name
* right: export name
* ExportDefaultStmt (BinaryNode) * ExportDefaultStmt (BinaryNode)
* left: export default declaration or expression * left: export default declaration or expression
* right: Name node for assignment * right: Name node for assignment

View File

@ -4933,7 +4933,7 @@ bool GeneralParser<ParseHandler, Unit>::namespaceImport(
pc_->varScope().lookupDeclaredName(bindingName)->value()->setClosedOver(); pc_->varScope().lookupDeclaredName(bindingName)->value()->setClosedOver();
BinaryNodeType importSpec = BinaryNodeType importSpec =
handler_.newImportSpec(importName, bindingNameNode); handler_.newImportNamespaceSpec(importName, bindingNameNode);
if (!importSpec) { if (!importSpec) {
return false; return false;
} }
@ -5449,7 +5449,8 @@ GeneralParser<ParseHandler, Unit>::exportBatch(uint32_t begin) {
return null(); return null();
} }
BinaryNodeType exportSpec = handler_.newExportSpec(importName, exportName); BinaryNodeType exportSpec =
handler_.newExportNamespaceSpec(importName, exportName);
if (!exportSpec) { if (!exportSpec) {
return null(); return null();
} }

View File

@ -476,12 +476,16 @@ using FunctionDeclarationVector =
// for readability. // for readability.
class StencilModuleEntry { class StencilModuleEntry {
public: public:
// | ModuleRequest | ImportEntry | ExportAs | ExportFrom | // clang-format off
// |-----------------------------------------------------| //
// specifier | required | required | nullptr | required | // | ModuleRequest | ImportEntry | ImportNamespaceEntry | ExportAs | ExportFrom | ExportNamespaceFrom | ExportBatchFrom |
// localName | null | required | required | nullptr | // |--------------------------------------------------------------------------------------------------------------------|
// importName | null | required | nullptr | required | // specifier | required | required | required | null | required | required | required |
// exportName | null | null | required | optional | // localName | null | required | required | required | null | null | null |
// importName | null | required | required | null | required | required | required |
// exportName | null | null | null | required | required | required | null |
//
// clang-format on
TaggedParserAtomIndex specifier; TaggedParserAtomIndex specifier;
TaggedParserAtomIndex localName; TaggedParserAtomIndex localName;
TaggedParserAtomIndex importName; TaggedParserAtomIndex importName;
@ -522,6 +526,17 @@ class StencilModuleEntry {
return entry; return entry;
} }
static StencilModuleEntry importNamespaceEntry(
TaggedParserAtomIndex specifier, TaggedParserAtomIndex localName,
TaggedParserAtomIndex importName, uint32_t lineno, uint32_t column) {
MOZ_ASSERT(specifier && localName && importName);
StencilModuleEntry entry(lineno, column);
entry.specifier = specifier;
entry.localName = localName;
entry.importName = importName;
return entry;
}
static StencilModuleEntry exportAsEntry(TaggedParserAtomIndex localName, static StencilModuleEntry exportAsEntry(TaggedParserAtomIndex localName,
TaggedParserAtomIndex exportName, TaggedParserAtomIndex exportName,
uint32_t lineno, uint32_t column) { uint32_t lineno, uint32_t column) {
@ -536,14 +551,34 @@ class StencilModuleEntry {
TaggedParserAtomIndex importName, TaggedParserAtomIndex importName,
TaggedParserAtomIndex exportName, TaggedParserAtomIndex exportName,
uint32_t lineno, uint32_t column) { uint32_t lineno, uint32_t column) {
// NOTE: The `export * from "mod";` syntax generates nullptr exportName. MOZ_ASSERT(specifier && importName && exportName);
MOZ_ASSERT(specifier && importName);
StencilModuleEntry entry(lineno, column); StencilModuleEntry entry(lineno, column);
entry.specifier = specifier; entry.specifier = specifier;
entry.importName = importName; entry.importName = importName;
entry.exportName = exportName; entry.exportName = exportName;
return entry; return entry;
} }
static StencilModuleEntry exportNamespaceFromEntry(
TaggedParserAtomIndex specifier, TaggedParserAtomIndex importName,
TaggedParserAtomIndex exportName, uint32_t lineno, uint32_t column) {
MOZ_ASSERT(specifier && importName && exportName);
StencilModuleEntry entry(lineno, column);
entry.specifier = specifier;
entry.importName = importName;
entry.exportName = exportName;
return entry;
}
static StencilModuleEntry exportBatchFromEntry(
TaggedParserAtomIndex specifier, TaggedParserAtomIndex importName,
uint32_t lineno, uint32_t column) {
MOZ_ASSERT(specifier && importName);
StencilModuleEntry entry(lineno, column);
entry.specifier = specifier;
entry.importName = importName;
return entry;
}
}; };
// Metadata generated by parsing module scripts, including import/export tables. // Metadata generated by parsing module scripts, including import/export tables.

View File

@ -415,6 +415,9 @@ class SyntaxParseHandler {
BinaryNodeType newImportSpec(Node importNameNode, Node bindingName) { BinaryNodeType newImportSpec(Node importNameNode, Node bindingName) {
return NodeGeneric; return NodeGeneric;
} }
BinaryNodeType newImportNamespaceSpec(Node importNameNode, Node bindingName) {
return NodeGeneric;
}
UnaryNodeType newExportDeclaration(Node kid, const TokenPos& pos) { UnaryNodeType newExportDeclaration(Node kid, const TokenPos& pos) {
return NodeGeneric; return NodeGeneric;
} }
@ -429,6 +432,9 @@ class SyntaxParseHandler {
BinaryNodeType newExportSpec(Node bindingName, Node exportName) { BinaryNodeType newExportSpec(Node bindingName, Node exportName) {
return NodeGeneric; return NodeGeneric;
} }
BinaryNodeType newExportNamespaceSpec(Node bindingName, Node exportName) {
return NodeGeneric;
}
NullaryNodeType newExportBatchSpec(const TokenPos& pos) { NullaryNodeType newExportBatchSpec(const TokenPos& pos) {
return NodeGeneric; return NodeGeneric;
} }

View File

@ -17,6 +17,11 @@ importSpecifier = (id, name) => Pattern({
id: id, id: id,
name: name name: name
}); });
importNamespaceSpecifier = (id, name) => Pattern({
type: "ImportNamespaceSpecifier",
id: id,
name: name
});
ident = (name) => Pattern({ ident = (name) => Pattern({
type: "Identifier", type: "Identifier",
name: name name: name
@ -46,7 +51,7 @@ program([
program([ program([
importDeclaration( importDeclaration(
[ [
importSpecifier( importNamespaceSpecifier(
ident("*"), ident("*"),
ident("a") ident("a")
) )
@ -117,7 +122,7 @@ program([
ident("default"), ident("default"),
ident("a") ident("a")
), ),
importSpecifier( importNamespaceSpecifier(
ident("*"), ident("*"),
ident("b") ident("b")
) )

View File

@ -65,8 +65,10 @@ ASTDEF(AST_DEBUGGER_STMT, "DebuggerStatement", "debuggerSta
ASTDEF(AST_LET_STMT, "LetStatement", "letStatement") ASTDEF(AST_LET_STMT, "LetStatement", "letStatement")
ASTDEF(AST_IMPORT_DECL, "ImportDeclaration", "importDeclaration") ASTDEF(AST_IMPORT_DECL, "ImportDeclaration", "importDeclaration")
ASTDEF(AST_IMPORT_SPEC, "ImportSpecifier", "importSpecifier") ASTDEF(AST_IMPORT_SPEC, "ImportSpecifier", "importSpecifier")
ASTDEF(AST_IMPORT_NAMESPACE_SPEC, "ImportNamespaceSpecifier", "importNamespaceSpecifier")
ASTDEF(AST_EXPORT_DECL, "ExportDeclaration", "exportDeclaration") ASTDEF(AST_EXPORT_DECL, "ExportDeclaration", "exportDeclaration")
ASTDEF(AST_EXPORT_SPEC, "ExportSpecifier", "exportSpecifier") ASTDEF(AST_EXPORT_SPEC, "ExportSpecifier", "exportSpecifier")
ASTDEF(AST_EXPORT_NAMESPACE_SPEC, "ExportNamespaceSpecifier", "exportNamespaceSpecifier")
ASTDEF(AST_EXPORT_BATCH_SPEC, "ExportBatchSpecifier", "exportBatchSpecifier") ASTDEF(AST_EXPORT_BATCH_SPEC, "ExportBatchSpecifier", "exportBatchSpecifier")
ASTDEF(AST_CASE, "SwitchCase", "switchCase") ASTDEF(AST_CASE, "SwitchCase", "switchCase")

View File

@ -34,6 +34,14 @@ function exportSpec(id, name) {
}; };
} }
function exportNamespaceSpec(id, name) {
return {
type: "ExportNamespaceSpecifier",
id,
name,
};
}
function assertModule(src, patt) { function assertModule(src, patt) {
program(patt).assert(Reflect.parse(src, {target: "module"})); program(patt).assert(Reflect.parse(src, {target: "module"}));
} }
@ -79,7 +87,7 @@ assertModule(`
assertModule(` assertModule(`
export * as "x" from "module"; export * as "x" from "module";
`, [ `, [
exportDecl(null, [exportSpec(ident("*"), literal("x"))], literal("module"), false), exportDecl(null, [exportNamespaceSpec(ident("*"), literal("x"))], literal("module"), false),
]); ]);
if (typeof reportCompare === "function") if (typeof reportCompare === "function")