• 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 #include "macros.h"
25 #include <sstream>
26 #include <variant>
27 
28 namespace panda::es2panda::varbinder {
29 class Variable;
30 }  // namespace panda::es2panda::varbinder
31 
32 namespace panda::es2panda::checker {
33 class ObjectDescriptor;
34 class GlobalTypesHolder;
35 class ETSDynamicType;
36 class ETSAsyncFuncReturnType;
37 class ETSChecker;
38 class ETSDynamicFunctionType;
39 class ETSTypeParameter;
40 
41 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
42 #define DECLARE_TYPENAMES(typeFlag, typeName) class typeName;
43 TYPE_MAPPING(DECLARE_TYPENAMES)
44 #undef DECLARE_TYPENAMES
45 class ETSStringType;
46 class ETSBigIntType;
47 
48 using Substitution = ArenaMap<ETSTypeParameter *, Type *>;
49 
50 class Type {
51 public:
Type(TypeFlag flag)52     explicit Type(TypeFlag flag) : typeFlags_(flag)
53     {
54         static uint64_t typeId = 0;
55         id_ = ++typeId;
56     }
57 
58     NO_COPY_SEMANTIC(Type);
59     NO_MOVE_SEMANTIC(Type);
60 
61     virtual ~Type() = default;
62 
63 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
64 #define TYPE_IS_CHECKS(typeFlag, typeName) \
65     bool Is##typeName() const              \
66     {                                      \
67         return HasTypeFlag(typeFlag);      \
68     }
69     TYPE_MAPPING(TYPE_IS_CHECKS)
70 #undef DECLARE_IS_CHECKS
71 
72 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
73 #define TYPE_AS_CASTS(typeFlag, 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     TYPE_MAPPING(TYPE_AS_CASTS)
85 #undef TYPE_AS_CASTS
86 
87     bool IsETSStringType() const;
88     bool IsETSBigIntType() const;
89     bool IsETSNullType() const;
90     bool IsETSUndefinedType() const;
91     bool IsETSNullLike() const;
92     bool IsETSAsyncFuncReturnType() const;
93     bool IsNullish() const;
94     bool IsNullishOrNullLike() const;
95     bool ContainsNull() const;
96     bool ContainsUndefined() const;
97 
AsETSStringType()98     ETSStringType *AsETSStringType()
99     {
100         ASSERT(IsETSObjectType());
101         return reinterpret_cast<ETSStringType *>(this);
102     }
103 
AsETSStringType()104     const ETSStringType *AsETSStringType() const
105     {
106         ASSERT(IsETSObjectType());
107         return reinterpret_cast<const ETSStringType *>(this);
108     }
109 
AsETSBigIntType()110     const ETSBigIntType *AsETSBigIntType() const
111     {
112         ASSERT(IsETSObjectType());
113         return reinterpret_cast<const ETSBigIntType *>(this);
114     }
115 
IsETSDynamicType()116     bool IsETSDynamicType() const
117     {
118         return IsETSObjectType() && HasTypeFlag(TypeFlag::ETS_DYNAMIC_FLAG);
119     }
120 
AsETSDynamicType()121     ETSDynamicType *AsETSDynamicType()
122     {
123         ASSERT(IsETSDynamicType());
124         return reinterpret_cast<ETSDynamicType *>(this);
125     }
126 
AsETSDynamicType()127     const ETSDynamicType *AsETSDynamicType() const
128     {
129         ASSERT(IsETSDynamicType());
130         return reinterpret_cast<const ETSDynamicType *>(this);
131     }
132 
AsETSAsyncFuncReturnType()133     ETSAsyncFuncReturnType *AsETSAsyncFuncReturnType()
134     {
135         ASSERT(IsETSAsyncFuncReturnType());
136         return reinterpret_cast<ETSAsyncFuncReturnType *>(this);
137     }
138 
AsETSAsyncFuncReturnType()139     const ETSAsyncFuncReturnType *AsETSAsyncFuncReturnType() const
140     {
141         ASSERT(IsETSAsyncFuncReturnType());
142         return reinterpret_cast<const ETSAsyncFuncReturnType *>(this);
143     }
144 
IsETSDynamicFunctionType()145     bool IsETSDynamicFunctionType() const
146     {
147         return TypeFlags() == TypeFlag::ETS_DYNAMIC_FUNCTION_TYPE;
148     }
149 
AsETSDynamicFunctionType()150     ETSDynamicFunctionType *AsETSDynamicFunctionType()
151     {
152         ASSERT(IsETSDynamicFunctionType());
153         return reinterpret_cast<ETSDynamicFunctionType *>(this);
154     }
155 
AsETSDynamicFunctionType()156     const ETSDynamicFunctionType *AsETSDynamicFunctionType() const
157     {
158         ASSERT(IsETSDynamicFunctionType());
159         return reinterpret_cast<const ETSDynamicFunctionType *>(this);
160     }
161 
IsConditionalExprType()162     bool IsConditionalExprType() const
163     {
164         return HasTypeFlag(TypeFlag::CONDITION_EXPRESSION_TYPE);
165     }
166 
IsConstantType()167     bool IsConstantType() const
168     {
169         return HasTypeFlag(checker::TypeFlag::CONSTANT);
170     }
171 
TypeFlags()172     TypeFlag TypeFlags() const
173     {
174         return typeFlags_;
175     }
176 
HasTypeFlag(TypeFlag typeFlag)177     bool HasTypeFlag(TypeFlag typeFlag) const
178     {
179         return (typeFlags_ & typeFlag) != 0;
180     }
181 
AddTypeFlag(TypeFlag typeFlag)182     void AddTypeFlag(TypeFlag typeFlag)
183     {
184         typeFlags_ |= typeFlag;
185     }
186 
RemoveTypeFlag(TypeFlag typeFlag)187     void RemoveTypeFlag(TypeFlag typeFlag)
188     {
189         typeFlags_ &= ~typeFlag;
190     }
191 
Id()192     uint64_t Id() const
193     {
194         return id_;
195     }
196 
SetVariable(varbinder::Variable * variable)197     void SetVariable(varbinder::Variable *variable)
198     {
199         variable_ = variable;
200     }
201 
Variable()202     varbinder::Variable *Variable()
203     {
204         return variable_;
205     }
206 
Variable()207     const varbinder::Variable *Variable() const
208     {
209         return variable_;
210     }
211 
ToAssemblerTypeView(ArenaAllocator * allocator)212     util::StringView ToAssemblerTypeView(ArenaAllocator *allocator) const
213     {
214         std::stringstream ss;
215         ToAssemblerType(ss);
216         return util::UString(ss.str(), allocator).View();
217     }
218 
ToAssemblerName()219     std::stringstream ToAssemblerName() const
220     {
221         std::stringstream ss;
222         ToAssemblerType(ss);
223         return ss;
224     }
225 
226     bool IsLambdaObject() const;
227     virtual void ToString(std::stringstream &ss) const = 0;
228     virtual void ToStringAsSrc(std::stringstream &ss) const;
229     virtual TypeFacts GetTypeFacts() const;
ToAssemblerType(std::stringstream & ss)230     virtual void ToAssemblerType([[maybe_unused]] std::stringstream &ss) const {};
ToDebugInfoType(std::stringstream & ss)231     virtual void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const {};
ToAssemblerTypeWithRank(std::stringstream & ss)232     virtual void ToAssemblerTypeWithRank([[maybe_unused]] std::stringstream &ss) const
233     {
234         ToAssemblerType(ss);
235     };
236 
Rank()237     virtual uint32_t Rank() const
238     {
239         return 0;
240     }
241 
ResolveConditionExpr()242     virtual std::tuple<bool, bool> ResolveConditionExpr() const
243     {
244         UNREACHABLE();
245     };
246 
247     virtual void Identical(TypeRelation *relation, Type *other);
248     virtual void AssignmentTarget(TypeRelation *relation, Type *source) = 0;
249     virtual bool AssignmentSource(TypeRelation *relation, Type *target);
250     virtual void Compare(TypeRelation *relation, Type *other);
251     virtual void Cast(TypeRelation *relation, Type *target);
252     virtual void CastTarget(TypeRelation *relation, Type *source);
253     virtual void IsSupertypeOf(TypeRelation *relation, Type *source);
254     virtual void IsSubtypeOf(TypeRelation *relation, Type *target);
255     virtual Type *AsSuper(Checker *checker, varbinder::Variable *sourceVar);
256 
257     virtual Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes);
258     virtual Type *Substitute(TypeRelation *relation, const Substitution *substitution);
259 
260 protected:
261     // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
262     TypeFlag typeFlags_;
263     varbinder::Variable *variable_ {};  // Variable associated with the type if any
264     uint64_t id_;
265     // NOLINTEND(misc-non-private-member-variables-in-classes)
266 };
267 }  // namespace panda::es2panda::checker
268 
269 #endif /* TYPESCRIPT_TYPES_TYPE_H */
270