• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 ES2PANDA_COMPILER_ENUM_PRE_CHECK_LOWERING_H
17 #define ES2PANDA_COMPILER_ENUM_PRE_CHECK_LOWERING_H
18 
19 #include <string>
20 #include <string_view>
21 #include "compiler/lowering/phase.h"
22 
23 namespace ark::es2panda::compiler {
24 
25 class EnumLoweringPhase : public PhaseForDeclarations {
26 public:
27     static constexpr std::string_view const STRING_REFERENCE_TYPE {"String"};
28     static constexpr std::string_view const IDENTIFIER_I {"i"};
29     static constexpr std::string_view const PARAM_NAME {"name"};
30     static constexpr std::string_view const PARAM_VALUE {"value"};
31     static constexpr std::string_view const PARAM_ORDINAL {"ordinal"};
32     static constexpr std::string_view const STRING_VALUES_ARRAY_NAME {"#StringValuesArray"};
33     static constexpr std::string_view const ITEMS_ARRAY_NAME {"#ItemsArray"};
34     static constexpr std::string_view const NAMES_ARRAY_NAME {"#NamesArray"};
35     static constexpr std::string_view const VALUES_ARRAY_NAME {"#ValuesArray"};
36     static constexpr std::string_view const ORDINAL_NAME {"#ordinal"};
37     static constexpr std::string_view const BASE_CLASS_NAME {"BaseEnum"};
38 
39     enum EnumType { INT = 0, LONG = 1, STRING = 2 };
40 
41     struct DeclarationFlags {
42         // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
43         bool isTopLevel;
44         bool isLocal;
45         bool isNamespace;
46         // NOLINTEND(misc-non-private-member-variables-in-classes)
47 
IsValidDeclarationFlags48         [[nodiscard]] bool IsValid() const noexcept
49         {
50             return isTopLevel || isLocal || isNamespace;
51         }
52     };
53 
54     EnumLoweringPhase() noexcept = default;
Name()55     std::string_view Name() const override
56     {
57         return "EnumLoweringPhase";
58     }
59     bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override;
Checker()60     checker::ETSChecker *Checker()
61     {
62         return checker_;
63     }
64 
Varbinder()65     varbinder::ETSBinder *Varbinder()
66     {
67         return varbinder_;
68     }
69 
70 private:
71     struct FunctionInfo {
72         ArenaVector<ir::Expression *> &&params;
73         ArenaVector<ir::Statement *> &&body;
74         ir::TypeNode *returnTypeAnnotation;
75         const ir::TSEnumDeclaration *enumDecl;
76         ir::ModifierFlags flags;
77     };
78 
79     void LogError(const diagnostic::DiagnosticKind &diagnostic, const util::DiagnosticMessageParams &diagnosticParams,
80                   const lexer::SourcePosition &pos);
81 
82     // clang-format off
83     template <typename TypeNode>
84     bool CheckEnumMemberType(const ArenaVector<ir::AstNode *> &enumMembers, bool &hasLoggedError,
85                              bool &hasLongLiteral);
86     // clang-format on
87 
88     [[nodiscard]] ir::ScriptFunction *MakeFunction(FunctionInfo &&functionInfo);
89     ir::ClassDeclaration *CreateClass(ir::TSEnumDeclaration *const enumDecl, const DeclarationFlags flags,
90                                       EnumType enumType);
91     ir::ClassProperty *CreateOrdinalField(ir::ClassDefinition *const enumClass);
92     ir::MemberExpression *CreateOrdinalAccessExpression();
93     void CreateCCtorForEnumClass(ir::ClassDefinition *const enumClass);
94     void CreateCtorForEnumClass(ir::ClassDefinition *const enumClass, EnumType enumType);
95     ir::ScriptFunction *CreateFunctionForCtorOfEnumClass(ir::ClassDefinition *const enumClass, EnumType enumType);
96 
97     void ProcessEnumClassDeclaration(ir::TSEnumDeclaration *const enumDecl, const DeclarationFlags &flags,
98                                      ir::ClassDeclaration *enumClassDecl);
99     template <ir::PrimitiveType TYPE>
100     ir::ClassDeclaration *CreateEnumIntClassFromEnumDeclaration(ir::TSEnumDeclaration *const enumDecl,
101                                                                 const DeclarationFlags flags);
102     ir::ClassDeclaration *CreateEnumStringClassFromEnumDeclaration(ir::TSEnumDeclaration *const enumDecl,
103                                                                    const DeclarationFlags flags);
104     static void AppendParentNames(util::UString &qualifiedName, const ir::AstNode *const node);
105     template <typename ElementMaker>
106     [[nodiscard]] ir::Identifier *MakeArray(const ir::TSEnumDeclaration *const enumDecl, ir::ClassDefinition *enumClass,
107                                             const util::StringView &name, ir::TypeNode *const typeAnnotation,
108                                             ElementMaker &&elementMaker);
109     void CreateEnumItemFields(const ir::TSEnumDeclaration *const enumDecl, ir::ClassDefinition *enumClass,
110                               EnumType enumType);
111     ir::Identifier *CreateEnumNamesArray(const ir::TSEnumDeclaration *const enumDecl, ir::ClassDefinition *enumClass);
112     template <ir::PrimitiveType TYPE>
113     ir::Identifier *CreateEnumValuesArray(const ir::TSEnumDeclaration *const enumDecl, ir::ClassDefinition *enumClass);
114     ir::Identifier *CreateEnumStringValuesArray(const ir::TSEnumDeclaration *const enumDecl,
115                                                 ir::ClassDefinition *enumClass);
116     ir::Identifier *CreateEnumItemsArray(const ir::TSEnumDeclaration *const enumDecl, ir::ClassDefinition *enumClass);
117     void CreateEnumToStringMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
118                                   ir::Identifier *const stringValuesArrayIdent);
119     void CreateEnumValueOfMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
120                                  ir::Identifier *const valuesArrayIdent,
121                                  std::optional<ir::PrimitiveType> primitiveType);
122     void CreateEnumGetNameMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
123                                  ir::Identifier *const namesArrayIdent);
124     void CreateEnumGetValueOfMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
125                                     ir::Identifier *const namesArrayIdent, ir::Identifier *const itemsArrayIdent);
126     void CreateEnumFromValueMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
127                                    ir::Identifier *const valuesArrayIdent, ir::Identifier *const itemsArrayIdent,
128                                    std::optional<ir::PrimitiveType> primitiveType);
129     void CreateEnumValuesMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass,
130                                 ir::Identifier *const itemsArrayIdent);
131     void CreateEnumGetOrdinalMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass);
132     void CreateEnumDollarGetMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass);
133     void SetDefaultPositionInUnfilledClassNodes(const ir::ClassDeclaration *enumClassDecl,
134                                                 ir::TSEnumDeclaration const *const enumDecl);
135     ArenaAllocator *Allocator();
136 
137     template <typename T, typename... Args>
138     T *AllocNode(Args &&...args);
139 
140 private:
141     public_lib::Context *context_ {nullptr};
142     checker::ETSChecker *checker_ {nullptr};
143     parser::Program *program_ {nullptr};
144     varbinder::ETSBinder *varbinder_ {nullptr};
145 };
146 
147 }  // namespace ark::es2panda::compiler
148 
149 #endif  // ES2PANDA_COMPILER_ENUM_PRE_CHECK_LOWERING_H
150