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