LCOV - code coverage report
Current view: top level - src/ast - modules.h (source / functions) Hit Total Coverage
Test: app.info Lines: 8 8 100.0 %
Date: 2019-04-18 Functions: 0 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             :   explicit ModuleDescriptor(Zone* zone)
      23             :       : module_requests_(zone),
      24             :         special_exports_(zone),
      25             :         namespace_imports_(zone),
      26             :         regular_exports_(zone),
      27             :         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(const AstRawString* import_name,
      36             :                  const AstRawString* local_name,
      37             :                  const AstRawString* module_request,
      38             :                  const Scanner::Location loc,
      39             :                  const Scanner::Location specifier_loc, Zone* zone);
      40             : 
      41             :   // import * as x from "foo.js";
      42             :   void AddStarImport(const AstRawString* local_name,
      43             :                      const AstRawString* module_request,
      44             :                      const Scanner::Location loc,
      45             :                      const Scanner::Location specifier_loc, Zone* zone);
      46             : 
      47             :   // import "foo.js";
      48             :   // import {} from "foo.js";
      49             :   // export {} from "foo.js";  (sic!)
      50             :   void AddEmptyImport(const AstRawString* module_request,
      51             :                       const Scanner::Location specifier_loc);
      52             : 
      53             :   // export {x};
      54             :   // export {x as y};
      55             :   // export VariableStatement
      56             :   // export Declaration
      57             :   // export default ...
      58             :   void AddExport(
      59             :     const AstRawString* local_name, const AstRawString* export_name,
      60             :     const Scanner::Location loc, Zone* zone);
      61             : 
      62             :   // export {x} from "foo.js";
      63             :   // export {x as y} from "foo.js";
      64             :   void AddExport(const AstRawString* export_name,
      65             :                  const AstRawString* import_name,
      66             :                  const AstRawString* module_request,
      67             :                  const Scanner::Location loc,
      68             :                  const Scanner::Location specifier_loc, Zone* zone);
      69             : 
      70             :   // export * from "foo.js";
      71             :   void AddStarExport(const AstRawString* module_request,
      72             :                      const Scanner::Location loc,
      73             :                      const Scanner::Location specifier_loc, Zone* zone);
      74             : 
      75             :   // Check if module is well-formed and report error if not.
      76             :   // Also canonicalize indirect exports.
      77             :   bool Validate(ModuleScope* module_scope,
      78             :                 PendingCompilationErrorHandler* error_handler, Zone* zone);
      79             : 
      80             :   struct Entry : public ZoneObject {
      81             :     Scanner::Location location;
      82             :     const AstRawString* export_name;
      83             :     const AstRawString* local_name;
      84             :     const AstRawString* import_name;
      85             : 
      86             :     // The module_request value records the order in which modules are
      87             :     // requested. It also functions as an index into the ModuleInfo's array of
      88             :     // module specifiers and into the Module's array of requested modules.  A
      89             :     // negative value means no module request.
      90             :     int module_request;
      91             : 
      92             :     // Import/export entries that are associated with a MODULE-allocated
      93             :     // variable (i.e. regular_imports and regular_exports after Validate) use
      94             :     // the cell_index value to encode the location of their cell.  During
      95             :     // variable allocation, this will be be copied into the variable's index
      96             :     // field.
      97             :     // Entries that are not associated with a MODULE-allocated variable have
      98             :     // GetCellIndexKind(cell_index) == kInvalid.
      99             :     int cell_index;
     100             : 
     101             :     // TODO(neis): Remove local_name component?
     102             :     explicit Entry(Scanner::Location loc)
     103             :         : location(loc),
     104             :           export_name(nullptr),
     105             :           local_name(nullptr),
     106             :           import_name(nullptr),
     107             :           module_request(-1),
     108       21893 :           cell_index(0) {}
     109             : 
     110             :     Handle<ModuleInfoEntry> Serialize(Isolate* isolate) const;
     111             :   };
     112             : 
     113             :   enum CellIndexKind { kInvalid, kExport, kImport };
     114             :   static CellIndexKind GetCellIndexKind(int cell_index);
     115             : 
     116             :   struct ModuleRequest {
     117             :     int index;
     118             :     int position;
     119             :     ModuleRequest(int index, int position) : index(index), position(position) {}
     120             :   };
     121             : 
     122             :   // Custom content-based comparer for the below maps, to keep them stable
     123             :   // across parses.
     124             :   struct V8_EXPORT_PRIVATE AstRawStringComparer {
     125             :     bool operator()(const AstRawString* lhs, const AstRawString* rhs) const;
     126             :   };
     127             : 
     128             :   typedef ZoneMap<const AstRawString*, ModuleRequest, AstRawStringComparer>
     129             :       ModuleRequestMap;
     130             :   typedef ZoneMultimap<const AstRawString*, Entry*, AstRawStringComparer>
     131             :       RegularExportMap;
     132             :   typedef ZoneMap<const AstRawString*, Entry*, AstRawStringComparer>
     133             :       RegularImportMap;
     134             : 
     135             :   // Module requests.
     136             :   const ModuleRequestMap& module_requests() const { return module_requests_; }
     137             : 
     138             :   // Namespace imports.
     139             :   const ZoneVector<const Entry*>& namespace_imports() const {
     140             :     return namespace_imports_;
     141             :   }
     142             : 
     143             :   // All the remaining imports, indexed by local name.
     144             :   const RegularImportMap& regular_imports() const { return regular_imports_; }
     145             : 
     146             :   // Star exports and explicitly indirect exports.
     147             :   const ZoneVector<const Entry*>& special_exports() const {
     148             :     return special_exports_;
     149             :   }
     150             : 
     151             :   // All the remaining exports, indexed by local name.
     152             :   // After canonicalization (see Validate), these are exactly the local exports.
     153             :   const RegularExportMap& regular_exports() const { return regular_exports_; }
     154             : 
     155             :   void AddRegularExport(Entry* entry) {
     156             :     DCHECK_NOT_NULL(entry->export_name);
     157             :     DCHECK_NOT_NULL(entry->local_name);
     158             :     DCHECK_NULL(entry->import_name);
     159             :     DCHECK_LT(entry->module_request, 0);
     160       38308 :     regular_exports_.insert(std::make_pair(entry->local_name, entry));
     161             :   }
     162             : 
     163             :   void AddSpecialExport(const Entry* entry, Zone* zone) {
     164             :     DCHECK_NULL(entry->local_name);
     165             :     DCHECK_LE(0, entry->module_request);
     166         380 :     special_exports_.push_back(entry);
     167             :   }
     168             : 
     169             :   void AddRegularImport(Entry* entry) {
     170             :     DCHECK_NOT_NULL(entry->import_name);
     171             :     DCHECK_NOT_NULL(entry->local_name);
     172             :     DCHECK_NULL(entry->export_name);
     173             :     DCHECK_LE(0, entry->module_request);
     174        4308 :     regular_imports_.insert(std::make_pair(entry->local_name, entry));
     175             :     // We don't care if there's already an entry for this local name, as in that
     176             :     // case we will report an error when declaring the variable.
     177             :   }
     178             : 
     179             :   void AddNamespaceImport(const Entry* entry, Zone* zone) {
     180             :     DCHECK_NULL(entry->import_name);
     181             :     DCHECK_NULL(entry->export_name);
     182             :     DCHECK_NOT_NULL(entry->local_name);
     183             :     DCHECK_LE(0, entry->module_request);
     184         260 :     namespace_imports_.push_back(entry);
     185             :   }
     186             : 
     187             :   Handle<FixedArray> SerializeRegularExports(Isolate* isolate,
     188             :                                              Zone* zone) const;
     189             : 
     190             :  private:
     191             :   ModuleRequestMap module_requests_;
     192             :   ZoneVector<const Entry*> special_exports_;
     193             :   ZoneVector<const Entry*> namespace_imports_;
     194             :   RegularExportMap regular_exports_;
     195             :   RegularImportMap regular_imports_;
     196             : 
     197             :   // If there are multiple export entries with the same export name, return the
     198             :   // last of them (in source order).  Otherwise return nullptr.
     199             :   const Entry* FindDuplicateExport(Zone* zone) const;
     200             : 
     201             :   // Find any implicitly indirect exports and make them explicit.
     202             :   //
     203             :   // An explicitly indirect export is an export entry arising from an export
     204             :   // statement of the following form:
     205             :   //   export {a as c} from "X";
     206             :   // An implicitly indirect export corresponds to
     207             :   //   export {b as c};
     208             :   // in the presence of an import statement of the form
     209             :   //   import {a as b} from "X";
     210             :   // This function finds such implicitly indirect export entries and rewrites
     211             :   // them by filling in the import name and module request, as well as nulling
     212             :   // out the local name.  Effectively, it turns
     213             :   //   import {a as b} from "X"; export {b as c};
     214             :   // into:
     215             :   //   import {a as b} from "X"; export {a as c} from "X";
     216             :   // (The import entry is never deleted.)
     217             :   void MakeIndirectExportsExplicit(Zone* zone);
     218             : 
     219             :   // Assign a cell_index of -1,-2,... to regular imports.
     220             :   // Assign a cell_index of +1,+2,... to regular (local) exports.
     221             :   // Assign a cell_index of 0 to anything else.
     222             :   void AssignCellIndices();
     223             : 
     224             :   int AddModuleRequest(const AstRawString* specifier,
     225             :                        Scanner::Location specifier_loc) {
     226             :     DCHECK_NOT_NULL(specifier);
     227        2884 :     int module_requests_count = static_cast<int>(module_requests_.size());
     228             :     auto it = module_requests_
     229        5768 :                   .insert(std::make_pair(specifier,
     230             :                                          ModuleRequest(module_requests_count,
     231             :                                                        specifier_loc.beg_pos)))
     232             :                   .first;
     233        2739 :     return it->second.index;
     234             :   }
     235             : };
     236             : 
     237             : }  // namespace internal
     238             : }  // namespace v8
     239             : 
     240             : #endif  // V8_AST_MODULES_H_

Generated by: LCOV version 1.10