1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#ifndef ES2PANDA_PARSER_CORE_MODULERECORD_H 17#define ES2PANDA_PARSER_CORE_MODULERECORD_H 18 19#include <util/ustring.h> 20 21namespace panda::es2panda::binder { 22class ModuleScope; 23class Variable; 24} 25 26namespace panda::es2panda::ir { 27class Identifier; 28} // namespace panda::es2panda::ir 29 30namespace panda::es2panda::parser { 31class SourceTextModuleRecord { 32public: 33 explicit SourceTextModuleRecord(ArenaAllocator *allocator) 34 : allocator_(allocator), 35 moduleRequestsMap_(allocator_->Adapter()), 36 moduleRequests_(allocator_->Adapter()), 37 localExportEntries_(allocator_->Adapter()), 38 regularImportEntries_(allocator_->Adapter()), 39 namespaceImportEntries_(allocator_->Adapter()), 40 starExportEntries_(allocator_->Adapter()), 41 indirectExportEntries_(allocator_->Adapter()) 42 { 43 } 44 45 ~SourceTextModuleRecord() = default; 46 NO_COPY_SEMANTIC(SourceTextModuleRecord); 47 NO_MOVE_SEMANTIC(SourceTextModuleRecord); 48 49 struct ImportEntry { 50 int moduleRequestIdx_; 51 util::StringView localName_; 52 util::StringView importName_; 53 const ir::Identifier *localId_ {nullptr}; 54 const ir::Identifier *importId_ {nullptr}; 55 56 ImportEntry(const util::StringView localName, const util::StringView importName, int moduleRequestIdx, 57 const ir::Identifier *localId, const ir::Identifier *importId) 58 : moduleRequestIdx_(moduleRequestIdx), localName_(localName), importName_(importName), 59 localId_(localId), importId_(importId) {} 60 ImportEntry(const util::StringView localName, int moduleRequestIdx, const ir::Identifier *localId) 61 : moduleRequestIdx_(moduleRequestIdx), localName_(localName), localId_(localId) {} 62 }; 63 64 struct ExportEntry { 65 int moduleRequestIdx_; 66 util::StringView exportName_; 67 util::StringView localName_; 68 util::StringView importName_; 69 const ir::Identifier *exportId_ {nullptr}; 70 const ir::Identifier *localId_ {nullptr}; 71 const ir::Identifier *importId_ {nullptr}; 72 bool isConstant_ {false}; 73 74 explicit ExportEntry(int moduleRequest) : moduleRequestIdx_(moduleRequest) {} 75 ExportEntry(const util::StringView exportName, const util::StringView localName, 76 const ir::Identifier *exportId, const ir::Identifier *localId) 77 : moduleRequestIdx_(-1), exportName_(exportName), localName_(localName), 78 exportId_(exportId), localId_(localId) {} 79 ExportEntry(const util::StringView exportName, const util::StringView importName, int moduleRequest, 80 const ir::Identifier *exportId, const ir::Identifier *importId) 81 : moduleRequestIdx_(moduleRequest), exportName_(exportName), importName_(importName), 82 exportId_(exportId), importId_(importId) {} 83 84 void SetAsConstant() 85 { 86 isConstant_ = true; 87 } 88 }; 89 90 struct ModuleRequestRecord { 91 util::StringView source_; 92 bool isLazy_ {false}; 93 94 explicit ModuleRequestRecord(util::StringView source) : source_{source} {} 95 ModuleRequestRecord(util::StringView source, bool isLazy) : source_{source}, isLazy_{isLazy} {} 96 97 bool operator<(const ModuleRequestRecord &mrr) const 98 { 99 return source_ < mrr.source_ || (source_ == mrr.source_ && isLazy_ && !mrr.isLazy_); 100 } 101 }; 102 103 template <typename T, typename... Args> 104 T *NewEntry(Args &&... args) 105 { 106 return allocator_->New<T>(std::forward<Args>(args)...); 107 } 108 109 template <typename... Args> 110 int AddModuleRequest(Args &&... args) 111 { 112 const auto *record = allocator_->New<ModuleRequestRecord>(std::forward<Args>(args)...); 113 CHECK_NOT_NULL(record); 114 return AddModuleRequest(*record); 115 } 116 int AddModuleRequest(const ModuleRequestRecord record); 117 void AddImportEntry(ImportEntry *entry); 118 void AddStarImportEntry(ImportEntry *entry); 119 bool AddLocalExportEntry(ExportEntry *entry); 120 void RemoveDefaultLocalExportEntry(); 121 bool AddIndirectExportEntry(ExportEntry *entry); 122 void AddStarExportEntry(ExportEntry *entry); 123 124 bool CheckImplicitIndirectExport(ExportEntry *exportEntry); 125 void CheckImplicitIndirectExport(ImportEntry *importEntry); 126 127 void AssignIndexToModuleVariable(binder::ModuleScope *moduleScope); 128 int GetModuleRequestIdx(const util::StringView localName); 129 130 using ModuleRequestList = ArenaVector<ModuleRequestRecord>; 131 using ModuleRequestMap = ArenaMap<const ModuleRequestRecord, uint32_t>; 132 using LocalExportEntryMap = ArenaMultiMap<const util::StringView, ExportEntry *>; 133 using RegularImportEntryMap = ArenaMap<const util::StringView, ImportEntry *>; 134 using NamespaceImportEntryList = ArenaVector<ImportEntry *>; 135 using SpecialExportEntryList = ArenaVector<ExportEntry *>; 136 137 const ModuleRequestList &GetModuleRequests() const 138 { 139 return moduleRequests_; 140 } 141 142 const LocalExportEntryMap &GetLocalExportEntries() const 143 { 144 return localExportEntries_; 145 } 146 147 const RegularImportEntryMap &GetRegularImportEntries() const 148 { 149 return regularImportEntries_; 150 } 151 152 const NamespaceImportEntryList &GetNamespaceImportEntries() const 153 { 154 return namespaceImportEntries_; 155 } 156 157 const SpecialExportEntryList &GetStarExportEntries() const 158 { 159 return starExportEntries_; 160 } 161 162 const SpecialExportEntryList &GetIndirectExportEntries() const 163 { 164 return indirectExportEntries_; 165 } 166 167 bool HasLazyImport() const 168 { 169 return hasLazyImport_; 170 } 171 172 static constexpr std::string_view DEFAULT_LOCAL_NAME = "*default*"; 173 static constexpr std::string_view DEFAULT_EXTERNAL_NAME = "default"; 174 static constexpr std::string_view ANONY_NAMESPACE_NAME = "=ens"; 175 static constexpr int INVALID_MODULEREQUEST_ID = -1; 176 177private: 178 bool HasDuplicateExport(util::StringView exportName) const; 179 void ConvertLocalExportToIndirect(ImportEntry *importEntry, ExportEntry *exportEntry); 180 binder::Variable *CheckAndAssignIndex(binder::ModuleScope *moduleScope, util::StringView name, uint32_t *idx) const; 181 182 ArenaAllocator *allocator_; 183 ModuleRequestMap moduleRequestsMap_; 184 ModuleRequestList moduleRequests_; 185 LocalExportEntryMap localExportEntries_; 186 RegularImportEntryMap regularImportEntries_; 187 NamespaceImportEntryList namespaceImportEntries_; 188 SpecialExportEntryList starExportEntries_; 189 SpecialExportEntryList indirectExportEntries_; 190 bool hasLazyImport_ { false }; 191}; 192} // namespace panda::es2panda::parser 193 194#endif