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 *> &¶ms; 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