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