Index: src/ast/modules.cc |
diff --git a/src/ast/modules.cc b/src/ast/modules.cc |
index f895756e4abc3339f97c95237761ce69b62bc1ca..286a117b3f506791c5ce1c02cd1100e1532dfdbb 100644 |
--- a/src/ast/modules.cc |
+++ b/src/ast/modules.cc |
@@ -3,56 +3,124 @@ |
// found in the LICENSE file. |
#include "src/ast/modules.h" |
- |
#include "src/ast/ast-value-factory.h" |
+#include "src/ast/scopes.h" |
namespace v8 { |
namespace internal { |
-void ModuleDescriptor::AddLocalExport(const AstRawString* export_name, |
- const AstRawString* local_name, |
- Zone* zone, bool* ok) { |
- void* key = const_cast<AstRawString*>(export_name); |
+void ModuleDescriptor::AddImport( |
+ const AstRawString* import_name, const AstRawString* local_name, |
+ const AstRawString* module_request, Scanner::Location loc, Zone* zone) { |
+ DCHECK_NOT_NULL(import_name); |
+ DCHECK_NOT_NULL(local_name); |
+ DCHECK_NOT_NULL(module_request); |
+ ModuleEntry* entry = new (zone) ModuleEntry(loc); |
+ entry->local_name = local_name; |
+ entry->import_name = import_name; |
+ entry->module_request = module_request; |
+ imports_.Add(entry, zone); |
+} |
- ZoneAllocationPolicy allocator(zone); |
- if (exports_ == nullptr) { |
- exports_ = new (zone->New(sizeof(ZoneHashMap))) |
- ZoneHashMap(ZoneHashMap::PointersMatch, |
- ZoneHashMap::kDefaultHashMapCapacity, allocator); |
- } |
+void ModuleDescriptor::AddStarImport( |
+ const AstRawString* local_name, const AstRawString* module_request, |
+ Scanner::Location loc, Zone* zone) { |
+ DCHECK_NOT_NULL(local_name); |
+ DCHECK_NOT_NULL(module_request); |
+ ModuleEntry* entry = new (zone) ModuleEntry(loc); |
+ entry->local_name = local_name; |
+ entry->module_request = module_request; |
+ imports_.Add(entry, zone); |
+} |
+ |
+ |
+void ModuleDescriptor::AddEmptyImport( |
+ const AstRawString* module_request, Scanner::Location loc, Zone* zone) { |
+ DCHECK_NOT_NULL(module_request); |
+ ModuleEntry* entry = new (zone) ModuleEntry(loc); |
+ entry->module_request = module_request; |
+ imports_.Add(entry, zone); |
+} |
- ZoneHashMap::Entry* p = |
- exports_->LookupOrInsert(key, export_name->hash(), allocator); |
- DCHECK_NOT_NULL(p); |
- if (p->value != nullptr) { |
- // Duplicate export. |
- *ok = false; |
- return; |
- } |
- p->value = const_cast<AstRawString*>(local_name); |
+void ModuleDescriptor::AddExport( |
+ const AstRawString* local_name, const AstRawString* export_name, |
+ Scanner::Location loc, Zone* zone) { |
+ DCHECK_NOT_NULL(local_name); |
+ DCHECK_NOT_NULL(export_name); |
+ ModuleEntry* entry = new (zone) ModuleEntry(loc); |
+ entry->export_name = export_name; |
+ entry->local_name = local_name; |
+ exports_.Add(entry, zone); |
} |
-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); |
+void ModuleDescriptor::AddExport( |
+ const AstRawString* import_name, const AstRawString* export_name, |
+ const AstRawString* module_request, Scanner::Location loc, Zone* zone) { |
+ DCHECK_NOT_NULL(import_name); |
+ DCHECK_NOT_NULL(export_name); |
+ DCHECK_NOT_NULL(module_request); |
+ ModuleEntry* entry = new (zone) ModuleEntry(loc); |
+ entry->export_name = export_name; |
+ entry->import_name = import_name; |
+ entry->module_request = module_request; |
+ exports_.Add(entry, zone); |
} |
-const AstRawString* ModuleDescriptor::LookupLocalExport( |
- const AstRawString* export_name, Zone* zone) { |
- if (exports_ == nullptr) return nullptr; |
- ZoneHashMap::Entry* entry = exports_->Lookup( |
- const_cast<AstRawString*>(export_name), export_name->hash()); |
- if (entry == nullptr) return nullptr; |
- DCHECK_NOT_NULL(entry->value); |
- return static_cast<const AstRawString*>(entry->value); |
+void ModuleDescriptor::AddStarExport( |
+ const AstRawString* module_request, Scanner::Location loc, Zone* zone) { |
+ DCHECK_NOT_NULL(module_request); |
+ ModuleEntry* entry = new (zone) ModuleEntry(loc); |
+ entry->module_request = module_request; |
+ exports_.Add(entry, zone); |
+} |
+ |
+ |
+bool ModuleDescriptor::Validate( |
+ Scope* module_scope, PendingCompilationErrorHandler* error_handler, |
+ Zone* zone) const { |
+ DCHECK(module_scope->is_module_scope()); |
+ DCHECK_EQ(this, module_scope->module()); |
+ DCHECK_NOT_NULL(error_handler); |
+ |
+ // Report error iff there are duplicate exports. |
+ { |
+ ZoneAllocationPolicy allocator(zone); |
+ ZoneHashMap* export_names = new (zone->New(sizeof(ZoneHashMap))) |
+ ZoneHashMap(ZoneHashMap::PointersMatch, |
+ ZoneHashMap::kDefaultHashMapCapacity, allocator); |
+ for (auto entry : exports_) { |
+ if (entry->export_name == nullptr) continue; |
+ AstRawString* key = const_cast<AstRawString*>(entry->export_name); |
+ ZoneHashMap::Entry* p = |
+ export_names->LookupOrInsert(key, key->hash(), allocator); |
+ DCHECK_NOT_NULL(p); |
+ if (p->value != nullptr) { |
+ error_handler->ReportMessageAt( |
+ entry->location.beg_pos, entry->location.end_pos, |
+ MessageTemplate::kDuplicateExport, entry->export_name); |
+ return false; |
+ } |
+ p->value = key; // Anything but nullptr. |
+ } |
+ } |
+ |
+ // Report error iff there are exports of non-existent local names. |
+ for (auto entry : exports_) { |
+ if (entry->local_name == nullptr) continue; |
+ if (module_scope->LookupLocal(entry->local_name) == nullptr) { |
+ error_handler->ReportMessageAt( |
+ entry->location.beg_pos, entry->location.end_pos, |
+ MessageTemplate::kModuleExportUndefined, entry->local_name); |
+ return false; |
+ } |
+ } |
+ |
+ return true; |
} |
} // namespace internal |
} // namespace v8 |