• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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