• 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]] 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