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