1 /**
2 * Copyright (c) 2021-2025 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_TS_OBJECT_TYPE_H
17 #define ES2PANDA_COMPILER_CHECKER_TYPES_TS_OBJECT_TYPE_H
18
19 #include "checker/types/type.h"
20
21 #include "checker/types/ts/objectDescriptor.h"
22 #include "varbinder/variable.h"
23 #include "util/ustring.h"
24 #include "util/enumbitops.h"
25
26 namespace ark::es2panda::checker {
27 class Signature;
28 class IndexInfo;
29
30 // CC-OFFNXT(G.PRE.02) name part
31 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
32 #define DECLARE_OBJECT_TYPENAMES(objectKind, typeName) class typeName; // CC-OFF(G.PRE.09) code gen
OBJECT_TYPE_MAPPING(DECLARE_OBJECT_TYPENAMES)33 OBJECT_TYPE_MAPPING(DECLARE_OBJECT_TYPENAMES)
34 #undef DECLARE_OBJECT_TYPENAMES
35
36 using ENUMBITOPS_OPERATORS;
37
38 enum class ObjectFlags : uint32_t {
39 NO_OPTS = 0U,
40 CHECK_EXCESS_PROPS = 1U << 0U,
41 RESOLVED_MEMBERS = 1U << 1U,
42 RESOLVED_BASE_TYPES = 1U << 2U,
43 RESOLVED_DECLARED_MEMBERS = 1U << 3U,
44 };
45
46 } // namespace ark::es2panda::checker
47
48 template <>
49 struct enumbitops::IsAllowedType<ark::es2panda::checker::ObjectFlags> : std::true_type {
50 };
51
52 namespace ark::es2panda::checker {
53
54 class ObjectType : public Type {
55 public:
56 enum class ObjectTypeKind {
57 LITERAL,
58 CLASS,
59 INTERFACE,
60 TUPLE,
61 FUNCTION,
62 };
63
64 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
65 #define OBJECT_TYPE_IS_CHECKS(object_kind, type_name) \
66 bool Is##type_name() const \
67 { \
68 /* CC-OFFNXT(G.PRE.02,G.PRE.09,G.PRE.05) name part*/ \
69 return kind_ == (object_kind); \
70 }
71 OBJECT_TYPE_MAPPING(OBJECT_TYPE_IS_CHECKS)
72 #undef OBJECT_TYPE_IS_CHECKS
73
74 // CC-OFFNXT(G.PRE.06) solid logic
75 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
76 #define OBJECT_TYPE_AS_CASTS(objectKind, typeName) \
77 /* CC-OFFNXT(G.PRE.02,G.PRE.09) name part*/ \
78 typeName *As##typeName() \
79 { \
80 ES2PANDA_ASSERT(Is##typeName()); \
81 /* CC-OFFNXT(G.PRE.05,G.PRE.02) The macro is used to generate a function. */ \
82 return reinterpret_cast<typeName *>(this); \
83 } \
84 const typeName *As##typeName() const \
85 { \
86 ES2PANDA_ASSERT(Is##typeName()); \
87 /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed*/ \
88 return reinterpret_cast<const typeName *>(this); \
89 }
90 OBJECT_TYPE_MAPPING(OBJECT_TYPE_AS_CASTS)
91 #undef OBJECT_TYPE_AS_CASTS
92
93 explicit ObjectType(ObjectType::ObjectTypeKind kind)
94 : Type(TypeFlag::OBJECT), kind_(kind), objFlag_(ObjectFlags::NO_OPTS)
95 {
96 }
97
98 ObjectType(ObjectType::ObjectTypeKind kind, ObjectDescriptor *desc)
99 : Type(TypeFlag::OBJECT), kind_(kind), desc_(desc), objFlag_(ObjectFlags::NO_OPTS)
100 {
101 }
102
103 ObjectType::ObjectTypeKind Kind() const
104 {
105 return kind_;
106 }
107
108 virtual ArenaVector<Signature *> CallSignatures()
109 {
110 return desc_->callSignatures;
111 }
112
113 virtual ArenaVector<Signature *> ConstructSignatures()
114 {
115 return desc_->constructSignatures;
116 }
117
118 virtual const IndexInfo *StringIndexInfo() const
119 {
120 return desc_->stringIndexInfo;
121 }
122
123 virtual const IndexInfo *NumberIndexInfo() const
124 {
125 return desc_->numberIndexInfo;
126 }
127
128 virtual IndexInfo *StringIndexInfo()
129 {
130 return desc_->stringIndexInfo;
131 }
132
133 virtual IndexInfo *NumberIndexInfo()
134 {
135 return desc_->numberIndexInfo;
136 }
137
138 virtual ArenaVector<varbinder::LocalVariable *> Properties()
139 {
140 return desc_->properties;
141 }
142
143 ObjectDescriptor *Desc()
144 {
145 return desc_;
146 }
147
148 const ObjectDescriptor *Desc() const
149 {
150 return desc_;
151 }
152
153 void AddProperty(varbinder::LocalVariable *prop)
154 {
155 desc_->properties.push_back(prop);
156 }
157
158 virtual varbinder::LocalVariable *GetProperty(const util::StringView &name,
159 [[maybe_unused]] bool searchInBase) const
160 {
161 for (auto *it : desc_->properties) {
162 if (name == it->Name()) {
163 return it;
164 }
165 }
166
167 return nullptr;
168 }
169
170 void AddCallSignature(Signature *signature)
171 {
172 desc_->callSignatures.push_back(signature);
173 }
174
175 void AddConstructSignature(Signature *signature)
176 {
177 desc_->constructSignatures.push_back(signature);
178 }
179
180 void AddObjectFlag(ObjectFlags flag)
181 {
182 objFlag_ |= flag;
183 }
184
185 void RemoveObjectFlag(ObjectFlags flag)
186 {
187 flag &= ~flag;
188 }
189
190 bool HasObjectFlag(ObjectFlags flag) const
191 {
192 return (objFlag_ & flag) != 0;
193 }
194
195 static bool SignatureRelatedToSomeSignature(TypeRelation *relation, Signature *sourceSignature,
196 ArenaVector<Signature *> *targetSignatures);
197
198 static bool EachSignatureRelatedToSomeSignature(TypeRelation *relation,
199 const ArenaVector<Signature *> &sourceSignatures,
200 const ArenaVector<Signature *> &targetSignatures);
201
202 bool FindPropertyAndCheckIdentical(TypeRelation *relation, ObjectType *otherObj);
203 bool IdenticalPropertiesHelper(TypeRelation *relation, ObjectType *otherObj);
204 void Identical(TypeRelation *relation, Type *other) override;
205 void AssignmentTarget(TypeRelation *relation, Type *source) override;
206
207 void CheckExcessProperties(TypeRelation *relation, ObjectType *source);
208 void AssignProperties(TypeRelation *relation, ObjectType *source);
209 void AssignSignatures(TypeRelation *relation, ObjectType *source, bool assignCallSignatures = true);
210 void AssignIndexInfo(TypeRelation *relation, ObjectType *source, bool assignNumberInfo = true);
211
212 protected:
213 // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
214 ObjectTypeKind kind_;
215 ObjectDescriptor *desc_ {};
216 ObjectFlags objFlag_ {};
217 // NOLINTEND(misc-non-private-member-variables-in-classes)
218 };
219 } // namespace ark::es2panda::checker
220
221 #endif /* TYPESCRIPT_TYPES_OBJECT_TYPE_H */
222