1 /* 2 * Copyright (c) 2023 - 2025 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 PANDA_IMPORTEXPORTDECLS_H 17 #define PANDA_IMPORTEXPORTDECLS_H 18 19 #include <parser/ETSparser.h> 20 #include "varbinder/ETSBinder.h" 21 #include "compiler/lowering/phase.h" 22 #include "ir/visitor/IterateAstVisitor.h" 23 #include "globalClassHandler.h" 24 25 namespace ark::es2panda::compiler { 26 27 class SavedImportExportDeclsContext; 28 class ImportExportDecls : ir::visitor::EmptyAstVisitor { 29 static constexpr std::string_view DEFAULT_IMPORT_SOURCE_FILE = "<default_import>.ets"; 30 CreateDefaultImportSource(const std::vector<std::string> & paths)31 static std::string CreateDefaultImportSource(const std::vector<std::string> &paths) 32 { 33 std::string importStdlibFile; 34 for (const auto &path : paths) { 35 importStdlibFile += "import * from \"" + path + "\";"; 36 } 37 return importStdlibFile; 38 } 39 40 const std::string defaultImportSource_ = CreateDefaultImportSource(util::Helpers::StdLib()); 41 42 public: 43 ImportExportDecls() = default; ImportExportDecls(varbinder::ETSBinder * varbinder,parser::ETSParser * parser)44 ImportExportDecls(varbinder::ETSBinder *varbinder, parser::ETSParser *parser) 45 : varbinder_(varbinder), parser_(parser) 46 { 47 } 48 49 /** 50 * Add stdlib names to default imports 51 */ 52 void ParseDefaultSources(); 53 54 /** 55 * Verifies import errors, and add Exported flag to top level variables and methods 56 * @param global_stmts program global statements 57 */ 58 GlobalClassHandler::ModuleDependencies HandleGlobalStmts(ArenaVector<parser::Program *> &programs); 59 void ProcessProgramStatements(parser::Program *program, const ArenaVector<ir::Statement *> &statements, 60 GlobalClassHandler::ModuleDependencies &moduleDependencies); 61 void VerifyTypeExports(const ArenaVector<parser::Program *> &programs); 62 void VerifyType(ir::Statement *stmt, std::set<util::StringView> &exportedStatements, 63 std::map<util::StringView, ir::AstNode *> &typesMap); 64 void HandleSimpleType(std::set<util::StringView> &exportedStatements, ir::Statement *stmt, util::StringView name); 65 66 void VerifySingleExportDefault(const ArenaVector<parser::Program *> &programs); 67 void AddExportFlags(ir::AstNode *node, util::StringView originalFieldName, bool exportedWithAlias); 68 void HandleSelectiveExportWithAlias(util::StringView originalFieldName, util::StringView exportName, 69 lexer::SourcePosition startLoc); 70 void PopulateAliasMap(const ir::ExportNamedDeclaration *decl, const util::StringView &path); 71 void PopulateAliasMap(const ir::TSTypeAliasDeclaration *decl, const util::StringView &path); 72 void VerifyCollectedExportName(const parser::Program *program); 73 void PreMergeNamespaces(parser::Program *program); 74 75 private: 76 void VisitFunctionDeclaration(ir::FunctionDeclaration *funcDecl) override; 77 void VisitVariableDeclaration(ir::VariableDeclaration *varDecl) override; 78 void VisitExportNamedDeclaration(ir::ExportNamedDeclaration *exportDecl) override; 79 void VisitClassDeclaration(ir::ClassDeclaration *classDecl) override; 80 void VisitTSEnumDeclaration(ir::TSEnumDeclaration *enumDecl) override; 81 void VisitTSTypeAliasDeclaration(ir::TSTypeAliasDeclaration *typeAliasDecl) override; 82 void VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration *interfaceDecl) override; 83 void VisitETSImportDeclaration(ir::ETSImportDeclaration *importDecl) override; 84 void VisitAnnotationDeclaration(ir::AnnotationDeclaration *annotationDecl) override; 85 void VisitETSModule(ir::ETSModule *etsModule) override; 86 87 private: 88 varbinder::ETSBinder *varbinder_ {nullptr}; 89 std::map<util::StringView, ir::AstNode *> fieldMap_; 90 std::map<util::StringView, lexer::SourcePosition> exportNameMap_; 91 std::set<util::StringView> exportedTypes_; 92 parser::ETSParser *parser_ {nullptr}; 93 std::map<util::StringView, util::StringView> importedSpecifiersForExportCheck_; 94 lexer::SourcePosition lastExportErrorPos_ {}; 95 util::StringView exportDefaultName_; 96 97 friend class SavedImportExportDeclsContext; 98 }; 99 100 class SavedImportExportDeclsContext { 101 public: SavedImportExportDeclsContext(ImportExportDecls * imExDecl,parser::Program * program)102 explicit SavedImportExportDeclsContext(ImportExportDecls *imExDecl, parser::Program *program) 103 : imExDecl_(imExDecl), 104 program_(program), 105 fieldMapPrev_(imExDecl_->fieldMap_), 106 exportNameMapPrev_(imExDecl_->exportNameMap_), 107 exportedTypesPrev_(imExDecl_->exportedTypes_), 108 exportDefaultNamePrev_(imExDecl_->exportDefaultName_), 109 exportAliasMultimapPrev_(SaveExportAliasMultimap()) 110 { 111 ClearImportExportDecls(); 112 UpdateExportMap(); 113 } 114 RecoverExportAliasMultimap()115 void RecoverExportAliasMultimap() 116 { 117 auto &exportMap = imExDecl_->varbinder_->GetSelectiveExportAliasMultimap(); 118 119 exportMap.erase(program_->SourceFilePath()); 120 exportMap.insert({program_->SourceFilePath(), exportAliasMultimapPrev_}); 121 } 122 123 NO_COPY_SEMANTIC(SavedImportExportDeclsContext); 124 DEFAULT_MOVE_SEMANTIC(SavedImportExportDeclsContext); 125 ~SavedImportExportDeclsContext()126 ~SavedImportExportDeclsContext() 127 { 128 RestoreImportExportDecls(); 129 } 130 131 private: ClearImportExportDecls()132 void ClearImportExportDecls() 133 { 134 imExDecl_->fieldMap_.clear(); 135 imExDecl_->exportNameMap_.clear(); 136 imExDecl_->exportedTypes_.clear(); 137 imExDecl_->exportDefaultName_ = nullptr; 138 } 139 UpdateExportMap()140 void UpdateExportMap() 141 { 142 auto &exportMap = imExDecl_->varbinder_->GetSelectiveExportAliasMultimap(); 143 if (auto it = exportMap.find(program_->SourceFilePath()); it != exportMap.end()) { 144 exportAliasMultimapPrev_ = it->second; 145 exportMap.erase(it); 146 } 147 148 ArenaMap<util::StringView, std::pair<util::StringView, ir::AstNode const *>> newMap( 149 program_->Allocator()->Adapter()); 150 exportMap.insert({program_->SourceFilePath(), newMap}); 151 } 152 RestoreImportExportDecls()153 void RestoreImportExportDecls() noexcept 154 { 155 imExDecl_->fieldMap_ = fieldMapPrev_; 156 imExDecl_->exportNameMap_ = exportNameMapPrev_; 157 imExDecl_->exportedTypes_ = exportedTypesPrev_; 158 imExDecl_->exportDefaultName_ = exportDefaultNamePrev_; 159 } 160 SaveExportAliasMultimap()161 ArenaMap<util::StringView, std::pair<util::StringView, ir::AstNode const *>> SaveExportAliasMultimap() 162 { 163 auto &exportMap = imExDecl_->varbinder_->GetSelectiveExportAliasMultimap(); 164 const auto found = exportMap.find(program_->SourceFilePath()); 165 if (found == exportMap.end()) { 166 return ArenaMap<util::StringView, std::pair<util::StringView, ir::AstNode const *>>( 167 program_->Allocator()->Adapter()); 168 } 169 return found->second; 170 } 171 172 private: 173 ImportExportDecls *imExDecl_; 174 parser::Program *program_; 175 std::map<util::StringView, ir::AstNode *> fieldMapPrev_; 176 std::map<util::StringView, lexer::SourcePosition> exportNameMapPrev_; 177 std::set<util::StringView> exportedTypesPrev_; 178 util::StringView exportDefaultNamePrev_; 179 ArenaMap<util::StringView, std::pair<util::StringView, ir::AstNode const *>> exportAliasMultimapPrev_; 180 }; 181 } // namespace ark::es2panda::compiler 182 183 #endif // PANDA_IMPORTEXPORTDECLS_H 184