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