1/**
2 * Copyright (c) 2021-2024 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_INCLUDE_PROGRAM_H
17#define ES2PANDA_PARSER_INCLUDE_PROGRAM_H
18
19#include "macros.h"
20#include "mem/pool_manager.h"
21#include "os/filesystem.h"
22#include "util/ustring.h"
23#include "util/path.h"
24#include "varbinder/varbinder.h"
25
26#include "es2panda.h"
27
28#include <set>
29
30namespace ark::es2panda::ir {
31class BlockStatement;
32}  // namespace ark::es2panda::ir
33
34namespace ark::es2panda::varbinder {
35class VarBinder;
36}  // namespace ark::es2panda::varbinder
37
38namespace ark::es2panda::parser {
39enum class ScriptKind { SCRIPT, MODULE, STDLIB };
40
41class Program {
42public:
43    using ExternalSource = ArenaUnorderedMap<util::StringView, ArenaVector<Program *>>;
44    using DirectExternalSource = ArenaUnorderedMap<util::StringView, ArenaVector<Program *>>;
45
46    using ETSNolintsCollectionMap = ArenaUnorderedMap<const ir::AstNode *, ArenaSet<ETSWarnings>>;
47
48    template <typename T>
49    static Program NewProgram(ArenaAllocator *allocator)
50    {
51        auto *varbinder = allocator->New<T>(allocator);
52        return Program(allocator, varbinder);
53    }
54
55    Program(ArenaAllocator *allocator, varbinder::VarBinder *varbinder)
56        : allocator_(allocator),
57          varbinder_(varbinder),
58          externalSources_(allocator_->Adapter()),
59          directExternalSources_(allocator_->Adapter()),
60          extension_(varbinder->Extension()),
61          etsnolintCollection_(allocator_->Adapter())
62    {
63    }
64
65    void SetKind(ScriptKind kind)
66    {
67        kind_ = kind;
68    }
69
70    NO_COPY_SEMANTIC(Program);
71    DEFAULT_MOVE_SEMANTIC(Program);
72
73    ~Program() = default;
74
75    ArenaAllocator *Allocator() const
76    {
77        return allocator_;
78    }
79
80    const varbinder::VarBinder *VarBinder() const
81    {
82        return varbinder_;
83    }
84
85    varbinder::VarBinder *VarBinder()
86    {
87        return varbinder_;
88    }
89
90    ScriptExtension Extension() const
91    {
92        return extension_;
93    }
94
95    ScriptKind Kind() const
96    {
97        return kind_;
98    }
99
100    util::StringView SourceCode() const
101    {
102        return sourceCode_;
103    }
104
105    const util::StringView &SourceFilePath() const
106    {
107        return sourceFile_.GetPath();
108    }
109
110    const util::Path &SourceFile() const
111    {
112        return sourceFile_;
113    }
114
115    util::StringView SourceFileFolder() const
116    {
117        return sourceFileFolder_;
118    }
119
120    util::StringView FileName() const
121    {
122        return sourceFile_.GetFileName();
123    }
124
125    util::StringView AbsoluteName() const
126    {
127        return sourceFile_.GetAbsolutePath();
128    }
129
130    util::StringView ResolvedFilePath() const
131    {
132        return resolvedFilePath_;
133    }
134
135    ir::BlockStatement *Ast()
136    {
137        return ast_;
138    }
139
140    const ir::BlockStatement *Ast() const
141    {
142        return ast_;
143    }
144
145    void SetAst(ir::BlockStatement *ast)
146    {
147        ast_ = ast;
148    }
149
150    ir::ClassDefinition *GlobalClass()
151    {
152        return globalClass_;
153    }
154
155    const ir::ClassDefinition *GlobalClass() const
156    {
157        return globalClass_;
158    }
159
160    void SetGlobalClass(ir::ClassDefinition *globalClass)
161    {
162        globalClass_ = globalClass;
163    }
164
165    ExternalSource &ExternalSources()
166    {
167        return externalSources_;
168    }
169
170    const ExternalSource &ExternalSources() const
171    {
172        return externalSources_;
173    }
174
175    DirectExternalSource &DirectExternalSources()
176    {
177        return directExternalSources_;
178    }
179
180    const DirectExternalSource &DirectExternalSources() const
181    {
182        return directExternalSources_;
183    }
184
185    void SetSource(const util::StringView &sourceCode, const util::StringView &sourceFilePath,
186                   const util::StringView &sourceFileFolder)
187    {
188        sourceCode_ = sourceCode;
189        sourceFile_ = util::Path(sourceFilePath, Allocator());
190        sourceFileFolder_ = sourceFileFolder;
191    }
192
193    void SetSource(const ark::es2panda::SourceFile &sourceFile)
194    {
195        sourceCode_ = util::UString(sourceFile.source, Allocator()).View();
196        sourceFile_ = util::Path(sourceFile.filePath, Allocator());
197        sourceFileFolder_ = util::UString(sourceFile.fileFolder, Allocator()).View();
198        resolvedFilePath_ = util::UString(sourceFile.resolvedPath, Allocator()).View();
199    }
200
201    void SetModuleInfo(const util::StringView &name, bool isPackage, bool omitName = false)
202    {
203        moduleInfo_.moduleName = name;
204        moduleInfo_.isPackageModule = isPackage;
205        moduleInfo_.omitModuleName = omitName;
206    }
207
208    const util::StringView &ModuleName() const
209    {
210        return moduleInfo_.moduleName;
211    }
212
213    bool IsPackageModule() const
214    {
215        return moduleInfo_.isPackageModule;
216    }
217
218    bool IsDeclarationModule() const
219    {
220        return moduleInfo_.isDeclModule;
221    }
222
223    bool OmitModuleName() const
224    {
225        return moduleInfo_.omitModuleName;
226    }
227
228    const bool &IsEntryPoint() const
229    {
230        return entryPoint_;
231    }
232
233    void MarkEntry()
234    {
235        entryPoint_ = true;
236    }
237
238    void MarkASTAsChecked()
239    {
240        isASTchecked_ = true;
241    }
242
243    bool IsASTChecked() const
244    {
245        return isASTchecked_;
246    }
247
248    bool IsStdLib() const
249    {
250        // NOTE (hurton): temporary solution, needs rework when std sources are renamed
251        return (ModuleName().Mutf8().rfind("std.", 0) == 0) || (ModuleName().Mutf8().rfind("escompat", 0) == 0) ||
252               (FileName().Is("etsstdlib"));
253    }
254
255    void SetDeclarationModuleInfo();
256
257    varbinder::ClassScope *GlobalClassScope();
258    const varbinder::ClassScope *GlobalClassScope() const;
259
260    varbinder::GlobalScope *GlobalScope();
261    const varbinder::GlobalScope *GlobalScope() const;
262
263    std::string Dump() const;
264
265    void DumpSilent() const;
266
267    void AddNodeToETSNolintCollection(const ir::AstNode *node, const std::set<ETSWarnings> &warningsCollection);
268    bool NodeContainsETSNolint(const ir::AstNode *node, ETSWarnings warning);
269
270private:
271    struct ModuleInfo {
272        explicit ModuleInfo(util::StringView name = util::StringView(), bool isPackage = false, bool omitName = false)
273            : moduleName(name), isPackageModule(isPackage), omitModuleName(omitName)
274        {
275        }
276
277        // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
278        util::StringView moduleName;
279        bool isPackageModule;
280        bool omitModuleName;  // unclear naming, used to determine the entry point without --ets-module option
281        bool isDeclModule = false;
282        // NOLINTEND(misc-non-private-member-variables-in-classes)
283    };
284
285    ArenaAllocator *allocator_ {};
286    varbinder::VarBinder *varbinder_ {};
287    ir::BlockStatement *ast_ {};
288    ir::ClassDefinition *globalClass_ {};
289    util::StringView sourceCode_ {};
290    util::Path sourceFile_ {};
291    util::StringView sourceFileFolder_ {};
292    util::StringView resolvedFilePath_ {};
293    ExternalSource externalSources_;
294    DirectExternalSource directExternalSources_;
295    ScriptKind kind_ {};
296    ScriptExtension extension_ {};
297    bool entryPoint_ {};
298    ETSNolintsCollectionMap etsnolintCollection_;
299    ModuleInfo moduleInfo_ {};
300    bool isASTchecked_ {};
301};
302}  // namespace ark::es2panda::parser
303
304#endif
305