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_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 "util/es2pandaMacros.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(util::DiagnosticEngine & diagnosticEngine,ArenaAllocator * programAllocator)124 explicit TSChecker(util::DiagnosticEngine &diagnosticEngine, [[maybe_unused]] ArenaAllocator *programAllocator) 125 : Checker(diagnosticEngine) 126 { 127 } 128 GlobalNumberType()129 Type *GlobalNumberType() 130 { 131 return GetGlobalTypesHolder()->GlobalNumberType(); 132 } 133 GlobalAnyType()134 Type *GlobalAnyType() 135 { 136 return GetGlobalTypesHolder()->GlobalAnyType(); 137 } 138 GlobalStringType()139 Type *GlobalStringType() 140 { 141 return GetGlobalTypesHolder()->GlobalStringType(); 142 } 143 GlobalBooleanType()144 Type *GlobalBooleanType() 145 { 146 return GetGlobalTypesHolder()->GlobalBooleanType(); 147 } 148 GlobalVoidType()149 Type *GlobalVoidType() 150 { 151 return GetGlobalTypesHolder()->GlobalVoidType(); 152 } 153 GlobalNullType()154 Type *GlobalNullType() 155 { 156 return GetGlobalTypesHolder()->GlobalNullType(); 157 } 158 GlobalUndefinedType()159 Type *GlobalUndefinedType() 160 { 161 return GetGlobalTypesHolder()->GlobalUndefinedType(); 162 } 163 GlobalUnknownType()164 Type *GlobalUnknownType() 165 { 166 return GetGlobalTypesHolder()->GlobalUnknownType(); 167 } 168 GlobalNeverType()169 Type *GlobalNeverType() 170 { 171 return GetGlobalTypesHolder()->GlobalNeverType(); 172 } 173 GlobalNonPrimitiveType()174 Type *GlobalNonPrimitiveType() 175 { 176 return GetGlobalTypesHolder()->GlobalNonPrimitiveType(); 177 } 178 GlobalBigintType()179 Type *GlobalBigintType() 180 { 181 return GetGlobalTypesHolder()->GlobalBigintType(); 182 } 183 GlobalFalseType()184 Type *GlobalFalseType() 185 { 186 return GetGlobalTypesHolder()->GlobalFalseType(); 187 } 188 GlobalTrueType()189 Type *GlobalTrueType() 190 { 191 return GetGlobalTypesHolder()->GlobalTrueType(); 192 } 193 GlobalNumberOrBigintType()194 Type *GlobalNumberOrBigintType() 195 { 196 return GetGlobalTypesHolder()->GlobalNumberOrBigintType(); 197 } 198 GlobalStringOrNumberType()199 Type *GlobalStringOrNumberType() 200 { 201 return GetGlobalTypesHolder()->GlobalStringOrNumberType(); 202 } 203 GlobalZeroType()204 Type *GlobalZeroType() 205 { 206 return GetGlobalTypesHolder()->GlobalZeroType(); 207 } 208 GlobalEmptyStringType()209 Type *GlobalEmptyStringType() 210 { 211 return GetGlobalTypesHolder()->GlobalEmptyStringType(); 212 } 213 GlobalZeroBigintType()214 Type *GlobalZeroBigintType() 215 { 216 return GetGlobalTypesHolder()->GlobalZeroBigintType(); 217 } 218 GlobalPrimitiveType()219 Type *GlobalPrimitiveType() 220 { 221 return GetGlobalTypesHolder()->GlobalPrimitiveType(); 222 } 223 GlobalEmptyTupleType()224 Type *GlobalEmptyTupleType() 225 { 226 return GetGlobalTypesHolder()->GlobalEmptyTupleType(); 227 } 228 GlobalEmptyObjectType()229 Type *GlobalEmptyObjectType() 230 { 231 return GetGlobalTypesHolder()->GlobalEmptyObjectType(); 232 } 233 GlobalResolvingReturnType()234 Type *GlobalResolvingReturnType() 235 { 236 return GetGlobalTypesHolder()->GlobalResolvingReturnType(); 237 } 238 GlobalErrorType()239 Type *GlobalErrorType() 240 { 241 return GetGlobalTypesHolder()->GlobalErrorType(); 242 } 243 NumberLiteralMap()244 NumberLiteralPool &NumberLiteralMap() 245 { 246 return numberLiteralMap_; 247 } 248 StringLiteralMap()249 StringLiteralPool &StringLiteralMap() 250 { 251 return stringLiteralMap_; 252 } 253 BigintLiteralMap()254 StringLiteralPool &BigintLiteralMap() 255 { 256 return bigintLiteralMap_; 257 } 258 259 bool StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const util::Options &options) override; 260 Type *CheckTypeCached(ir::Expression *expr) override; 261 262 // Util 263 static bool InAssignment(ir::AstNode *node); 264 static bool IsAssignmentOperator(lexer::TokenType op); 265 static bool IsLiteralType(const Type *type); 266 static ir::AstNode *FindAncestorUntilGivenType(ir::AstNode *node, ir::AstNodeType stop); 267 static bool MaybeTypeOfKind(const Type *type, TypeFlag flags); 268 static bool MaybeTypeOfKind(const Type *type, ObjectType::ObjectTypeKind kind); 269 static bool IsConstantMemberAccess(ir::Expression *expr); 270 static bool IsStringLike(ir::Expression *expr); 271 static ir::MemberExpression *ResolveLeftMostMemberExpression(ir::MemberExpression *expr); 272 273 // Helpers 274 void CheckTruthinessOfType(Type *type, lexer::SourcePosition lineInfo); 275 Type *CheckNonNullType(Type *type, lexer::SourcePosition lineInfo); 276 Type *GetBaseTypeOfLiteralType(Type *type); 277 void CheckReferenceExpression(ir::Expression *expr, const char *invalidReferenceMsg, 278 const char *invalidOptionalChainMsg); 279 void CheckTestingKnownTruthyCallableOrAwaitableType(ir::Expression *condExpr, Type *type, ir::AstNode *body); 280 Type *ExtractDefinitelyFalsyTypes(Type *type); 281 Type *RemoveDefinitelyFalsyTypes(Type *type); 282 TypeFlag GetFalsyFlags(Type *type); 283 bool IsVariableUsedInConditionBody(ir::AstNode *parent, varbinder::Variable *searchVar); 284 bool FindVariableInBinaryExpressionChain(ir::AstNode *parent, varbinder::Variable *searchVar); 285 bool IsVariableUsedInBinaryExpressionChain(ir::AstNode *parent, varbinder::Variable *searchVar); 286 [[noreturn]] void ThrowTypeError(std::string_view message, const lexer::SourcePosition &pos); 287 [[noreturn]] void ThrowTypeError(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &pos); 288 [[noreturn]] void ThrowBinaryLikeError(lexer::TokenType op, Type *leftType, Type *rightType, 289 lexer::SourcePosition lineInfo); 290 [[noreturn]] void ThrowAssignmentError(Type *source, Type *target, lexer::SourcePosition lineInfo, 291 bool isAsSrcLeftType = false); 292 void ElaborateElementwise(Type *targetType, ir::Expression *sourceNode, const lexer::SourcePosition &pos); 293 void InferSimpleVariableDeclaratorType(ir::VariableDeclarator *declarator); 294 void GetTypeVar(varbinder::Decl *decl); 295 void GetTypeParam(varbinder::Variable *var, varbinder::Decl *decl); 296 void GetTypeEnum(varbinder::Variable *var, varbinder::Decl *decl); 297 Type *GetDeclTsType(varbinder::Variable *var, varbinder::Decl *decl); 298 Type *GetTypeOfVariable(varbinder::Variable *var) override; 299 Type *GetUnaryResultType(Type *operandType); 300 Type *GetTypeFromClassOrInterfaceReference(ir::TSTypeReference *node, varbinder::Variable *var); 301 Type *GetTypeFromTypeAliasReference(ir::TSTypeReference *node, varbinder::Variable *var); 302 Type *GetTypeReferenceType(ir::TSTypeReference *node, varbinder::Variable *var); 303 304 // Type creation 305 Type *CreateNumberLiteralType(double value); 306 Type *CreateBigintLiteralType(const util::StringView &str, bool negative); 307 Type *CreateStringLiteralType(const util::StringView &str); 308 Type *CreateFunctionTypeWithSignature(Signature *callSignature); 309 Type *CreateConstructorTypeWithSignature(Signature *constructSignature); 310 Type *CreateTupleType(ObjectDescriptor *desc, ArenaVector<ElementFlags> &&elementFlags, 311 const TupleTypeInfo &tupleTypeInfo); 312 Type *CreateTupleType(ObjectDescriptor *desc, ArenaVector<ElementFlags> &&elementFlags, 313 const TupleTypeInfo &tupleTypeInfo, NamedTupleMemberPool &&namedMembers); 314 Type *CreateUnionType(std::initializer_list<Type *> constituentTypes); 315 Type *CreateUnionType(ArenaVector<Type *> &&constituentTypes); 316 Type *CreateUnionType(ArenaVector<Type *> &constituentTypes); 317 Type *CreateObjectTypeWithCallSignature(Signature *callSignature); 318 Type *CreateObjectTypeWithConstructSignature(Signature *constructSignature); 319 320 // Object 321 void ResolvePropertiesOfObjectType(ObjectType *type, ir::AstNode *member, 322 ArenaVector<ir::TSSignatureDeclaration *> &signatureDeclarations, 323 ArenaVector<ir::TSIndexSignature *> &indexDeclarations, bool isInterface); 324 void ResolveSignaturesOfObjectType(ObjectType *type, 325 ArenaVector<ir::TSSignatureDeclaration *> &signatureDeclarations); 326 void ResolveIndexInfosOfObjectType(ObjectType *type, ArenaVector<ir::TSIndexSignature *> &indexDeclarations); 327 void ResolveDeclaredMembers(InterfaceType *type); 328 bool ValidateInterfaceMemberRedeclaration(ObjectType *type, varbinder::Variable *prop, 329 const lexer::SourcePosition &locInfo); 330 varbinder::Variable *GetPropertyOfType(Type *type, const util::StringView &name, bool getPartial = false, 331 varbinder::VariableFlags propagateFlags = varbinder::VariableFlags::NONE); 332 varbinder::Variable *GetPropertyOfUnionType(UnionType *type, const util::StringView &name, bool getPartial, 333 varbinder::VariableFlags propagateFlags); 334 void CheckIndexConstraints(Type *type); 335 void ResolveUnionTypeMembers(UnionType *type); 336 void ResolveObjectTypeMembers(ObjectType *type); 337 void ResolveInterfaceOrClassTypeMembers(InterfaceType *type); 338 Type *CheckComputedPropertyName(ir::Expression *key); 339 Type *GetPropertyTypeForIndexType(Type *type, Type *indexType); 340 IndexInfo *GetApplicableIndexInfo(Type *type, Type *indexType); 341 ArenaVector<ObjectType *> GetBaseTypes(InterfaceType *type); 342 void ResolveStructuredTypeMembers(Type *type) override; 343 344 // Function 345 Type *HandleFunctionReturn(ir::ScriptFunction *func); 346 void CheckFunctionParameterDeclarations(const ArenaVector<ir::Expression *> ¶ms, SignatureInfo *signatureInfo); 347 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionParameter( 348 ir::Expression *param, SignatureInfo *signatureInfo); 349 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionIdentifierParameter( 350 ir::Identifier *param); 351 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionAssignmentPatternParameter( 352 ir::AssignmentExpression *param); 353 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionRestParameter( 354 ir::SpreadElement *param, SignatureInfo *signatureInfo); 355 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionArrayPatternParameter( 356 ir::ArrayExpression *param); 357 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionObjectPatternParameter( 358 ir::ObjectExpression *param); 359 void ValidateSubsequentNode(const ir::Statement *const subsequentNode, const ir::ScriptFunction *const func); 360 void CheckOverloadSignatureCompatibility(Signature *bodyCallSignature, Signature *signature); 361 void InferFunctionDeclarationType(const varbinder::FunctionDecl *decl, varbinder::Variable *funcVar); 362 void CollectTypesFromReturnStatements(ir::AstNode *parent, ArenaVector<Type *> *returnTypes); 363 void CheckAllCodePathsInNonVoidFunctionReturnOrThrow(ir::ScriptFunction *func, lexer::SourcePosition lineInfo, 364 const char *errMsg); 365 void CreatePatternParameterName(ir::AstNode *node, std::stringstream &ss); 366 void HandlePropertyPatternParameterName(ir::Property *prop, std::stringstream &ss); 367 void ThrowReturnTypeCircularityError(ir::ScriptFunction *func); 368 ArgRange GetArgRange(const ArenaVector<Signature *> &signatures, ArenaVector<Signature *> *potentialSignatures, 369 uint32_t callArgsSize, bool *haveSignatureWithRest); 370 bool CallMatchesSignature(const ArenaVector<ir::Expression *> &args, Signature *signature, bool throwError); 371 Type *ResolveCallOrNewExpression(const ArenaVector<Signature *> &signatures, 372 ArenaVector<ir::Expression *> arguments, const lexer::SourcePosition &errPos); 373 Type *CreateParameterTypeForArrayAssignmentPattern(ir::ArrayExpression *arrayPattern, Type *inferredType); 374 Type *CreateParameterTypeForObjectAssignmentPattern(ir::ObjectExpression *objectPattern, Type *inferredType); 375 376 // Binary like expression 377 Type *CheckBinaryOperator(ExpressionTypeInfo *leftRightType, ir::Expression *leftExpr, ir::Expression *rightExpr, 378 ir::AstNode *expr, lexer::TokenType op); 379 Type *CheckPlusOperator(ExpressionTypeInfo *leftRightType, ir::Expression *leftExpr, ir::Expression *rightExpr, 380 ir::AstNode *expr, lexer::TokenType op); 381 Type *CheckCompareOperator(ExpressionTypeInfo *leftRightType, ir::Expression *leftExpr, ir::Expression *rightExpr, 382 ir::AstNode *expr, lexer::TokenType op); 383 Type *CheckAndOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr); 384 Type *CheckOrOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr); 385 Type *CheckInstanceofExpression(Type *leftType, Type *rightType, ir::Expression *rightExpr, ir::AstNode *expr); 386 Type *CheckInExpression(Type *leftType, Type *rightType, ir::Expression *leftExpr, ir::Expression *rightExpr, 387 ir::AstNode *expr); 388 void CheckAssignmentOperator(lexer::TokenType op, ir::Expression *leftExpr, Type *leftType, Type *valueType); 389 390 private: 391 NumberLiteralPool numberLiteralMap_; 392 StringLiteralPool stringLiteralMap_; 393 StringLiteralPool bigintLiteralMap_; 394 395 // Binary like expression 396 void CheckBooleanLikeType(Type *leftType, Type *rightType, ir::AstNode *expr, lexer::TokenType op); 397 398 void CheckExtendsBases(ObjectType *&baseObj, InterfaceType *&type, varbinder::InterfaceDecl *&decl); 399 }; 400 401 } // namespace ark::es2panda::checker 402 403 #endif /* CHECKER_H */ 404