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