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