From 52bbb4f6091ca0f0177a54a47fdb7ced9057b6e6 Mon Sep 17 00:00:00 2001 From: adamk Date: Thu, 9 Apr 2015 15:09:44 -0700 Subject: [PATCH] Collect list of requested modules in ModuleDescriptor while parsing BUG=v8:1569 LOG=n Review URL: https://codereview.chromium.org/1078903002 Cr-Commit-Position: refs/heads/master@{#27724} --- src/modules.cc | 9 +++++++++ src/modules.h | 19 ++++++++++++++++--- src/parser.cc | 4 ++++ test/cctest/test-parsing.cc | 9 ++++++++- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/modules.cc b/src/modules.cc index 863443e627..3d6aa2c789 100644 --- a/src/modules.cc +++ b/src/modules.cc @@ -35,6 +35,15 @@ void ModuleDescriptor::AddLocalExport(const AstRawString* export_name, } +void ModuleDescriptor::AddModuleRequest(const AstRawString* module_specifier, + Zone* zone) { + // TODO(adamk): Avoid this O(N) operation on each insert by storing + // a HashMap, or by de-duping after parsing. + if (requested_modules_.Contains(module_specifier)) return; + requested_modules_.Add(module_specifier, zone); +} + + const AstRawString* ModuleDescriptor::LookupLocalExport( const AstRawString* export_name, Zone* zone) { if (exports_ == nullptr) return nullptr; diff --git a/src/modules.h b/src/modules.h index 7dd7e26716..33afd6128d 100644 --- a/src/modules.h +++ b/src/modules.h @@ -20,7 +20,7 @@ class ModuleDescriptor : public ZoneObject { // Factory methods. static ModuleDescriptor* New(Zone* zone) { - return new (zone) ModuleDescriptor(); + return new (zone) ModuleDescriptor(zone); } // --------------------------------------------------------------------------- @@ -31,6 +31,10 @@ class ModuleDescriptor : public ZoneObject { void AddLocalExport(const AstRawString* export_name, const AstRawString* local_name, Zone* zone, bool* ok); + // Add module_specifier to the list of requested modules, + // if not already present. + void AddModuleRequest(const AstRawString* module_specifier, Zone* zone); + // Do not allow any further refinements, directly or through unification. void Freeze() { frozen_ = true; } @@ -61,6 +65,10 @@ class ModuleDescriptor : public ZoneObject { const AstRawString* LookupLocalExport(const AstRawString* export_name, Zone* zone); + const ZoneList& requested_modules() const { + return requested_modules_; + } + // --------------------------------------------------------------------------- // Iterators. @@ -95,11 +103,16 @@ class ModuleDescriptor : public ZoneObject { // --------------------------------------------------------------------------- // Implementation. private: + explicit ModuleDescriptor(Zone* zone) + : frozen_(false), + exports_(NULL), + requested_modules_(1, zone), + index_(-1) {} + bool frozen_; ZoneHashMap* exports_; // Module exports and their types (allocated lazily) + ZoneList requested_modules_; int index_; - - ModuleDescriptor() : frozen_(false), exports_(NULL), index_(-1) {} }; } } // namespace v8::internal diff --git a/src/parser.cc b/src/parser.cc index 0dc013202f..fc4138d186 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -1560,6 +1560,8 @@ Statement* Parser::ParseImportDeclaration(bool* ok) { const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); ExpectSemicolon(CHECK_OK); + scope_->module()->AddModuleRequest(module_specifier, zone()); + if (module_instance_binding != NULL) { // TODO(ES6): Set the module specifier for the module namespace binding. } @@ -1697,6 +1699,8 @@ Statement* Parser::ParseExportDeclaration(bool* ok) { } } } else { + scope_->module()->AddModuleRequest(indirect_export_module_specifier, + zone()); for (int i = 0; i < length; ++i) { // TODO(ES6): scope_->module()->AddIndirectExport(...);( } diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index 72077cc8da..6f5708110b 100644 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -5445,7 +5445,8 @@ TEST(ModuleParsingInternals) { "let x = 5;" "export { x as y };" "import { q as z } from 'm.js';" - "import n from 'n.js'"; + "import n from 'n.js';" + "export { a as b } from 'm.js';"; i::Handle source = factory->NewStringFromAsciiChecked(kSource); i::Handle script = factory->NewScript(source); i::Zone zone; @@ -5485,6 +5486,12 @@ TEST(ModuleParsingInternals) { CHECK(import_decl->import_name()->IsOneByteEqualTo("default")); CHECK(import_decl->proxy()->raw_name()->IsOneByteEqualTo("n")); CHECK(import_decl->module_specifier()->IsOneByteEqualTo("n.js")); + // TODO(adamk): Add test for indirect exports once they're fully implemented. + const i::ZoneList& requested_modules = + descriptor->requested_modules(); + CHECK_EQ(2, requested_modules.length()); + CHECK(requested_modules[0]->IsOneByteEqualTo("m.js")); + CHECK(requested_modules[1]->IsOneByteEqualTo("n.js")); }