1 /*
2  * Copyright (c) 2023 - 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 PANDA_GLOBALCLASSHANDLER_H
17 #define PANDA_GLOBALCLASSHANDLER_H
18 
19 #include "parser/program/program.h"
20 #include "public/public.h"
21 #include "ir/astNode.h"
22 
23 namespace ark::es2panda::compiler {
24 
25 class GlobalClassHandler {
26 public:
27     using ModuleDependencies = ArenaUnorderedSet<parser::Program *>;
28 
29     struct GlobalStmts {
30         parser::Program *program;
31         ArenaVector<ir::Statement *> statements;
32     };
GlobalClassHandler(parser::ETSParser *parser, ArenaAllocator *allocator)33     explicit GlobalClassHandler(parser::ETSParser *parser, ArenaAllocator *allocator)
34         : parser_(parser), allocator_(allocator) {};
35 
36     /**
37      * Each "Module" has it's own global class, which contains all top level statements across "module"
38      * Result - creation of global class and _$init$_ method
39      * @param programs - vector of files in module
40      */
41     void SetupGlobalClass(const ArenaVector<parser::Program *> &programs, const ModuleDependencies *moduleDependencies);
42 
43 private:
44     /**
45      * Move top level statements to _$init$_ and
46      * @param program program of module
47      * @param init_statements statements which should be executed
48      */
49     void SetupGlobalMethods(parser::Program *program, ArenaVector<ir::Statement *> &&statements,
50                             bool mainExists = false, bool topLevelStatementsExist = false);
51 
52     ir::ClassDeclaration *CreateGlobalClass();
53     ir::ClassStaticBlock *CreateStaticBlock(ir::ClassDefinition *classDef);
54     ir::MethodDefinition *CreateGlobalMethod(const std::string_view name, ArenaVector<ir::Statement *> &&statements);
55     void AddInitCallFromStaticBlock(ir::ClassDefinition *globalClass, ir::MethodDefinition *initMethod);
56 
57     ArenaVector<ir::Statement *> FormInitMethodStatements(parser::Program *program,
58                                                           const ModuleDependencies *moduleDependencies,
59                                                           ArenaVector<GlobalStmts> &&initStatements);
60 
61     void FormDependentInitTriggers(ArenaVector<ir::Statement *> &statements,
62                                    const ModuleDependencies *moduleDependencies);
63 
64     /**
65      *
66      * @param program leave only declarations here
67      * @param class_def add new properties such as methods and fields
68      * @param addInitializer $init$ should contain global variable initializers
69      * @return Statements, which should be executed before the start
70      */
71     ArenaVector<ir::Statement *> CollectProgramGlobalStatements(parser::Program *program, ir::ClassDefinition *classDef,
72                                                                 bool addInitializer);
73 
74     ir::Identifier *RefIdent(const util::StringView &name);
75     util::UString ReplaceSpecialCharacters(util::UString *word) const;
76 
77     parser::ETSParser *const parser_;
78     ArenaAllocator *const allocator_;
79 };
80 }  // namespace ark::es2panda::compiler
81 
82 #endif  // PANDA_GLOBALCLASSHANDLER_H
83