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_COMPILER_ENUM_PRE_CHECK_LOWERING_H
17 #define ES2PANDA_COMPILER_ENUM_PRE_CHECK_LOWERING_H
18 
19 #include "compiler/lowering/phase.h"
20 #include "checker/types/ets/etsEnumType.h"
21 
22 namespace ark::es2panda::compiler {
23 
24 class EnumLoweringPhase : public Phase {
25 public:
26     EnumLoweringPhase() noexcept = default;
27     std::string_view Name() const override
28     {
29         return "EnumLoweringPhase";
30     }
31     bool Perform(public_lib::Context *ctx, parser::Program *program) override;
32     static util::UString GetEnumClassName(checker::ETSChecker *checker, const ir::TSEnumDeclaration *const enumDecl);
Checker()33     checker::ETSChecker *Checker()
34     {
35         return checker_;
36     }
37 
Varbinder()38     varbinder::ETSBinder *Varbinder()
39     {
40         return varbinder_;
41     }
42 
43 private:
44     struct FunctionInfo {
45         varbinder::FunctionParamScope *paramScope;
46         ArenaVector<ir::Expression *> &&params;
47         ArenaVector<ir::Statement *> &&body;
48         ir::TypeNode *returnTypeAnnotation;
49         const ir::TSEnumDeclaration *enumDecl;
50         ir::ModifierFlags flags;
51     };
52 
53     [[nodiscard]] ir::ScriptFunction *MakeFunction(FunctionInfo &&functionInfo);
54     ir::ClassDefinition *CreateClass(ir::TSEnumDeclaration *const enumDecl);
55     ir::ClassProperty *CreateOrdinalField(ir::ClassDefinition *const enumClass);
56     void CreateCCtorForEnumClass(ir::ClassDefinition *const enumClass);
57     void CreateCtorForEnumClass(ir::ClassDefinition *const enumClass);
58 
59     void CreateEnumIntClassFromEnumDeclaration(ir::TSEnumDeclaration *const enumDecl);
60     void CreateEnumStringClassFromEnumDeclaration(ir::TSEnumDeclaration *const enumDecl);
61     static void AppendParentNames(util::UString &qualifiedName, const ir::AstNode *const node);
62     template <typename ElementMaker>
63     [[nodiscard]] ir::Identifier *MakeArray(const ir::TSEnumDeclaration *const enumDecl, ir::ClassDefinition *enumClass,
64                                             const util::StringView &name, ir::TypeNode *const typeAnnotation,
65                                             ElementMaker &&elementMaker);
66 
67     ir::Identifier *CreateEnumNamesArray(const ir::TSEnumDeclaration *const enumDecl, ir::ClassDefinition *enumClass);
68     ir::Identifier *CreateEnumValuesArray(const ir::TSEnumDeclaration *const enumDecl, ir::ClassDefinition *enumClass);
69     ir::Identifier *CreateEnumStringValuesArray(const ir::TSEnumDeclaration *const enumDecl,
70                                                 ir::ClassDefinition *enumClass);
71     ir::Identifier *CreateEnumItemsArray(const ir::TSEnumDeclaration *const enumDecl, ir::ClassDefinition *enumClass);
72     ir::Identifier *CreateBoxedEnumItemsArray(const ir::TSEnumDeclaration *const enumDecl,
73                                               ir::ClassDefinition *enumClass);
74 
75     void CreateEnumFromIntMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
76                                  ir::Identifier *const arrayIdent, const util::StringView &methodName,
77                                  const util::StringView &returnTypeName);
78     void CreateEnumToStringMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
79                                   ir::Identifier *const stringValuesArrayIdent);
80     void CreateEnumValueOfMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
81                                  ir::Identifier *const valuesArrayIdent);
82     void CreateEnumGetNameMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
83                                  ir::Identifier *const namesArrayIdent);
84     void CreateEnumGetValueOfMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
85                                     ir::Identifier *const namesArrayIdent);
86     void CreateEnumValuesMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
87                                 ir::Identifier *const itemsArrayIdent);
88     void CreateUnboxingMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
89                               ir::Identifier *const itemsArrayIdent);
90 
91     ArenaAllocator *Allocator();
92 
93 private:
94     checker::ETSChecker *checker_ {nullptr};
95     parser::Program *program_ {nullptr};
96     varbinder::ETSBinder *varbinder_ {nullptr};
97 };
98 
99 }  // namespace ark::es2panda::compiler
100 
101 #endif  // ES2PANDA_COMPILER_ENUM_PRE_CHECK_LOWERING_H
102