• 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_TYPE_H
17 #define ES2PANDA_COMPILER_CHECKER_TYPES_TYPE_H
18 
19 #include "generated/signatures.h"
20 #include "checker/types/typeMapping.h"
21 #include "checker/types/typeRelation.h"
22 #include "checker/types/typeFacts.h"
23 
24 namespace ark::es2panda::varbinder {
25 class Variable;
26 }  // namespace ark::es2panda::varbinder
27 
28 namespace ark::es2panda::checker {
29 class ObjectDescriptor;
30 class GlobalTypesHolder;
31 class ETSDynamicType;
32 class ETSAsyncFuncReturnType;
33 class ETSChecker;
34 class ETSDynamicFunctionType;
35 class ETSTypeParameter;
36 class ETSEnumType;
37 
38 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
39 #define DECLARE_TYPENAMES(typeFlag, typeName) class typeName;
40 TYPE_MAPPING(DECLARE_TYPENAMES)
41 #undef DECLARE_TYPENAMES
42 class ETSStringType;
43 class ETSBigIntType;
44 
45 using Substitution = ArenaMap<ETSTypeParameter *, Type *>;
46 
47 class Type {
48 public:
Type(TypeFlag flag)49     explicit Type(TypeFlag flag) : typeFlags_(flag)
50     {
51         static uint64_t typeId = 0;
52         id_ = ++typeId;
53     }
54 
55     NO_COPY_SEMANTIC(Type);
56     NO_MOVE_SEMANTIC(Type);
57 
58     virtual ~Type() = default;
59 
60 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
61 #define TYPE_IS_CHECKS(typeFlag, typeName) \
62     bool Is##typeName() const              \
63     {                                      \
64         return HasTypeFlag(typeFlag);      \
65     }
66     TYPE_MAPPING(TYPE_IS_CHECKS)
67 #undef DECLARE_IS_CHECKS
68 
69 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
70 #define TYPE_AS_CASTS(typeFlag, typeName)                \
71     typeName *As##typeName()                             \
72     {                                                    \
73         ASSERT(Is##typeName());                          \
74         return reinterpret_cast<typeName *>(this);       \
75     }                                                    \
76     const typeName *As##typeName() const                 \
77     {                                                    \
78         ASSERT(Is##typeName());                          \
79         return reinterpret_cast<const typeName *>(this); \
80     }
81     TYPE_MAPPING(TYPE_AS_CASTS)
82 #undef TYPE_AS_CASTS
83 
84     bool IsETSStringType() const;
85     bool IsETSBigIntType() const;
86     bool IsETSReferenceType() const;
87     bool IsETSAsyncFuncReturnType() const;
88     bool IsETSUnboxableObject() const;
89 
90     bool PossiblyETSNull() const;
91     bool PossiblyETSUndefined() const;
92     bool PossiblyETSNullish() const;
93     bool DefinitelyETSNullish() const;
94     bool DefinitelyNotETSNullish() const;
95 
96     bool PossiblyETSString() const;
97     bool PossiblyETSValueTyped() const;
98     bool PossiblyETSValueTypedExceptNullish() const;
99 
AsETSStringType()100     ETSStringType *AsETSStringType()
101     {
102         ASSERT(IsETSObjectType());
103         return reinterpret_cast<ETSStringType *>(this);
104     }
105 
AsETSStringType()106     const ETSStringType *AsETSStringType() const
107     {
108         ASSERT(IsETSObjectType());
109         return reinterpret_cast<const ETSStringType *>(this);
110     }
111 
AsETSBigIntType()112     const ETSBigIntType *AsETSBigIntType() const
113     {
114         ASSERT(IsETSObjectType());
115         return reinterpret_cast<const ETSBigIntType *>(this);
116     }
117 
IsETSDynamicType()118     bool IsETSDynamicType() const
119     {
120         return IsETSObjectType() && HasTypeFlag(TypeFlag::ETS_DYNAMIC_FLAG);
121     }
122 
AsETSDynamicType()123     ETSDynamicType *AsETSDynamicType()
124     {
125         ASSERT(IsETSDynamicType());
126         return reinterpret_cast<ETSDynamicType *>(this);
127     }
128 
AsETSDynamicType()129     const ETSDynamicType *AsETSDynamicType() const
130     {
131         ASSERT(IsETSDynamicType());
132         return reinterpret_cast<const ETSDynamicType *>(this);
133     }
134 
AsETSAsyncFuncReturnType()135     ETSAsyncFuncReturnType *AsETSAsyncFuncReturnType()
136     {
137         ASSERT(IsETSAsyncFuncReturnType());
138         return reinterpret_cast<ETSAsyncFuncReturnType *>(this);
139     }
140 
AsETSAsyncFuncReturnType()141     const ETSAsyncFuncReturnType *AsETSAsyncFuncReturnType() const
142     {
143         ASSERT(IsETSAsyncFuncReturnType());
144         return reinterpret_cast<const ETSAsyncFuncReturnType *>(this);
145     }
146 
IsETSDynamicFunctionType()147     bool IsETSDynamicFunctionType() const
148     {
149         return TypeFlags() == TypeFlag::ETS_DYNAMIC_FUNCTION_TYPE;
150     }
151 
AsETSDynamicFunctionType()152     ETSDynamicFunctionType *AsETSDynamicFunctionType()
153     {
154         ASSERT(IsETSDynamicFunctionType());
155         return reinterpret_cast<ETSDynamicFunctionType *>(this);
156     }
157 
AsETSDynamicFunctionType()158     const ETSDynamicFunctionType *AsETSDynamicFunctionType() const
159     {
160         ASSERT(IsETSDynamicFunctionType());
161         return reinterpret_cast<const ETSDynamicFunctionType *>(this);
162     }
163 
IsConditionalExprType()164     bool IsConditionalExprType() const
165     {
166         return HasTypeFlag(TypeFlag::CONDITION_EXPRESSION_TYPE);
167     }
168 
IsConstantType()169     bool IsConstantType() const
170     {
171         return HasTypeFlag(checker::TypeFlag::CONSTANT);
172     }
173 
TypeFlags()174     TypeFlag TypeFlags() const
175     {
176         return typeFlags_;
177     }
178 
HasTypeFlag(TypeFlag typeFlag)179     bool HasTypeFlag(TypeFlag typeFlag) const
180     {
181         return (typeFlags_ & typeFlag) != 0;
182     }
183 
AddTypeFlag(TypeFlag typeFlag)184     void AddTypeFlag(TypeFlag typeFlag)
185     {
186         typeFlags_ |= typeFlag;
187     }
188 
RemoveTypeFlag(TypeFlag typeFlag)189     void RemoveTypeFlag(TypeFlag typeFlag)
190     {
191         typeFlags_ &= ~typeFlag;
192     }
193 
Id()194     uint64_t Id() const
195     {
196         return id_;
197     }
198 
SetVariable(varbinder::Variable * variable)199     void SetVariable(varbinder::Variable *variable)
200     {
201         variable_ = variable;
202     }
203 
Variable()204     varbinder::Variable *Variable()
205     {
206         return variable_;
207     }
208 
Variable()209     const varbinder::Variable *Variable() const
210     {
211         return variable_;
212     }
213 
ToAssemblerTypeView(ArenaAllocator * allocator)214     util::StringView ToAssemblerTypeView(ArenaAllocator *allocator) const
215     {
216         std::stringstream ss;
217         ToAssemblerType(ss);
218         return util::UString(ss.str(), allocator).View();
219     }
220 
ToAssemblerName()221     std::stringstream ToAssemblerName() const
222     {
223         std::stringstream ss;
224         ToAssemblerType(ss);
225         return ss;
226     }
227 
228     bool IsLambdaObject() const;
229     virtual void ToString(std::stringstream &ss, bool precise) const = 0;
230     void ToString(std::stringstream &ss) const;
231     [[nodiscard]] std::string ToString() const;
232     [[nodiscard]] std::string ToStringPrecise() const;
233 
234     virtual void ToStringAsSrc(std::stringstream &ss) const;
235     std::string ToStringAsSrc() const;
236 
237     virtual TypeFacts GetTypeFacts() const;
ToAssemblerType(std::stringstream & ss)238     virtual void ToAssemblerType([[maybe_unused]] std::stringstream &ss) const {};
ToDebugInfoType(std::stringstream & ss)239     virtual void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const {};
ToAssemblerTypeWithRank(std::stringstream & ss)240     virtual void ToAssemblerTypeWithRank([[maybe_unused]] std::stringstream &ss) const
241     {
242         ToAssemblerType(ss);
243     }
244 
Rank()245     virtual uint32_t Rank() const
246     {
247         return 0;
248     }
249 
ResolveConditionExpr()250     virtual std::tuple<bool, bool> ResolveConditionExpr() const
251     {
252         UNREACHABLE();
253     };
254 
255     virtual void Identical(TypeRelation *relation, Type *other);
256     virtual void AssignmentTarget(TypeRelation *relation, Type *source) = 0;
257     virtual bool AssignmentSource(TypeRelation *relation, Type *target);
258     virtual void Compare(TypeRelation *relation, Type *other);
259     virtual void Cast(TypeRelation *relation, Type *target);
260     virtual void CastTarget(TypeRelation *relation, Type *source);
261     virtual void IsSupertypeOf(TypeRelation *relation, Type *source);
262     virtual void IsSubtypeOf(TypeRelation *relation, Type *target);
263     virtual Type *AsSuper(Checker *checker, varbinder::Variable *sourceVar);
264 
265     [[nodiscard]] static std::uint32_t GetPrecedence(Type const *type) noexcept;
266 
267     virtual Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes);
268     [[nodiscard]] virtual Type *Clone(Checker *checker);
269     virtual Type *Substitute(TypeRelation *relation, const Substitution *substitution);
270 
AsETSEnumType()271     const ETSEnumType *AsETSEnumType() const
272     {
273         ASSERT(IsETSEnumType());
274         return reinterpret_cast<const ETSEnumType *>(this);
275     }
276 
AsETSEnumType()277     ETSEnumType *AsETSEnumType()
278     {
279         ASSERT(IsETSEnumType());
280         return reinterpret_cast<ETSEnumType *>(this);
281     }
282 
IsETSEnumType()283     bool IsETSEnumType() const
284     {
285         return IsETSIntEnumType() || IsETSStringEnumType();
286     }
287 
288 protected:
289     // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
290     TypeFlag typeFlags_;
291     varbinder::Variable *variable_ {};  // Variable associated with the type if any
292     uint64_t id_;
293     // NOLINTEND(misc-non-private-member-variables-in-classes)
294 };
295 
296 // NOLINTBEGIN(readability-redundant-declaration)
297 // To avoid including type.h from variable.h, astNode.h
298 bool IsTypeError(Type const *tp);
299 // Use this in order to avoid crashes where TypeError is not expected
300 [[noreturn]] void ThrowEmptyError();
301 // NOLINTEND(readability-redundant-declaration)
302 
303 }  // namespace ark::es2panda::checker
304 
305 #endif /* TYPESCRIPT_TYPES_TYPE_H */
306