LCOV - code coverage report
Current view: top level - src/ast - modules.h (source / functions) Hit Total Coverage
Test: app.info Lines: 9 9 100.0 %
Date: 2017-04-26 Functions: 2 2 100.0 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_AST_MODULES_H_
       6             : #define V8_AST_MODULES_H_
       7             : 
       8             : #include "src/parsing/scanner.h"  // Only for Scanner::Location.
       9             : #include "src/zone/zone-containers.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : 
      14             : 
      15             : class AstRawString;
      16             : class ModuleInfo;
      17             : class ModuleInfoEntry;
      18             : class PendingCompilationErrorHandler;
      19             : 
      20             : class ModuleDescriptor : public ZoneObject {
      21             :  public:
      22       33608 :   explicit ModuleDescriptor(Zone* zone)
      23             :       : module_requests_(zone),
      24             :         special_exports_(1, zone),
      25             :         namespace_imports_(1, zone),
      26             :         regular_exports_(zone),
      27       67216 :         regular_imports_(zone) {}
      28             : 
      29             :   // The following Add* methods are high-level convenience functions for use by
      30             :   // the parser.
      31             : 
      32             :   // import x from "foo.js";
      33             :   // import {x} from "foo.js";
      34             :   // import {x as y} from "foo.js";
      35             :   void AddImport(
      36             :     const AstRawString* import_name, const AstRawString* local_name,
      37             :     const AstRawString* module_request, const Scanner::Location loc,
      38             :     Zone* zone);
      39             : 
      40             :   // import * as x from "foo.js";
      41             :   void AddStarImport(
      42             :     const AstRawString* local_name, const AstRawString* module_request,
      43             :     const Scanner::Location loc, Zone* zone);
      44             : 
      45             :   // import "foo.js";
      46             :   // import {} from "foo.js";
      47             :   // export {} from "foo.js";  (sic!)
      48             :   void AddEmptyImport(const AstRawString* module_request);
      49             : 
      50             :   // export {x};
      51             :   // export {x as y};
      52             :   // export VariableStatement
      53             :   // export Declaration
      54             :   // export default ...
      55             :   void AddExport(
      56             :     const AstRawString* local_name, const AstRawString* export_name,
      57             :     const Scanner::Location loc, Zone* zone);
      58             : 
      59             :   // export {x} from "foo.js";
      60             :   // export {x as y} from "foo.js";
      61             :   void AddExport(
      62             :     const AstRawString* export_name, const AstRawString* import_name,
      63             :     const AstRawString* module_request, const Scanner::Location loc,
      64             :     Zone* zone);
      65             : 
      66             :   // export * from "foo.js";
      67             :   void AddStarExport(
      68             :     const AstRawString* module_request, const Scanner::Location loc,
      69             :     Zone* zone);
      70             : 
      71             :   // Check if module is well-formed and report error if not.
      72             :   // Also canonicalize indirect exports.
      73             :   bool Validate(ModuleScope* module_scope,
      74             :                 PendingCompilationErrorHandler* error_handler, Zone* zone);
      75             : 
      76             :   struct Entry : public ZoneObject {
      77             :     Scanner::Location location;
      78             :     const AstRawString* export_name;
      79             :     const AstRawString* local_name;
      80             :     const AstRawString* import_name;
      81             : 
      82             :     // The module_request value records the order in which modules are
      83             :     // requested. It also functions as an index into the ModuleInfo's array of
      84             :     // module specifiers and into the Module's array of requested modules.  A
      85             :     // negative value means no module request.
      86             :     int module_request;
      87             : 
      88             :     // Import/export entries that are associated with a MODULE-allocated
      89             :     // variable (i.e. regular_imports and regular_exports after Validate) use
      90             :     // the cell_index value to encode the location of their cell.  During
      91             :     // variable allocation, this will be be copied into the variable's index
      92             :     // field.
      93             :     // Entries that are not associated with a MODULE-allocated variable have
      94             :     // GetCellIndexKind(cell_index) == kInvalid.
      95             :     int cell_index;
      96             : 
      97             :     // TODO(neis): Remove local_name component?
      98             :     explicit Entry(Scanner::Location loc)
      99             :         : location(loc),
     100             :           export_name(nullptr),
     101             :           local_name(nullptr),
     102             :           import_name(nullptr),
     103             :           module_request(-1),
     104        9310 :           cell_index(0) {}
     105             : 
     106             :     // (De-)serialization support.
     107             :     // Note that the location value is not preserved as it's only needed by the
     108             :     // parser.  (A Deserialize'd entry has an invalid location.)
     109             :     Handle<ModuleInfoEntry> Serialize(Isolate* isolate) const;
     110             :     static Entry* Deserialize(Isolate* isolate, AstValueFactory* avfactory,
     111             :                               Handle<ModuleInfoEntry> entry);
     112             :   };
     113             : 
     114             :   enum CellIndexKind { kInvalid, kExport, kImport };
     115             :   static CellIndexKind GetCellIndexKind(int cell_index);
     116             : 
     117             :   // Module requests.
     118             :   const ZoneMap<const AstRawString*, int>& module_requests() const {
     119             :     return module_requests_;
     120             :   }
     121             : 
     122             :   // Namespace imports.
     123             :   const ZoneList<const Entry*>& namespace_imports() const {
     124             :     return namespace_imports_;
     125             :   }
     126             : 
     127             :   // All the remaining imports, indexed by local name.
     128             :   const ZoneMap<const AstRawString*, Entry*>& regular_imports() const {
     129             :     return regular_imports_;
     130             :   }
     131             : 
     132             :   // Star exports and explicitly indirect exports.
     133             :   const ZoneList<const Entry*>& special_exports() const {
     134             :     return special_exports_;
     135             :   }
     136             : 
     137             :   // All the remaining exports, indexed by local name.
     138             :   // After canonicalization (see Validate), these are exactly the local exports.
     139             :   const ZoneMultimap<const AstRawString*, Entry*>& regular_exports() const {
     140             :     return regular_exports_;
     141             :   }
     142             : 
     143             :   void AddRegularExport(Entry* entry) {
     144             :     DCHECK_NOT_NULL(entry->export_name);
     145             :     DCHECK_NOT_NULL(entry->local_name);
     146             :     DCHECK_NULL(entry->import_name);
     147             :     DCHECK_LT(entry->module_request, 0);
     148       10770 :     regular_exports_.insert(std::make_pair(entry->local_name, entry));
     149             :   }
     150             : 
     151             :   void AddSpecialExport(const Entry* entry, Zone* zone) {
     152             :     DCHECK_NULL(entry->local_name);
     153             :     DCHECK_LE(0, entry->module_request);
     154             :     special_exports_.Add(entry, zone);
     155             :   }
     156             : 
     157             :   void AddRegularImport(Entry* entry) {
     158             :     DCHECK_NOT_NULL(entry->import_name);
     159             :     DCHECK_NOT_NULL(entry->local_name);
     160             :     DCHECK_NULL(entry->export_name);
     161             :     DCHECK_LE(0, entry->module_request);
     162        6662 :     regular_imports_.insert(std::make_pair(entry->local_name, entry));
     163             :     // We don't care if there's already an entry for this local name, as in that
     164             :     // case we will report an error when declaring the variable.
     165             :   }
     166             : 
     167             :   void AddNamespaceImport(const Entry* entry, Zone* zone) {
     168             :     DCHECK_NULL(entry->import_name);
     169             :     DCHECK_NULL(entry->export_name);
     170             :     DCHECK_NOT_NULL(entry->local_name);
     171             :     DCHECK_LE(0, entry->module_request);
     172             :     namespace_imports_.Add(entry, zone);
     173             :   }
     174             : 
     175             :   Handle<FixedArray> SerializeRegularExports(Isolate* isolate,
     176             :                                              Zone* zone) const;
     177             :   void DeserializeRegularExports(Isolate* isolate, AstValueFactory* avfactory,
     178             :                                  Handle<ModuleInfo> module_info);
     179             : 
     180             :  private:
     181             :   // TODO(neis): Use STL datastructure instead of ZoneList?
     182             :   ZoneMap<const AstRawString*, int> module_requests_;
     183             :   ZoneList<const Entry*> special_exports_;
     184             :   ZoneList<const Entry*> namespace_imports_;
     185             :   ZoneMultimap<const AstRawString*, Entry*> regular_exports_;
     186             :   ZoneMap<const AstRawString*, Entry*> regular_imports_;
     187             : 
     188             :   // If there are multiple export entries with the same export name, return the
     189             :   // last of them (in source order).  Otherwise return nullptr.
     190             :   const Entry* FindDuplicateExport(Zone* zone) const;
     191             : 
     192             :   // Find any implicitly indirect exports and make them explicit.
     193             :   //
     194             :   // An explicitly indirect export is an export entry arising from an export
     195             :   // statement of the following form:
     196             :   //   export {a as c} from "X";
     197             :   // An implicitly indirect export corresponds to
     198             :   //   export {b as c};
     199             :   // in the presence of an import statement of the form
     200             :   //   import {a as b} from "X";
     201             :   // This function finds such implicitly indirect export entries and rewrites
     202             :   // them by filling in the import name and module request, as well as nulling
     203             :   // out the local name.  Effectively, it turns
     204             :   //   import {a as b} from "X"; export {b as c};
     205             :   // into:
     206             :   //   import {a as b} from "X"; export {a as c} from "X";
     207             :   // (The import entry is never deleted.)
     208             :   void MakeIndirectExportsExplicit(Zone* zone);
     209             : 
     210             :   // Assign a cell_index of -1,-2,... to regular imports.
     211             :   // Assign a cell_index of +1,+2,... to regular (local) exports.
     212             :   // Assign a cell_index of 0 to anything else.
     213             :   void AssignCellIndices();
     214             : 
     215        1203 :   int AddModuleRequest(const AstRawString* specifier) {
     216             :     DCHECK_NOT_NULL(specifier);
     217        1203 :     int module_requests_count = static_cast<int>(module_requests_.size());
     218             :     auto it = module_requests_
     219        2406 :                   .insert(std::make_pair(specifier, module_requests_count))
     220             :                   .first;
     221        1203 :     return it->second;
     222             :   }
     223             : };
     224             : 
     225             : }  // namespace internal
     226             : }  // namespace v8
     227             : 
     228             : #endif  // V8_AST_MODULES_H_

Generated by: LCOV version 1.10