1 /* 2 * Copyright (c) 2021 - 2023 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 panda::es2panda::varbinder { 28 class LocalVariable; 29 } // namespace panda::es2panda::varbinder 30 31 namespace panda::es2panda::checker { 32 template <typename T> 33 struct ETSEnumValueType { 34 using ValueType = T; 35 }; 36 37 class ETSEnumInterface : public Type { 38 public: 39 using UType = std::int32_t; 40 41 explicit ETSEnumInterface(const ir::TSEnumDeclaration *enumDecl, UType ordinal, const ir::TSEnumMember *member, 42 TypeFlag typeFlag); 43 44 NO_COPY_SEMANTIC(ETSEnumInterface); 45 NO_MOVE_SEMANTIC(ETSEnumInterface); 46 47 ETSEnumInterface() = delete; 48 ~ETSEnumInterface() 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) 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]] ETSEnumInterface *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 ETSEnumInterface *other) const noexcept; 84 85 [[nodiscard]] bool IsSameEnumLiteralType(const ETSEnumInterface *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 GET_VALUE_METHOD_NAME {"getValue"}; 95 static constexpr std::string_view const GET_NAME_METHOD_NAME {"getName"}; 96 static constexpr std::string_view const VALUE_OF_METHOD_NAME {"valueOf"}; 97 static constexpr std::string_view const VALUES_METHOD_NAME {"values"}; 98 static constexpr std::string_view const FROM_INT_METHOD_NAME {"fromInt"}; 99 100 struct Method { 101 Signature *globalSignature; 102 ETSFunctionType *memberProxyType; 103 }; 104 105 [[nodiscard]] Method ToStringMethod() const noexcept; SetToStringMethod(Method const & method)106 void SetToStringMethod(Method const &method) noexcept 107 { 108 toStringMethod_ = method; 109 } 110 111 [[nodiscard]] Method GetValueMethod() const noexcept; SetGetValueMethod(Method const & method)112 void SetGetValueMethod(Method const &method) noexcept 113 { 114 getValueMethod_ = method; 115 } 116 117 [[nodiscard]] Method GetNameMethod() const noexcept; SetGetNameMethod(Method const & method)118 void SetGetNameMethod(Method const &method) noexcept 119 { 120 getNameMethod_ = method; 121 } 122 123 [[nodiscard]] Method ValueOfMethod() const noexcept; SetValueOfMethod(Method const & method)124 void SetValueOfMethod(Method const &method) noexcept 125 { 126 valueOfMethod_ = method; 127 } 128 129 [[nodiscard]] Method ValuesMethod() const noexcept; SetValuesMethod(Method const & method)130 void SetValuesMethod(Method const &method) noexcept 131 { 132 valuesMethod_ = method; 133 } 134 135 [[nodiscard]] Method FromIntMethod() const noexcept; SetFromIntMethod(Method const & method)136 void SetFromIntMethod(Method const &method) noexcept 137 { 138 fromIntMethod_ = method; 139 } 140 ResolveConditionExpr()141 std::tuple<bool, bool> ResolveConditionExpr() const override 142 { 143 return {true, !GetMembers().empty()}; 144 } 145 146 private: 147 const ir::TSEnumDeclaration *decl_; 148 const UType ordinal_; 149 const ir::TSEnumMember *member_; 150 151 Method toStringMethod_ {}; 152 Method getValueMethod_ {}; 153 Method getNameMethod_ {}; 154 Method valueOfMethod_ {}; 155 Method valuesMethod_ {}; 156 Method fromIntMethod_ {}; 157 158 [[nodiscard]] ir::TSEnumMember *FindMember(const util::StringView &name) const noexcept; 159 160 [[nodiscard]] ETSFunctionType *LookupConstantMethod(ETSChecker *checker, const ir::Identifier *prop) const; 161 162 [[nodiscard]] ETSFunctionType *LookupTypeMethod(ETSChecker *checker, const ir::Identifier *prop) const; 163 164 template <typename T> ToAssemblerTypeImpl(std::stringstream & ss)165 void ToAssemblerTypeImpl(std::stringstream &ss) const noexcept 166 { 167 if constexpr (std::is_same_v<T, int64_t>) { 168 ss << compiler::Signatures::PRIMITIVE_LONG; 169 } else if constexpr (std::is_same_v<T, int32_t>) { 170 ss << compiler::Signatures::PRIMITIVE_INT; 171 } else { 172 static_assert(dependent_false_v<T>, "Invalid underlying type for enumeration."); 173 } 174 } 175 176 template <typename T> ToDebugInfoTypeImpl(std::stringstream & ss)177 void ToDebugInfoTypeImpl(std::stringstream &ss) const noexcept 178 { 179 if constexpr (std::is_same_v<T, int64_t>) { 180 ss << compiler::Signatures::TYPE_DESCRIPTOR_LONG; 181 } else if constexpr (std::is_same_v<T, int32_t>) { 182 ss << compiler::Signatures::TYPE_DESCRIPTOR_INT; 183 } else { 184 static_assert(dependent_false_v<T>, "Invalid underlying type for enumeration."); 185 } 186 } 187 }; 188 189 class ETSEnumType : public ETSEnumInterface, public ETSEnumValueType<std::int32_t> { 190 public: 191 explicit ETSEnumType(const ir::TSEnumDeclaration *enumDecl, UType ordinal, const ir::TSEnumMember *member = nullptr) ETSEnumInterface(enumDecl,ordinal,member,TypeFlag::ETS_ENUM)192 : ETSEnumInterface(enumDecl, ordinal, member, TypeFlag::ETS_ENUM) 193 { 194 } 195 196 NO_COPY_SEMANTIC(ETSEnumType); 197 NO_MOVE_SEMANTIC(ETSEnumType); 198 199 ETSEnumType() = delete; 200 ~ETSEnumType() override = default; 201 }; 202 203 class ETSStringEnumType : public ETSEnumInterface, public ETSEnumValueType<std::string> { 204 public: 205 explicit ETSStringEnumType(const ir::TSEnumDeclaration *enumDecl, UType ordinal, 206 const ir::TSEnumMember *member = nullptr) ETSEnumInterface(enumDecl,ordinal,member,TypeFlag::ETS_STRING_ENUM)207 : ETSEnumInterface(enumDecl, ordinal, member, TypeFlag::ETS_STRING_ENUM) 208 { 209 } 210 211 NO_COPY_SEMANTIC(ETSStringEnumType); 212 NO_MOVE_SEMANTIC(ETSStringEnumType); 213 214 ETSStringEnumType() = delete; 215 ~ETSStringEnumType() override = default; 216 }; 217 } // namespace panda::es2panda::checker 218 219 #endif 220