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_CHECKER_TS_CHECKER_H 17 #define ES2PANDA_CHECKER_TS_CHECKER_H 18 19 #include "checker/checker.h" 20 #include "varbinder/enumMemberResult.h" 21 #include "checker/types/globalTypesHolder.h" 22 #include "checker/types/ts/types.h" 23 #include "util/enumbitops.h" 24 #include "util/ustring.h" 25 #include "macros.h" 26 27 #include <cstdint> 28 #include <initializer_list> 29 #include <unordered_map> 30 #include <unordered_set> 31 32 namespace ark::es2panda::varbinder { 33 class VarBinder; 34 class Decl; 35 class EnumVariable; 36 class FunctionDecl; 37 class LocalVariable; 38 class Scope; 39 class Variable; 40 } // namespace ark::es2panda::varbinder 41 42 namespace ark::es2panda::ir { 43 class AstNode; 44 class SpreadElement; 45 class AssignmentExpression; 46 class Property; 47 class Expression; 48 class ScriptFunction; 49 class UnaryExpression; 50 class BinaryExpression; 51 class Identifier; 52 class MemberExpression; 53 class TSEnumDeclaration; 54 class TSInterfaceDeclaration; 55 class ObjectExpression; 56 class TSArrayType; 57 class TSUnionType; 58 class TSFunctionType; 59 class TSConstructorType; 60 class TSTypeLiteral; 61 class TSTypeReference; 62 class TSQualifiedName; 63 class TSIndexedAccessType; 64 class TSInterfaceHeritage; 65 class TSTypeQuery; 66 class TSTupleType; 67 class ArrayExpression; 68 class Statement; 69 class TSTypeParameterDeclaration; 70 class TSTypeParameterInstantiation; 71 class BlockStatement; 72 class VariableDeclaration; 73 class IfStatement; 74 class DoWhileStatement; 75 class WhileStatement; 76 class ForUpdateStatement; 77 class ForInStatement; 78 class ForOfStatement; 79 class ReturnStatement; 80 class SwitchStatement; 81 class LabelledStatement; 82 class ThrowStatement; 83 class TryStatement; 84 class TSTypeAliasDeclaration; 85 class TSAsExpression; 86 class ThisExpression; 87 class TypeofExpression; 88 class NewExpression; 89 class FunctionExpression; 90 class AwaitExpression; 91 class UpdateExpression; 92 class ConditionalExpression; 93 class YieldExpression; 94 class ArrowFunctionExpression; 95 class TemplateLiteral; 96 class TaggedTemplateExpression; 97 class TSIndexSignature; 98 class TSSignatureDeclaration; 99 class TSPropertySignature; 100 class TSMethodSignature; 101 class ChainExpression; 102 class VariableDeclarator; 103 104 enum class AstNodeType; 105 } // namespace ark::es2panda::ir 106 107 namespace ark::es2panda::checker { 108 109 struct ExpressionTypeInfo { 110 Type *leftType; 111 Type *rightType; 112 }; 113 114 struct TupleTypeInfo { 115 ElementFlags combinedFlags; 116 uint32_t minLength; 117 uint32_t fixedLength; 118 bool readonly; 119 }; 120 121 class TSChecker : public Checker { 122 public: 123 // NOLINTNEXTLINE(readability-redundant-member-init) TSChecker()124 explicit TSChecker() : Checker() {} 125 GlobalNumberType()126 Type *GlobalNumberType() 127 { 128 return GetGlobalTypesHolder()->GlobalNumberType(); 129 } 130 GlobalAnyType()131 Type *GlobalAnyType() 132 { 133 return GetGlobalTypesHolder()->GlobalAnyType(); 134 } 135 GlobalStringType()136 Type *GlobalStringType() 137 { 138 return GetGlobalTypesHolder()->GlobalStringType(); 139 } 140 GlobalBooleanType()141 Type *GlobalBooleanType() 142 { 143 return GetGlobalTypesHolder()->GlobalBooleanType(); 144 } 145 GlobalVoidType()146 Type *GlobalVoidType() 147 { 148 return GetGlobalTypesHolder()->GlobalVoidType(); 149 } 150 GlobalNullType()151 Type *GlobalNullType() 152 { 153 return GetGlobalTypesHolder()->GlobalNullType(); 154 } 155 GlobalUndefinedType()156 Type *GlobalUndefinedType() 157 { 158 return GetGlobalTypesHolder()->GlobalUndefinedType(); 159 } 160 GlobalUnknownType()161 Type *GlobalUnknownType() 162 { 163 return GetGlobalTypesHolder()->GlobalUnknownType(); 164 } 165 GlobalNeverType()166 Type *GlobalNeverType() 167 { 168 return GetGlobalTypesHolder()->GlobalNeverType(); 169 } 170 GlobalNonPrimitiveType()171 Type *GlobalNonPrimitiveType() 172 { 173 return GetGlobalTypesHolder()->GlobalNonPrimitiveType(); 174 } 175 GlobalBigintType()176 Type *GlobalBigintType() 177 { 178 return GetGlobalTypesHolder()->GlobalBigintType(); 179 } 180 GlobalFalseType()181 Type *GlobalFalseType() 182 { 183 return GetGlobalTypesHolder()->GlobalFalseType(); 184 } 185 GlobalTrueType()186 Type *GlobalTrueType() 187 { 188 return GetGlobalTypesHolder()->GlobalTrueType(); 189 } 190 GlobalNumberOrBigintType()191 Type *GlobalNumberOrBigintType() 192 { 193 return GetGlobalTypesHolder()->GlobalNumberOrBigintType(); 194 } 195 GlobalStringOrNumberType()196 Type *GlobalStringOrNumberType() 197 { 198 return GetGlobalTypesHolder()->GlobalStringOrNumberType(); 199 } 200 GlobalZeroType()201 Type *GlobalZeroType() 202 { 203 return GetGlobalTypesHolder()->GlobalZeroType(); 204 } 205 GlobalEmptyStringType()206 Type *GlobalEmptyStringType() 207 { 208 return GetGlobalTypesHolder()->GlobalEmptyStringType(); 209 } 210 GlobalZeroBigintType()211 Type *GlobalZeroBigintType() 212 { 213 return GetGlobalTypesHolder()->GlobalZeroBigintType(); 214 } 215 GlobalPrimitiveType()216 Type *GlobalPrimitiveType() 217 { 218 return GetGlobalTypesHolder()->GlobalPrimitiveType(); 219 } 220 GlobalEmptyTupleType()221 Type *GlobalEmptyTupleType() 222 { 223 return GetGlobalTypesHolder()->GlobalEmptyTupleType(); 224 } 225 GlobalEmptyObjectType()226 Type *GlobalEmptyObjectType() 227 { 228 return GetGlobalTypesHolder()->GlobalEmptyObjectType(); 229 } 230 GlobalResolvingReturnType()231 Type *GlobalResolvingReturnType() 232 { 233 return GetGlobalTypesHolder()->GlobalResolvingReturnType(); 234 } 235 GlobalErrorType()236 Type *GlobalErrorType() 237 { 238 return GetGlobalTypesHolder()->GlobalErrorType(); 239 } 240 NumberLiteralMap()241 NumberLiteralPool &NumberLiteralMap() 242 { 243 return numberLiteralMap_; 244 } 245 StringLiteralMap()246 StringLiteralPool &StringLiteralMap() 247 { 248 return stringLiteralMap_; 249 } 250 BigintLiteralMap()251 StringLiteralPool &BigintLiteralMap() 252 { 253 return bigintLiteralMap_; 254 } 255 256 bool StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const CompilerOptions &options) override; 257 Type *CheckTypeCached(ir::Expression *expr) override; 258 259 // Util 260 static bool InAssignment(ir::AstNode *node); 261 static bool IsAssignmentOperator(lexer::TokenType op); 262 static bool IsLiteralType(const Type *type); 263 static ir::AstNode *FindAncestorUntilGivenType(ir::AstNode *node, ir::AstNodeType stop); 264 static bool MaybeTypeOfKind(const Type *type, TypeFlag flags); 265 static bool MaybeTypeOfKind(const Type *type, ObjectType::ObjectTypeKind kind); 266 static bool IsConstantMemberAccess(ir::Expression *expr); 267 static bool IsStringLike(ir::Expression *expr); 268 static ir::MemberExpression *ResolveLeftMostMemberExpression(ir::MemberExpression *expr); 269 270 // Helpers 271 void CheckTruthinessOfType(Type *type, lexer::SourcePosition lineInfo); 272 Type *CheckNonNullType(Type *type, lexer::SourcePosition lineInfo); 273 Type *GetBaseTypeOfLiteralType(Type *type); 274 void CheckReferenceExpression(ir::Expression *expr, const char *invalidReferenceMsg, 275 const char *invalidOptionalChainMsg); 276 void CheckTestingKnownTruthyCallableOrAwaitableType(ir::Expression *condExpr, Type *type, ir::AstNode *body); 277 Type *ExtractDefinitelyFalsyTypes(Type *type); 278 Type *RemoveDefinitelyFalsyTypes(Type *type); 279 TypeFlag GetFalsyFlags(Type *type); 280 bool IsVariableUsedInConditionBody(ir::AstNode *parent, varbinder::Variable *searchVar); 281 bool FindVariableInBinaryExpressionChain(ir::AstNode *parent, varbinder::Variable *searchVar); 282 bool IsVariableUsedInBinaryExpressionChain(ir::AstNode *parent, varbinder::Variable *searchVar); 283 [[noreturn]] void ThrowBinaryLikeError(lexer::TokenType op, Type *leftType, Type *rightType, 284 lexer::SourcePosition lineInfo); 285 [[noreturn]] void ThrowAssignmentError(Type *source, Type *target, lexer::SourcePosition lineInfo, 286 bool isAsSrcLeftType = false); 287 void ElaborateElementwise(Type *targetType, ir::Expression *sourceNode, const lexer::SourcePosition &pos); 288 void InferSimpleVariableDeclaratorType(ir::VariableDeclarator *declarator); 289 void GetTypeVar(varbinder::Decl *decl); 290 void GetTypeParam(varbinder::Variable *var, varbinder::Decl *decl); 291 void GetTypeEnum(varbinder::Variable *var, varbinder::Decl *decl); 292 Type *GetDeclTsType(varbinder::Variable *var, varbinder::Decl *decl); 293 Type *GetTypeOfVariable(varbinder::Variable *var) override; 294 Type *GetUnaryResultType(Type *operandType); 295 Type *GetTypeFromClassOrInterfaceReference(ir::TSTypeReference *node, varbinder::Variable *var); 296 Type *GetTypeFromTypeAliasReference(ir::TSTypeReference *node, varbinder::Variable *var); 297 Type *GetTypeReferenceType(ir::TSTypeReference *node, varbinder::Variable *var); 298 299 // Type creation 300 Type *CreateNumberLiteralType(double value); 301 Type *CreateBigintLiteralType(const util::StringView &str, bool negative); 302 Type *CreateStringLiteralType(const util::StringView &str); 303 Type *CreateFunctionTypeWithSignature(Signature *callSignature); 304 Type *CreateConstructorTypeWithSignature(Signature *constructSignature); 305 Type *CreateTupleType(ObjectDescriptor *desc, ArenaVector<ElementFlags> &&elementFlags, 306 const TupleTypeInfo &tupleTypeInfo); 307 Type *CreateTupleType(ObjectDescriptor *desc, ArenaVector<ElementFlags> &&elementFlags, 308 const TupleTypeInfo &tupleTypeInfo, NamedTupleMemberPool &&namedMembers); 309 Type *CreateUnionType(std::initializer_list<Type *> constituentTypes); 310 Type *CreateUnionType(ArenaVector<Type *> &&constituentTypes); 311 Type *CreateUnionType(ArenaVector<Type *> &constituentTypes); 312 Type *CreateObjectTypeWithCallSignature(Signature *callSignature); 313 Type *CreateObjectTypeWithConstructSignature(Signature *constructSignature); 314 315 // Object 316 void ResolvePropertiesOfObjectType(ObjectType *type, ir::AstNode *member, 317 ArenaVector<ir::TSSignatureDeclaration *> &signatureDeclarations, 318 ArenaVector<ir::TSIndexSignature *> &indexDeclarations, bool isInterface); 319 void ResolveSignaturesOfObjectType(ObjectType *type, 320 ArenaVector<ir::TSSignatureDeclaration *> &signatureDeclarations); 321 void ResolveIndexInfosOfObjectType(ObjectType *type, ArenaVector<ir::TSIndexSignature *> &indexDeclarations); 322 void ResolveDeclaredMembers(InterfaceType *type); 323 bool ValidateInterfaceMemberRedeclaration(ObjectType *type, varbinder::Variable *prop, 324 const lexer::SourcePosition &locInfo); 325 varbinder::Variable *GetPropertyOfType(Type *type, const util::StringView &name, bool getPartial = false, 326 varbinder::VariableFlags propagateFlags = varbinder::VariableFlags::NONE); 327 varbinder::Variable *GetPropertyOfUnionType(UnionType *type, const util::StringView &name, bool getPartial, 328 varbinder::VariableFlags propagateFlags); 329 void CheckIndexConstraints(Type *type); 330 void ResolveUnionTypeMembers(UnionType *type); 331 void ResolveObjectTypeMembers(ObjectType *type); 332 void ResolveInterfaceOrClassTypeMembers(InterfaceType *type); 333 Type *CheckComputedPropertyName(ir::Expression *key); 334 Type *GetPropertyTypeForIndexType(Type *type, Type *indexType); 335 IndexInfo *GetApplicableIndexInfo(Type *type, Type *indexType); 336 ArenaVector<ObjectType *> GetBaseTypes(InterfaceType *type); 337 void ResolveStructuredTypeMembers(Type *type) override; 338 339 // Function 340 Type *HandleFunctionReturn(ir::ScriptFunction *func); 341 void CheckFunctionParameterDeclarations(const ArenaVector<ir::Expression *> ¶ms, SignatureInfo *signatureInfo); 342 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionParameter( 343 ir::Expression *param, SignatureInfo *signatureInfo); 344 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionIdentifierParameter( 345 ir::Identifier *param); 346 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionAssignmentPatternParameter( 347 ir::AssignmentExpression *param); 348 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionRestParameter( 349 ir::SpreadElement *param, SignatureInfo *signatureInfo); 350 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionArrayPatternParameter( 351 ir::ArrayExpression *param); 352 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionObjectPatternParameter( 353 ir::ObjectExpression *param); 354 void ValidateSubsequentNode(const ir::Statement *const subsequentNode, const ir::ScriptFunction *const func); 355 void CheckOverloadSignatureCompatibility(Signature *bodyCallSignature, Signature *signature); 356 void InferFunctionDeclarationType(const varbinder::FunctionDecl *decl, varbinder::Variable *funcVar); 357 void CollectTypesFromReturnStatements(ir::AstNode *parent, ArenaVector<Type *> *returnTypes); 358 void CheckAllCodePathsInNonVoidFunctionReturnOrThrow(ir::ScriptFunction *func, lexer::SourcePosition lineInfo, 359 const char *errMsg); 360 void CreatePatternParameterName(ir::AstNode *node, std::stringstream &ss); 361 void HandlePropertyPatternParameterName(ir::Property *prop, std::stringstream &ss); 362 void ThrowReturnTypeCircularityError(ir::ScriptFunction *func); 363 ArgRange GetArgRange(const ArenaVector<Signature *> &signatures, ArenaVector<Signature *> *potentialSignatures, 364 uint32_t callArgsSize, bool *haveSignatureWithRest); 365 bool CallMatchesSignature(const ArenaVector<ir::Expression *> &args, Signature *signature, bool throwError); 366 Type *ResolveCallOrNewExpression(const ArenaVector<Signature *> &signatures, 367 ArenaVector<ir::Expression *> arguments, const lexer::SourcePosition &errPos); 368 Type *CreateParameterTypeForArrayAssignmentPattern(ir::ArrayExpression *arrayPattern, Type *inferredType); 369 Type *CreateParameterTypeForObjectAssignmentPattern(ir::ObjectExpression *objectPattern, Type *inferredType); 370 371 // Binary like expression 372 Type *CheckBinaryOperator(ExpressionTypeInfo *leftRightType, ir::Expression *leftExpr, ir::Expression *rightExpr, 373 ir::AstNode *expr, lexer::TokenType op); 374 Type *CheckPlusOperator(ExpressionTypeInfo *leftRightType, ir::Expression *leftExpr, ir::Expression *rightExpr, 375 ir::AstNode *expr, lexer::TokenType op); 376 Type *CheckCompareOperator(ExpressionTypeInfo *leftRightType, ir::Expression *leftExpr, ir::Expression *rightExpr, 377 ir::AstNode *expr, lexer::TokenType op); 378 Type *CheckAndOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr); 379 Type *CheckOrOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr); 380 Type *CheckInstanceofExpression(Type *leftType, Type *rightType, ir::Expression *rightExpr, ir::AstNode *expr); 381 Type *CheckInExpression(Type *leftType, Type *rightType, ir::Expression *leftExpr, ir::Expression *rightExpr, 382 ir::AstNode *expr); 383 void CheckAssignmentOperator(lexer::TokenType op, ir::Expression *leftExpr, Type *leftType, Type *valueType); 384 385 private: 386 NumberLiteralPool numberLiteralMap_; 387 StringLiteralPool stringLiteralMap_; 388 StringLiteralPool bigintLiteralMap_; 389 390 // Binary like expression 391 void CheckBooleanLikeType(Type *leftType, Type *rightType, ir::AstNode *expr, lexer::TokenType op); 392 393 void CheckExtendsBases(ObjectType *&baseObj, InterfaceType *&type, varbinder::InterfaceDecl *&decl); 394 }; 395 396 } // namespace ark::es2panda::checker 397 398 #endif /* CHECKER_H */ 399