1 /* 2 * Copyright (c) 2021 - 2023 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 panda::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 panda::es2panda::varbinder 41 42 namespace panda::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 NewExpression; 88 class FunctionExpression; 89 class AwaitExpression; 90 class UpdateExpression; 91 class ConditionalExpression; 92 class YieldExpression; 93 class ArrowFunctionExpression; 94 class TemplateLiteral; 95 class TaggedTemplateExpression; 96 class TSIndexSignature; 97 class TSSignatureDeclaration; 98 class TSPropertySignature; 99 class TSMethodSignature; 100 class ChainExpression; 101 class VariableDeclarator; 102 103 enum class AstNodeType; 104 } // namespace panda::es2panda::ir 105 106 namespace panda::es2panda::checker { 107 108 class TSChecker : public Checker { 109 public: 110 // NOLINTNEXTLINE(readability-redundant-member-init) TSChecker()111 explicit TSChecker() : Checker() {} 112 GlobalNumberType()113 Type *GlobalNumberType() 114 { 115 return GetGlobalTypesHolder()->GlobalNumberType(); 116 } 117 GlobalAnyType()118 Type *GlobalAnyType() 119 { 120 return GetGlobalTypesHolder()->GlobalAnyType(); 121 } 122 GlobalStringType()123 Type *GlobalStringType() 124 { 125 return GetGlobalTypesHolder()->GlobalStringType(); 126 } 127 GlobalBooleanType()128 Type *GlobalBooleanType() 129 { 130 return GetGlobalTypesHolder()->GlobalBooleanType(); 131 } 132 GlobalVoidType()133 Type *GlobalVoidType() 134 { 135 return GetGlobalTypesHolder()->GlobalVoidType(); 136 } 137 GlobalNullType()138 Type *GlobalNullType() 139 { 140 return GetGlobalTypesHolder()->GlobalNullType(); 141 } 142 GlobalUndefinedType()143 Type *GlobalUndefinedType() 144 { 145 return GetGlobalTypesHolder()->GlobalUndefinedType(); 146 } 147 GlobalUnknownType()148 Type *GlobalUnknownType() 149 { 150 return GetGlobalTypesHolder()->GlobalUnknownType(); 151 } 152 GlobalNeverType()153 Type *GlobalNeverType() 154 { 155 return GetGlobalTypesHolder()->GlobalNeverType(); 156 } 157 GlobalNonPrimitiveType()158 Type *GlobalNonPrimitiveType() 159 { 160 return GetGlobalTypesHolder()->GlobalNonPrimitiveType(); 161 } 162 GlobalBigintType()163 Type *GlobalBigintType() 164 { 165 return GetGlobalTypesHolder()->GlobalBigintType(); 166 } 167 GlobalFalseType()168 Type *GlobalFalseType() 169 { 170 return GetGlobalTypesHolder()->GlobalFalseType(); 171 } 172 GlobalTrueType()173 Type *GlobalTrueType() 174 { 175 return GetGlobalTypesHolder()->GlobalTrueType(); 176 } 177 GlobalNumberOrBigintType()178 Type *GlobalNumberOrBigintType() 179 { 180 return GetGlobalTypesHolder()->GlobalNumberOrBigintType(); 181 } 182 GlobalStringOrNumberType()183 Type *GlobalStringOrNumberType() 184 { 185 return GetGlobalTypesHolder()->GlobalStringOrNumberType(); 186 } 187 GlobalZeroType()188 Type *GlobalZeroType() 189 { 190 return GetGlobalTypesHolder()->GlobalZeroType(); 191 } 192 GlobalEmptyStringType()193 Type *GlobalEmptyStringType() 194 { 195 return GetGlobalTypesHolder()->GlobalEmptyStringType(); 196 } 197 GlobalZeroBigintType()198 Type *GlobalZeroBigintType() 199 { 200 return GetGlobalTypesHolder()->GlobalZeroBigintType(); 201 } 202 GlobalPrimitiveType()203 Type *GlobalPrimitiveType() 204 { 205 return GetGlobalTypesHolder()->GlobalPrimitiveType(); 206 } 207 GlobalEmptyTupleType()208 Type *GlobalEmptyTupleType() 209 { 210 return GetGlobalTypesHolder()->GlobalEmptyTupleType(); 211 } 212 GlobalEmptyObjectType()213 Type *GlobalEmptyObjectType() 214 { 215 return GetGlobalTypesHolder()->GlobalEmptyObjectType(); 216 } 217 GlobalResolvingReturnType()218 Type *GlobalResolvingReturnType() 219 { 220 return GetGlobalTypesHolder()->GlobalResolvingReturnType(); 221 } 222 GlobalErrorType()223 Type *GlobalErrorType() 224 { 225 return GetGlobalTypesHolder()->GlobalErrorType(); 226 } 227 NumberLiteralMap()228 NumberLiteralPool &NumberLiteralMap() 229 { 230 return numberLiteralMap_; 231 } 232 StringLiteralMap()233 StringLiteralPool &StringLiteralMap() 234 { 235 return stringLiteralMap_; 236 } 237 BigintLiteralMap()238 StringLiteralPool &BigintLiteralMap() 239 { 240 return bigintLiteralMap_; 241 } 242 243 bool StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const CompilerOptions &options) override; 244 Type *CheckTypeCached(ir::Expression *expr) override; 245 246 // Util 247 static bool InAssignment(ir::AstNode *node); 248 static bool IsAssignmentOperator(lexer::TokenType op); 249 static bool IsLiteralType(const Type *type); 250 static ir::AstNode *FindAncestorUntilGivenType(ir::AstNode *node, ir::AstNodeType stop); 251 static bool MaybeTypeOfKind(const Type *type, TypeFlag flags); 252 static bool MaybeTypeOfKind(const Type *type, ObjectType::ObjectTypeKind kind); 253 static bool IsConstantMemberAccess(ir::Expression *expr); 254 static bool IsStringLike(ir::Expression *expr); 255 static ir::MemberExpression *ResolveLeftMostMemberExpression(ir::MemberExpression *expr); 256 257 // Helpers 258 void CheckTruthinessOfType(Type *type, lexer::SourcePosition lineInfo); 259 Type *CheckNonNullType(Type *type, lexer::SourcePosition lineInfo); 260 Type *GetBaseTypeOfLiteralType(Type *type); 261 void CheckReferenceExpression(ir::Expression *expr, const char *invalidReferenceMsg, 262 const char *invalidOptionalChainMsg); 263 void CheckTestingKnownTruthyCallableOrAwaitableType(ir::Expression *condExpr, Type *type, ir::AstNode *body); 264 Type *ExtractDefinitelyFalsyTypes(Type *type); 265 Type *RemoveDefinitelyFalsyTypes(Type *type); 266 TypeFlag GetFalsyFlags(Type *type); 267 bool IsVariableUsedInConditionBody(ir::AstNode *parent, varbinder::Variable *searchVar); 268 bool FindVariableInBinaryExpressionChain(ir::AstNode *parent, varbinder::Variable *searchVar); 269 bool IsVariableUsedInBinaryExpressionChain(ir::AstNode *parent, varbinder::Variable *searchVar); 270 [[noreturn]] void ThrowBinaryLikeError(lexer::TokenType op, Type *leftType, Type *rightType, 271 lexer::SourcePosition lineInfo); 272 [[noreturn]] void ThrowAssignmentError(Type *source, Type *target, lexer::SourcePosition lineInfo, 273 bool isAsSrcLeftType = false); 274 void ElaborateElementwise(Type *targetType, ir::Expression *sourceNode, const lexer::SourcePosition &pos); 275 void InferSimpleVariableDeclaratorType(ir::VariableDeclarator *declarator); 276 Type *GetTypeOfVariable(varbinder::Variable *var) override; 277 Type *GetUnaryResultType(Type *operandType); 278 Type *GetTypeFromClassOrInterfaceReference(ir::TSTypeReference *node, varbinder::Variable *var); 279 Type *GetTypeFromTypeAliasReference(ir::TSTypeReference *node, varbinder::Variable *var); 280 Type *GetTypeReferenceType(ir::TSTypeReference *node, varbinder::Variable *var); 281 282 // Type creation 283 Type *CreateNumberLiteralType(double value); 284 Type *CreateBigintLiteralType(const util::StringView &str, bool negative); 285 Type *CreateStringLiteralType(const util::StringView &str); 286 Type *CreateFunctionTypeWithSignature(Signature *callSignature); 287 Type *CreateConstructorTypeWithSignature(Signature *constructSignature); 288 Type *CreateTupleType(ObjectDescriptor *desc, ArenaVector<ElementFlags> &&elementFlags, ElementFlags combinedFlags, 289 uint32_t minLength, uint32_t fixedLength, bool readonly); 290 Type *CreateTupleType(ObjectDescriptor *desc, ArenaVector<ElementFlags> &&elementFlags, ElementFlags combinedFlags, 291 uint32_t minLength, uint32_t fixedLength, bool readonly, NamedTupleMemberPool &&namedMembers); 292 Type *CreateUnionType(std::initializer_list<Type *> constituentTypes); 293 Type *CreateUnionType(ArenaVector<Type *> &&constituentTypes); 294 Type *CreateUnionType(ArenaVector<Type *> &constituentTypes); 295 Type *CreateObjectTypeWithCallSignature(Signature *callSignature); 296 Type *CreateObjectTypeWithConstructSignature(Signature *constructSignature); 297 298 // Object 299 void ResolvePropertiesOfObjectType(ObjectType *type, ir::AstNode *member, 300 ArenaVector<ir::TSSignatureDeclaration *> &signatureDeclarations, 301 ArenaVector<ir::TSIndexSignature *> &indexDeclarations, bool isInterface); 302 void ResolveSignaturesOfObjectType(ObjectType *type, 303 ArenaVector<ir::TSSignatureDeclaration *> &signatureDeclarations); 304 void ResolveIndexInfosOfObjectType(ObjectType *type, ArenaVector<ir::TSIndexSignature *> &indexDeclarations); 305 void ResolveDeclaredMembers(InterfaceType *type); 306 bool ValidateInterfaceMemberRedeclaration(ObjectType *type, varbinder::Variable *prop, 307 const lexer::SourcePosition &locInfo); 308 varbinder::Variable *GetPropertyOfType(Type *type, const util::StringView &name, bool getPartial = false, 309 varbinder::VariableFlags propagateFlags = varbinder::VariableFlags::NONE); 310 varbinder::Variable *GetPropertyOfUnionType(UnionType *type, const util::StringView &name, bool getPartial, 311 varbinder::VariableFlags propagateFlags); 312 void CheckIndexConstraints(Type *type); 313 void ResolveUnionTypeMembers(UnionType *type); 314 void ResolveObjectTypeMembers(ObjectType *type); 315 void ResolveInterfaceOrClassTypeMembers(InterfaceType *type); 316 Type *CheckComputedPropertyName(ir::Expression *key); 317 Type *GetPropertyTypeForIndexType(Type *type, Type *indexType); 318 IndexInfo *GetApplicableIndexInfo(Type *type, Type *indexType); 319 ArenaVector<ObjectType *> GetBaseTypes(InterfaceType *type); 320 void ResolveStructuredTypeMembers(Type *type) override; 321 322 // Function 323 Type *HandleFunctionReturn(ir::ScriptFunction *func); 324 void CheckFunctionParameterDeclarations(const ArenaVector<ir::Expression *> ¶ms, SignatureInfo *signatureInfo); 325 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionParameter( 326 ir::Expression *param, SignatureInfo *signatureInfo); 327 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionIdentifierParameter( 328 ir::Identifier *param); 329 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionAssignmentPatternParameter( 330 ir::AssignmentExpression *param); 331 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionRestParameter( 332 ir::SpreadElement *param, SignatureInfo *signatureInfo); 333 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionArrayPatternParameter( 334 ir::ArrayExpression *param); 335 std::tuple<varbinder::LocalVariable *, varbinder::LocalVariable *, bool> CheckFunctionObjectPatternParameter( 336 ir::ObjectExpression *param); 337 void InferFunctionDeclarationType(const varbinder::FunctionDecl *decl, varbinder::Variable *funcVar); 338 void CollectTypesFromReturnStatements(ir::AstNode *parent, ArenaVector<Type *> *returnTypes); 339 void CheckAllCodePathsInNonVoidFunctionReturnOrThrow(ir::ScriptFunction *func, lexer::SourcePosition lineInfo, 340 const char *errMsg); 341 void CreatePatternParameterName(ir::AstNode *node, std::stringstream &ss); 342 void ThrowReturnTypeCircularityError(ir::ScriptFunction *func); 343 ArgRange GetArgRange(const ArenaVector<Signature *> &signatures, ArenaVector<Signature *> *potentialSignatures, 344 uint32_t callArgsSize, bool *haveSignatureWithRest); 345 bool CallMatchesSignature(const ArenaVector<ir::Expression *> &args, Signature *signature, bool throwError); 346 Type *ResolveCallOrNewExpression(const ArenaVector<Signature *> &signatures, 347 ArenaVector<ir::Expression *> arguments, const lexer::SourcePosition &errPos); 348 Type *CreateParameterTypeForArrayAssignmentPattern(ir::ArrayExpression *arrayPattern, Type *inferredType); 349 Type *CreateParameterTypeForObjectAssignmentPattern(ir::ObjectExpression *objectPattern, Type *inferredType); 350 351 // Binary like expression 352 Type *CheckBinaryOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr, ir::Expression *rightExpr, 353 ir::AstNode *expr, lexer::TokenType op); 354 Type *CheckPlusOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr, ir::Expression *rightExpr, 355 ir::AstNode *expr, lexer::TokenType op); 356 Type *CheckCompareOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr, ir::Expression *rightExpr, 357 ir::AstNode *expr, lexer::TokenType op); 358 Type *CheckAndOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr); 359 Type *CheckOrOperator(Type *leftType, Type *rightType, ir::Expression *leftExpr); 360 Type *CheckInstanceofExpression(Type *leftType, Type *rightType, ir::Expression *rightExpr, ir::AstNode *expr); 361 Type *CheckInExpression(Type *leftType, Type *rightType, ir::Expression *leftExpr, ir::Expression *rightExpr, 362 ir::AstNode *expr); 363 void CheckAssignmentOperator(lexer::TokenType op, ir::Expression *leftExpr, Type *leftType, Type *valueType); 364 365 private: 366 NumberLiteralPool numberLiteralMap_; 367 StringLiteralPool stringLiteralMap_; 368 StringLiteralPool bigintLiteralMap_; 369 }; 370 371 } // namespace panda::es2panda::checker 372 373 #endif /* CHECKER_H */ 374