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]] Type *BoxedType() const noexcept; 68 69 [[nodiscard]] const ArenaVector<ir::AstNode *> &GetMembers() const noexcept; 70 71 [[nodiscard]] varbinder::LocalVariable *GetMemberVar() const noexcept; 72 73 [[nodiscard]] util::StringView GetName() const noexcept; 74 75 [[nodiscard]] UType GetOrdinal() const noexcept; 76 77 [[nodiscard]] ETSEnumType *LookupConstant(ETSChecker *checker, const ir::Expression *expression, 78 const ir::Identifier *prop) const; 79 80 [[nodiscard]] ETSFunctionType *LookupMethod(ETSChecker *checker, const ir::Expression *expression, 81 const ir::Identifier *prop) const; 82 83 [[nodiscard]] bool IsLiteralType() const noexcept; 84 85 [[nodiscard]] bool IsSameEnumType(const ETSEnumType *const other) const noexcept; 86 87 [[nodiscard]] bool IsSameEnumLiteralType(const ETSEnumType *const other) const noexcept; 88 89 [[nodiscard]] bool IsEnumInstanceExpression(const ir::Expression *expression) const noexcept; 90 91 [[nodiscard]] bool IsEnumLiteralExpression(const ir::Expression *expression) const noexcept; 92 93 [[nodiscard]] bool IsEnumTypeExpression(const ir::Expression *expression) const noexcept; 94 95 static constexpr std::string_view const TO_STRING_METHOD_NAME {"toString"}; 96 static constexpr std::string_view const VALUE_OF_METHOD_NAME {"valueOf"}; 97 static constexpr std::string_view const GET_NAME_METHOD_NAME {"getName"}; 98 static constexpr std::string_view const GET_VALUE_OF_METHOD_NAME {"getValueOf"}; 99 static constexpr std::string_view const VALUES_METHOD_NAME {"values"}; 100 static constexpr std::string_view const FROM_INT_METHOD_NAME {"fromInt"}; 101 static constexpr std::string_view const BOXED_FROM_INT_METHOD_NAME {"boxedfromInt"}; 102 static constexpr std::string_view const UNBOX_METHOD_NAME {"unbox"}; 103 104 struct Method { 105 Signature *globalSignature; 106 ETSFunctionType *memberProxyType; 107 }; 108 109 [[nodiscard]] Method ToStringMethod() const noexcept; SetToStringMethod(Method const & method)110 void SetToStringMethod(Method const &method) noexcept 111 { 112 toStringMethod_ = method; 113 } 114 115 [[nodiscard]] Method ValueOfMethod() const noexcept; SetValueOfMethod(Method const & method)116 void SetValueOfMethod(Method const &method) noexcept 117 { 118 valueOfMethod_ = method; 119 } 120 121 [[nodiscard]] Method GetNameMethod() const noexcept; SetGetNameMethod(Method const & method)122 void SetGetNameMethod(Method const &method) noexcept 123 { 124 getNameMethod_ = method; 125 } 126 127 [[nodiscard]] Method GetValueOfMethod() const noexcept; SetGetValueOfMethod(Method const & method)128 void SetGetValueOfMethod(Method const &method) noexcept 129 { 130 getValueOfMethod_ = method; 131 } 132 133 [[nodiscard]] Method ValuesMethod() const noexcept; SetValuesMethod(Method const & method)134 void SetValuesMethod(Method const &method) noexcept 135 { 136 valuesMethod_ = method; 137 } 138 139 [[nodiscard]] Method FromIntMethod() const noexcept; SetFromIntMethod(Method const & method)140 void SetFromIntMethod(Method const &method) noexcept 141 { 142 fromIntMethod_ = method; 143 } 144 145 [[nodiscard]] Method BoxedFromIntMethod() const noexcept; SetBoxedFromIntMethod(Method const & method)146 void SetBoxedFromIntMethod(Method const &method) noexcept 147 { 148 boxedFromIntMethod_ = method; 149 } 150 151 [[nodiscard]] Method UnboxMethod() const noexcept; SetUnboxMethod(Method const & method)152 void SetUnboxMethod(Method const &method) noexcept 153 { 154 unboxMethod_ = method; 155 } 156 ResolveConditionExpr()157 std::tuple<bool, bool> ResolveConditionExpr() const override 158 { 159 return {false, false}; // NOTE (psiket) It should be true, int value != 0 | string value !empty() 160 } 161 162 private: 163 const ir::TSEnumDeclaration *decl_; 164 const UType ordinal_; 165 const ir::TSEnumMember *member_; 166 167 Method toStringMethod_ {}; 168 Method valueOfMethod_ {}; 169 Method getNameMethod_ {}; 170 Method getValueOfMethod_ {}; 171 Method valuesMethod_ {}; 172 Method fromIntMethod_ {}; 173 Method boxedFromIntMethod_ {}; 174 Method unboxMethod_ {}; 175 176 [[nodiscard]] ir::TSEnumMember *FindMember(const util::StringView &name) const noexcept; 177 178 [[nodiscard]] ETSFunctionType *LookupConstantMethod(ETSChecker *checker, const ir::Identifier *prop) const; 179 180 [[nodiscard]] ETSFunctionType *LookupTypeMethod(ETSChecker *checker, const ir::Identifier *prop) const; 181 182 template <typename T> ToAssemblerTypeImpl(std::stringstream & ss)183 void ToAssemblerTypeImpl(std::stringstream &ss) const noexcept 184 { 185 if constexpr (std::is_same_v<T, int64_t>) { 186 ss << compiler::Signatures::PRIMITIVE_LONG; 187 } else if constexpr (std::is_same_v<T, int32_t>) { 188 ss << compiler::Signatures::PRIMITIVE_INT; 189 } else { 190 static_assert(dependent_false_v<T>, "Invalid underlying type for enumeration."); 191 } 192 } 193 194 template <typename T> ToDebugInfoTypeImpl(std::stringstream & ss)195 void ToDebugInfoTypeImpl(std::stringstream &ss) const noexcept 196 { 197 if constexpr (std::is_same_v<T, int64_t>) { 198 ss << compiler::Signatures::TYPE_DESCRIPTOR_LONG; 199 } else if constexpr (std::is_same_v<T, int32_t>) { 200 ss << compiler::Signatures::TYPE_DESCRIPTOR_INT; 201 } else { 202 static_assert(dependent_false_v<T>, "Invalid underlying type for enumeration."); 203 } 204 } 205 }; 206 207 class ETSIntEnumType : public ETSEnumType, public ETSEnumValueType<std::int32_t> { 208 public: 209 explicit ETSIntEnumType(const ir::TSEnumDeclaration *enumDecl, UType ordinal, 210 const ir::TSEnumMember *member = nullptr) ETSEnumType(enumDecl,ordinal,member,TypeFlag::ETS_INT_ENUM)211 : ETSEnumType(enumDecl, ordinal, member, TypeFlag::ETS_INT_ENUM) 212 { 213 } 214 215 NO_COPY_SEMANTIC(ETSIntEnumType); 216 NO_MOVE_SEMANTIC(ETSIntEnumType); 217 218 ETSIntEnumType() = delete; 219 ~ETSIntEnumType() override = default; 220 }; 221 222 class ETSStringEnumType : public ETSEnumType, public ETSEnumValueType<std::string> { 223 public: 224 explicit ETSStringEnumType(const ir::TSEnumDeclaration *enumDecl, UType ordinal, 225 const ir::TSEnumMember *member = nullptr) ETSEnumType(enumDecl,ordinal,member,TypeFlag::ETS_STRING_ENUM)226 : ETSEnumType(enumDecl, ordinal, member, TypeFlag::ETS_STRING_ENUM) 227 { 228 } 229 230 NO_COPY_SEMANTIC(ETSStringEnumType); 231 NO_MOVE_SEMANTIC(ETSStringEnumType); 232 233 ETSStringEnumType() = delete; 234 ~ETSStringEnumType() override = default; 235 }; 236 } // namespace ark::es2panda::checker 237 238 #endif 239