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_CHECKER_TYPES_ETS_ENUM_TYPE_H 17 #define ES2PANDA_COMPILER_CHECKER_TYPES_ETS_ENUM_TYPE_H 18 19 #include "checker/types/type.h" 20 #include "ir/base/property.h" 21 #include "ir/ts/tsEnumDeclaration.h" 22 23 template <typename> 24 // NOLINTNEXTLINE(readability-identifier-naming) 25 inline constexpr bool dependent_false_v = false; 26 27 namespace ark::es2panda::varbinder { 28 class LocalVariable; 29 } // namespace ark::es2panda::varbinder 30 31 namespace ark::es2panda::checker { 32 template <typename T> 33 struct ETSEnumValueType { 34 using ValueType = T; 35 }; 36 37 class ETSEnumType : public Type { 38 public: 39 using UType = std::int32_t; 40 41 explicit ETSEnumType(const ir::TSEnumDeclaration *enumDecl, UType ordinal, const ir::TSEnumMember *member, 42 TypeFlag typeFlag); 43 44 NO_COPY_SEMANTIC(ETSEnumType); 45 NO_MOVE_SEMANTIC(ETSEnumType); 46 47 ETSEnumType() = delete; 48 ~ETSEnumType() override = default; 49 50 [[nodiscard]] bool AssignmentSource(TypeRelation *relation, Type *target) override; 51 52 void AssignmentTarget(TypeRelation *relation, Type *source) override; 53 54 void Cast(TypeRelation *relation, Type *target) override; 55 56 Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; 57 58 void Identical(TypeRelation *relation, Type *other) override; 59 60 void ToAssemblerType(std::stringstream &ss) const override; 61 void ToDebugInfoType(std::stringstream &ss) const override; 62 63 void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; 64 65 [[nodiscard]] const ir::TSEnumDeclaration *GetDecl() const noexcept; 66 67 [[nodiscard]] const ArenaVector<ir::AstNode *> &GetMembers() const noexcept; 68 69 [[nodiscard]] varbinder::LocalVariable *GetMemberVar() const noexcept; 70 71 [[nodiscard]] util::StringView GetName() const noexcept; 72 73 [[nodiscard]] UType GetOrdinal() const noexcept; 74 75 [[nodiscard]] ETSEnumType *LookupConstant(ETSChecker *checker, const ir::Expression *expression, 76 const ir::Identifier *prop) const; 77 78 [[nodiscard]] ETSFunctionType *LookupMethod(ETSChecker *checker, const ir::Expression *expression, 79 const ir::Identifier *prop) const; 80 81 [[nodiscard]] bool IsLiteralType() const noexcept; 82 83 [[nodiscard]] bool IsSameEnumType(const ETSEnumType *const other) const noexcept; 84 85 [[nodiscard]] bool IsSameEnumLiteralType(const ETSEnumType *const other) const noexcept; 86 87 [[nodiscard]] bool IsEnumInstanceExpression(const ir::Expression *expression) const noexcept; 88 89 [[nodiscard]] bool IsEnumLiteralExpression(const ir::Expression *expression) const noexcept; 90 91 [[nodiscard]] bool IsEnumTypeExpression(const ir::Expression *expression) const noexcept; 92 93 static constexpr std::string_view const TO_STRING_METHOD_NAME {"toString"}; 94 static constexpr std::string_view const VALUE_OF_METHOD_NAME {"valueOf"}; 95 static constexpr std::string_view const GET_NAME_METHOD_NAME {"getName"}; 96 static constexpr std::string_view const GET_VALUE_OF_METHOD_NAME {"getValueOf"}; 97 static constexpr std::string_view const VALUES_METHOD_NAME {"values"}; 98 static constexpr std::string_view const FROM_INT_METHOD_NAME {"fromInt"}; 99 static constexpr std::string_view const BOXED_FROM_INT_METHOD_NAME {"boxedfromInt"}; 100 static constexpr std::string_view const UNBOX_METHOD_NAME {"unbox"}; 101 102 struct Method { 103 Signature *globalSignature; 104 ETSFunctionType *memberProxyType; 105 }; 106 107 [[nodiscard]] Method ToStringMethod() const noexcept; SetToStringMethod(Method const & method)108 void SetToStringMethod(Method const &method) noexcept 109 { 110 toStringMethod_ = method; 111 } 112 113 [[nodiscard]] Method ValueOfMethod() const noexcept; SetValueOfMethod(Method const & method)114 void SetValueOfMethod(Method const &method) noexcept 115 { 116 valueOfMethod_ = method; 117 } 118 119 [[nodiscard]] Method GetNameMethod() const noexcept; SetGetNameMethod(Method const & method)120 void SetGetNameMethod(Method const &method) noexcept 121 { 122 getNameMethod_ = method; 123 } 124 125 [[nodiscard]] Method GetValueOfMethod() const noexcept; SetGetValueOfMethod(Method const & method)126 void SetGetValueOfMethod(Method const &method) noexcept 127 { 128 getValueOfMethod_ = method; 129 } 130 131 [[nodiscard]] Method ValuesMethod() const noexcept; SetValuesMethod(Method const & method)132 void SetValuesMethod(Method const &method) noexcept 133 { 134 valuesMethod_ = method; 135 } 136 137 [[nodiscard]] Method FromIntMethod() const noexcept; SetFromIntMethod(Method const & method)138 void SetFromIntMethod(Method const &method) noexcept 139 { 140 fromIntMethod_ = method; 141 } 142 143 [[nodiscard]] Method BoxedFromIntMethod() const noexcept; SetBoxedFromIntMethod(Method const & method)144 void SetBoxedFromIntMethod(Method const &method) noexcept 145 { 146 boxedFromIntMethod_ = method; 147 } 148 149 [[nodiscard]] Method UnboxMethod() const noexcept; SetUnboxMethod(Method const & method)150 void SetUnboxMethod(Method const &method) noexcept 151 { 152 unboxMethod_ = method; 153 } 154 ResolveConditionExpr()155 std::tuple<bool, bool> ResolveConditionExpr() const override 156 { 157 return {false, false}; // NOTE (psiket) It should be true, int value != 0 | string value !empty() 158 } 159 160 private: 161 const ir::TSEnumDeclaration *decl_; 162 const UType ordinal_; 163 const ir::TSEnumMember *member_; 164 165 Method toStringMethod_ {}; 166 Method valueOfMethod_ {}; 167 Method getNameMethod_ {}; 168 Method getValueOfMethod_ {}; 169 Method valuesMethod_ {}; 170 Method fromIntMethod_ {}; 171 Method boxedFromIntMethod_ {}; 172 Method unboxMethod_ {}; 173 174 [[nodiscard]] ir::TSEnumMember *FindMember(const util::StringView &name) const noexcept; 175 176 [[nodiscard]] ETSFunctionType *LookupConstantMethod(ETSChecker *checker, const ir::Identifier *prop) const; 177 178 [[nodiscard]] ETSFunctionType *LookupTypeMethod(ETSChecker *checker, const ir::Identifier *prop) const; 179 180 template <typename T> ToAssemblerTypeImpl(std::stringstream & ss)181 void ToAssemblerTypeImpl(std::stringstream &ss) const noexcept 182 { 183 if constexpr (std::is_same_v<T, int64_t>) { 184 ss << compiler::Signatures::PRIMITIVE_LONG; 185 } else if constexpr (std::is_same_v<T, int32_t>) { 186 ss << compiler::Signatures::PRIMITIVE_INT; 187 } else { 188 static_assert(dependent_false_v<T>, "Invalid underlying type for enumeration."); 189 } 190 } 191 192 template <typename T> ToDebugInfoTypeImpl(std::stringstream & ss)193 void ToDebugInfoTypeImpl(std::stringstream &ss) const noexcept 194 { 195 if constexpr (std::is_same_v<T, int64_t>) { 196 ss << compiler::Signatures::TYPE_DESCRIPTOR_LONG; 197 } else if constexpr (std::is_same_v<T, int32_t>) { 198 ss << compiler::Signatures::TYPE_DESCRIPTOR_INT; 199 } else { 200 static_assert(dependent_false_v<T>, "Invalid underlying type for enumeration."); 201 } 202 } 203 }; 204 205 class ETSIntEnumType : public ETSEnumType, public ETSEnumValueType<std::int32_t> { 206 public: 207 explicit ETSIntEnumType(const ir::TSEnumDeclaration *enumDecl, UType ordinal, 208 const ir::TSEnumMember *member = nullptr) ETSEnumType(enumDecl,ordinal,member,TypeFlag::ETS_INT_ENUM)209 : ETSEnumType(enumDecl, ordinal, member, TypeFlag::ETS_INT_ENUM) 210 { 211 } 212 213 NO_COPY_SEMANTIC(ETSIntEnumType); 214 NO_MOVE_SEMANTIC(ETSIntEnumType); 215 216 ETSIntEnumType() = delete; 217 ~ETSIntEnumType() override = default; 218 }; 219 220 class ETSStringEnumType : public ETSEnumType, public ETSEnumValueType<std::string> { 221 public: 222 explicit ETSStringEnumType(const ir::TSEnumDeclaration *enumDecl, UType ordinal, 223 const ir::TSEnumMember *member = nullptr) ETSEnumType(enumDecl,ordinal,member,TypeFlag::ETS_STRING_ENUM)224 : ETSEnumType(enumDecl, ordinal, member, TypeFlag::ETS_STRING_ENUM) 225 { 226 } 227 228 NO_COPY_SEMANTIC(ETSStringEnumType); 229 NO_MOVE_SEMANTIC(ETSStringEnumType); 230 231 ETSStringEnumType() = delete; 232 ~ETSStringEnumType() override = default; 233 }; 234 } // namespace ark::es2panda::checker 235 236 #endif 237