• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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