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