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