Lines Matching refs:checker
18 #include "checker/TSchecker.h"
19 #include "checker/ts/destructuringContext.h"
21 namespace ark::es2panda::checker {
29 checker::Type *TSAnalyzer::Check(ir::CatchClause *st) const
31 TSChecker *checker = GetTSChecker();
35 checker::Type *catchParamType = typeAnnotation->Check(checker);
37 if (!catchParamType->HasTypeFlag(checker::TypeFlag::ANY_OR_UNKNOWN)) {
38 checker->ThrowTypeError("Catch clause variable type annotation must be 'any' or 'unknown' if specified",
43 st->Body()->Check(checker);
48 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ClassDefinition *node) const
50 TSChecker *checker = GetTSChecker();
52 return checker->GlobalAnyType();
55 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::MetaProperty *expr) const
57 TSChecker *checker = GetTSChecker();
59 return checker->GlobalAnyType();
62 checker::Type *TSAnalyzer::Check(ir::TSIndexSignature *node) const
64 TSChecker *checker = GetTSChecker();
70 node->typeAnnotation_->Check(checker);
71 checker::Type *indexType = node->typeAnnotation_->GetType(checker);
72 checker::IndexInfo *info =
73 checker->Allocator()->New<checker::IndexInfo>(indexType, paramName, node->Readonly(), node->Start());
74 checker::ObjectDescriptor *desc = checker->Allocator()->New<checker::ObjectDescriptor>(checker->Allocator());
75 checker::ObjectType *placeholder = checker->Allocator()->New<checker::ObjectLiteralType>(desc);
87 checker::Type *TSAnalyzer::Check(ir::TSMethodSignature *node) const
89 TSChecker *checker = GetTSChecker();
91 checker->CheckComputedPropertyName(node->Key());
94 checker::ScopeContext scopeCtx(checker, node->Scope());
96 auto *signatureInfo = checker->Allocator()->New<checker::SignatureInfo>(checker->Allocator());
97 checker->CheckFunctionParameterDeclarations(node->Params(), signatureInfo);
99 auto *callSignature = checker->Allocator()->New<checker::Signature>(signatureInfo, checker->GlobalAnyType());
100 node->Variable()->SetTsType(checker->CreateFunctionTypeWithSignature(callSignature));
104 checker->ThrowTypeError(
109 returnType->Check(checker);
110 callSignature->SetReturnType(returnType->GetType(checker));
115 checker::Type *TSAnalyzer::Check(ir::TSPropertySignature *node) const
117 TSChecker *checker = GetTSChecker();
119 node->TypeAnnotation()->Check(checker);
123 checker->CheckComputedPropertyName(node->Key());
127 node->Variable()->SetTsType(node->TypeAnnotation()->GetType(checker));
131 checker->ThrowTypeError("Property implicitly has an 'any' type.", node->Start());
135 checker::Type *TSAnalyzer::Check(ir::TSSignatureDeclaration *node) const
137 TSChecker *checker = GetTSChecker();
142 checker::ScopeContext scopeCtx(checker, node->Scope());
144 auto *signatureInfo = checker->Allocator()->New<checker::SignatureInfo>(checker->Allocator());
145 checker->CheckFunctionParameterDeclarations(node->Params(), signatureInfo);
151 checker->ThrowTypeError(
156 checker->ThrowTypeError(
161 node->ReturnTypeAnnotation()->Check(checker);
162 checker::Type *returnType = node->ReturnTypeAnnotation()->GetType(checker);
164 auto *signature = checker->Allocator()->New<checker::Signature>(signatureInfo, returnType);
166 checker::Type *placeholderObj = nullptr;
169 placeholderObj = checker->CreateObjectTypeWithCallSignature(signature);
171 placeholderObj = checker->CreateObjectTypeWithConstructSignature(signature);
178 static void GetSpreadElementType(checker::TSChecker *checker, checker::Type *spreadType,
179 ArenaVector<checker::Type *> &elementTypes, const lexer::SourcePosition &loc)
181 bool inConstContext = checker->HasStatus(checker::CheckerStatus::IN_CONST_CONTEXT);
184 ArenaVector<checker::Type *> tupleElementTypes(checker->Allocator()->Adapter());
185 checker::TupleType *spreadTuple = spreadType->AsObjectType()->AsTupleType();
200 elementTypes.push_back(checker->CreateUnionType(std::move(tupleElementTypes)));
205 checker->ThrowTypeError(
210 ArenaVector<checker::Type *> spreadTypes(checker->Allocator()->Adapter());
220 checker::TupleType *tuple = type->AsObjectType()->AsTupleType();
234 elementTypes.push_back(checker->CreateUnionType(std::move(spreadTypes)));
238 checker->ThrowTypeError(
242 checker::Type *TSAnalyzer::Check(ir::ArrayExpression *expr) const
244 TSChecker *checker = GetTSChecker();
245 ArenaVector<checker::Type *> elementTypes(checker->Allocator()->Adapter());
246 ArenaVector<checker::ElementFlags> elementFlags(checker->Allocator()->Adapter());
247 bool inConstContext = checker->HasStatus(checker::CheckerStatus::IN_CONST_CONTEXT);
248 bool createTuple = checker->HasStatus(checker::CheckerStatus::FORCE_TUPLE);
252 checker::Type *spreadType = it->AsSpreadElement()->Argument()->Check(checker);
256 elementFlags.push_back(checker::ElementFlags::VARIADIC);
260 GetSpreadElementType(checker, spreadType, elementTypes, it->Start());
261 elementFlags.push_back(checker::ElementFlags::REST);
265 checker::Type *elementType = it->Check(checker);
268 elementType = checker->GetBaseTypeOfLiteralType(elementType);
271 elementFlags.push_back(checker::ElementFlags::REQUIRED);
276 checker::ObjectDescriptor *desc = checker->Allocator()->New<checker::ObjectDescriptor>(checker->Allocator());
280 util::StringView memberIndex = util::Helpers::ToStringView(checker->Allocator(), index);
282 checker->Allocator(), memberIndex, varbinder::VariableFlags::PROPERTY, nullptr);
292 const checker::TupleTypeInfo tupleTypeInfo = {ElementFlags::REQUIRED, index, index, inConstContext};
293 return checker->CreateTupleType(desc, std::move(elementFlags), tupleTypeInfo);
296 checker::Type *arrayElementType = nullptr;
298 arrayElementType = checker->GlobalAnyType();
300 arrayElementType = checker->CreateUnionType(std::move(elementTypes));
303 return checker->Allocator()->New<checker::ArrayType>(arrayElementType);
306 checker::Type *TSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const
308 TSChecker *checker = GetTSChecker();
317 checker::ScopeContext scopeCtx(checker, expr->Function()->Scope());
319 auto *signatureInfo = checker->Allocator()->New<checker::SignatureInfo>(checker->Allocator());
320 checker->CheckFunctionParameterDeclarations(expr->Function()->Params(), signatureInfo);
322 auto *signature = checker->Allocator()->New<checker::Signature>(signatureInfo, checker->GlobalResolvingReturnType(),
324 checker::Type *funcType = checker->CreateFunctionTypeWithSignature(signature);
330 signature->SetReturnType(checker->HandleFunctionReturn(expr->Function()));
333 expr->Function()->Body()->Check(checker);
339 checker::Type *TSAnalyzer::CheckAssignmentExprOperatorType(ir::AssignmentExpression *expr, checker::Type *leftType,
340 checker::Type *rightType) const
342 TSChecker *checker = GetTSChecker();
358 return checker->CheckBinaryOperator(&leftRightType, expr->Left(), expr->Right(), expr,
362 return checker->CheckPlusOperator(&leftRightType, expr->Left(), expr->Right(), expr, expr->OperatorType());
365 checker->CheckAssignmentOperator(expr->OperatorType(), expr->Left(), leftType, rightType);
377 checker::Type *TSAnalyzer::Check(ir::AssignmentExpression *expr) const
379 TSChecker *checker = GetTSChecker();
381 auto savedContext = checker::SavedCheckerContext(checker, checker::CheckerStatus::FORCE_TUPLE);
383 checker::ArrayDestructuringContext({checker, expr->Left(), true, true, nullptr, expr->Right()});
389 auto savedContext = checker::SavedCheckerContext(checker, checker::CheckerStatus::FORCE_TUPLE);
391 checker::ObjectDestructuringContext({checker, expr->Left(), true, true, nullptr, expr->Right()});
398 checker->ThrowTypeError(
403 auto *leftType = expr->Left()->Check(checker);
405 if (leftType->HasTypeFlag(checker::TypeFlag::READONLY)) {
406 checker->ThrowTypeError("Cannot assign to this property because it is readonly.", expr->Left()->Start());
410 checker->ElaborateElementwise(leftType, expr->Right(), expr->Left()->Start());
411 return checker->CheckTypeCached(expr->Right());
414 auto *rightType = expr->Right()->Check(checker);
419 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::AwaitExpression *expr) const
421 TSChecker *checker = GetTSChecker();
423 return checker->GlobalAnyType();
426 checker::Type *TSAnalyzer::CheckBinaryExprArithmLogical(ir::BinaryExpression *expr, ExpressionTypeInfo *leftRightType,
427 TSChecker *checker) const
441 return checker->CheckBinaryOperator(leftRightType, expr->Left(), expr->Right(), expr, expr->OperatorType());
444 return checker->CheckPlusOperator(leftRightType, expr->Left(), expr->Right(), expr, expr->OperatorType());
447 return checker->CheckAndOperator(leftRightType->leftType, leftRightType->rightType, expr->Left());
450 return checker->CheckOrOperator(leftRightType->leftType, leftRightType->rightType, expr->Left());
458 checker::Type *TSAnalyzer::Check(ir::BinaryExpression *expr) const
460 TSChecker *checker = GetTSChecker();
462 leftRightType.leftType = expr->Left()->Check(checker);
463 leftRightType.rightType = expr->Right()->Check(checker);
465 auto *checkBinaryExprPunctuator = CheckBinaryExprArithmLogical(expr, &leftRightType, checker);
473 return checker->CheckCompareOperator(&leftRightType, expr->Left(), expr->Right(), expr,
480 if (checker->IsTypeEqualityComparableTo(leftRightType.leftType, leftRightType.rightType) ||
481 checker->IsTypeEqualityComparableTo(leftRightType.rightType, leftRightType.leftType)) {
482 return checker->GlobalBooleanType();
485 checker->ThrowBinaryLikeError(expr->OperatorType(), leftRightType.leftType, leftRightType.rightType,
489 // NOTE: Csaba Repasi. Implement checker for nullish coalescing
490 return checker->GlobalAnyType();
493 checker->CheckAssignmentOperator(expr->OperatorType(), expr->Left(), leftRightType.leftType,
498 return checker->CheckInstanceofExpression(leftRightType.leftType, leftRightType.rightType, expr->Right(),
502 return checker->CheckInExpression(leftRightType.leftType, leftRightType.rightType, expr->Left(),
514 checker::Type *TSAnalyzer::Check(ir::CallExpression *expr) const
516 TSChecker *checker = GetTSChecker();
517 checker::Type *calleeType = expr->callee_->Check(checker);
521 checker::ObjectType *calleeObj = calleeType->AsObjectType();
522 return checker->ResolveCallOrNewExpression(calleeObj->CallSignatures(), expr->Arguments(), expr->Start());
525 checker->ThrowTypeError("This expression is not callable.", expr->Start());
529 checker::Type *TSAnalyzer::Check(ir::ChainExpression *expr) const
531 TSChecker *checker = GetTSChecker();
532 return expr->expression_->Check(checker);
535 checker::Type *TSAnalyzer::Check(ir::ConditionalExpression *expr) const
537 TSChecker *checker = GetTSChecker();
538 checker::Type *testType = expr->Test()->Check(checker);
540 checker->CheckTruthinessOfType(testType, expr->Test()->Start());
541 checker->CheckTestingKnownTruthyCallableOrAwaitableType(expr->Test(), testType, expr->Consequent());
543 checker::Type *consequentType = expr->Consequent()->Check(checker);
544 checker::Type *alternateType = expr->Alternate()->Check(checker);
546 return checker->CreateUnionType({consequentType, alternateType});
549 checker::Type *TSAnalyzer::Check(ir::FunctionExpression *expr) const
551 TSChecker *checker = GetTSChecker();
560 checker::ScopeContext scopeCtx(checker, expr->Function()->Scope());
562 auto *signatureInfo = checker->Allocator()->New<checker::SignatureInfo>(checker->Allocator());
563 checker->CheckFunctionParameterDeclarations(expr->Function()->Params(), signatureInfo);
565 auto *signature = checker->Allocator()->New<checker::Signature>(signatureInfo, checker->GlobalResolvingReturnType(),
567 checker::Type *funcType = checker->CreateFunctionTypeWithSignature(signature);
573 signature->SetReturnType(checker->HandleFunctionReturn(expr->Function()));
575 expr->Function()->Body()->Check(checker);
580 checker::Type *TSAnalyzer::Check(ir::Identifier *expr) const
582 TSChecker *checker = GetTSChecker();
585 return checker->GlobalUndefinedType();
588 checker->ThrowTypeError({"Cannot find name ", expr->Name()}, expr->Start());
594 checker->ThrowTypeError({expr->Name(), " only refers to a type, but is being used as a value here."},
598 expr->SetTsType(checker->GetTypeOfVariable(expr->Variable()));
602 void TSAnalyzer::CheckComputed(ir::MemberExpression *expr, checker::Type *indexType) const
604 TSChecker *checker = GetTSChecker();
605 if (!indexType->HasTypeFlag(checker::TypeFlag::STRING_LIKE | checker::TypeFlag::NUMBER_LIKE)) {
606 checker->ThrowTypeError({"Type ", indexType, " cannot be used as index type"}, expr->Property()->Start());
610 checker->ThrowTypeError("No index signature with a parameter of type 'string' was found on type this type",
615 checker->ThrowTypeError("No index signature with a parameter of type 'number' was found on type this type",
621 checker->ThrowTypeError(
626 checker->ThrowTypeError(
631 checker->ThrowTypeError(
641 checker::Type *TSAnalyzer::Check(ir::MemberExpression *expr) const
643 TSChecker *checker = GetTSChecker();
644 checker::Type *baseType = checker->CheckNonNullType(expr->Object()->Check(checker), expr->Object()->Start());
647 checker::Type *indexType = expr->Property()->Check(checker);
648 checker::Type *indexedAccessType = checker->GetPropertyTypeForIndexType(baseType, indexType);
656 varbinder::Variable *prop = checker->GetPropertyOfType(baseType, expr->Property()->AsIdentifier()->Name());
659 checker::Type *propType = checker->GetTypeOfVariable(prop);
661 propType->AddTypeFlag(checker::TypeFlag::READONLY);
668 checker::ObjectType *objType = baseType->AsObjectType();
671 checker::Type *indexType = objType->StringIndexInfo()->GetType();
673 indexType->AddTypeFlag(checker::TypeFlag::READONLY);
680 checker->ThrowTypeError({"Property ", expr->Property()->AsIdentifier()->Name(), " does not exist on this type."},
685 checker::Type *TSAnalyzer::Check(ir::NewExpression *expr) const
687 TSChecker *checker = GetTSChecker();
688 checker::Type *calleeType = expr->callee_->Check(checker);
691 checker::ObjectType *calleeObj = calleeType->AsObjectType();
692 return checker->ResolveCallOrNewExpression(calleeObj->ConstructSignatures(), expr->Arguments(), expr->Start());
695 checker->ThrowTypeError("This expression is not callable.", expr->Start());
727 static checker::Type *GetTypeForProperty(ir::Property *prop, checker::TSChecker *checker)
730 checker::Type *funcType = prop->Value()->Check(checker);
733 return checker->GlobalAnyType();
741 return prop->Key()->Check(checker);
744 return prop->Value()->Check(checker);
748 checker::ObjectDescriptor *desc, ir::Expression *it) const
750 TSChecker *checker = GetTSChecker();
753 checker::Type *const spreadType = it->AsSpreadElement()->Argument()->Check(checker);
757 checker->ThrowTypeError("Spread types may only be created from object types.", it->Start());
763 checker->ThrowTypeError({found->first, " is specified more than once, so this usage will be overwritten."},
778 void TSAnalyzer::CheckNonComputed(checker::ObjectDescriptor *desc, ir::Expression *it,
782 TSChecker *checker = GetTSChecker();
784 checker::Type *propType = GetTypeForProperty(prop, checker);
788 auto *memberVar = varbinder::Scope::CreateVar(checker->Allocator(), propName, flags, it);
793 propType = checker->GetBaseTypeOfLiteralType(propType);
813 checker::IndexInfo *TSAnalyzer::CreateUnionTypeHelper(ArenaVector<checker::Type *> &computedPropTypes,
816 TSChecker *checker = GetTSChecker();
818 return checker->Allocator()->New<checker::IndexInfo>(checker->CreateUnionType(std::move(computedPropTypes)), "x",
822 checker::Type *TSAnalyzer::Check(ir::ObjectExpression *expr) const
824 TSChecker *checker = GetTSChecker();
826 checker::ObjectDescriptor *desc = checker->Allocator()->New<checker::ObjectDescriptor>(checker->Allocator());
828 bool inConstContext = checker->HasStatus(checker::CheckerStatus::IN_CONST_CONTEXT);
829 ArenaVector<checker::Type *> computedNumberPropTypes(checker->Allocator()->Adapter());
830 ArenaVector<checker::Type *> computedStringPropTypes(checker->Allocator()->Adapter());
839 if (prop->IsComputed() && checker->CheckComputedPropertyName(prop->Key())->IsNumberType()) {
841 computedNumberPropTypes.push_back(prop->Value()->Check(checker));
845 if (prop->IsComputed() && checker->CheckComputedPropertyName(prop->Key())->IsStringType()) {
847 computedStringPropTypes.push_back(prop->Value()->Check(checker));
878 checker::Type *returnType = checker->Allocator()->New<checker::ObjectLiteralType>(desc);
879 returnType->AsObjectType()->AddObjectFlag(checker::ObjectFlags::RESOLVED_MEMBERS |
880 checker::ObjectFlags::CHECK_EXCESS_PROPS);
884 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::OmittedExpression *expr) const
886 TSChecker *checker = GetTSChecker();
887 return checker->GlobalUndefinedType();
890 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::OpaqueTypeNode *expr) const
895 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::SequenceExpression *expr) const
897 TSChecker *checker = GetTSChecker();
899 return checker->GlobalAnyType();
902 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::SuperExpression *expr) const
904 TSChecker *checker = GetTSChecker();
906 return checker->GlobalAnyType();
909 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TaggedTemplateExpression *expr) const
911 TSChecker *checker = GetTSChecker();
913 return checker->GlobalAnyType();
916 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TemplateLiteral *expr) const
918 TSChecker *checker = GetTSChecker();
920 return checker->GlobalAnyType();
923 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ThisExpression *expr) const
925 TSChecker *checker = GetTSChecker();
927 return checker->GlobalAnyType();
930 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TypeofExpression *expr) const
932 TSChecker *checker = GetTSChecker();
933 return checker->GlobalStringType();
936 checker::Type *TSAnalyzer::CheckDeleteKeyword([[maybe_unused]] checker::TSChecker *checker,
939 checker::Type *propType = expr->argument_->Check(checker);
941 checker->ThrowTypeError("The operand of a delete operator must be a property reference.",
945 checker->ThrowTypeError("The operand of a delete operator cannot be a readonly property.",
949 checker->ThrowTypeError("The operand of a delete operator must be a optional.", expr->Argument()->Start());
951 return checker->GlobalBooleanType();
954 checker::Type *TSAnalyzer::CheckLiteral([[maybe_unused]] checker::TSChecker *checker, ir::UnaryExpression *expr) const
964 return checker->CreateNumberLiteralType(numberValue);
967 return checker->CreateNumberLiteralType(-numberValue);
970 return checker->CreateBigintLiteralType(lit->AsBigIntLiteral()->Str(), true);
976 checker::Type *TSAnalyzer::Check(ir::UnaryExpression *expr) const
978 TSChecker *checker = GetTSChecker();
979 checker::Type *operandType = expr->argument_->Check(checker);
986 return CheckDeleteKeyword(checker, expr);
989 auto *res = CheckLiteral(checker, expr);
998 checker->CheckNonNullType(operandType, expr->Start());
1002 if (checker::TSChecker::MaybeTypeOfKind(operandType, checker::TypeFlag::BIGINT_LIKE)) {
1003 checker->ThrowTypeError({"Operator '+' cannot be applied to type '", operandType, "'"},
1007 return checker->GlobalNumberType();
1010 return checker->GetUnaryResultType(operandType);
1013 checker->CheckTruthinessOfType(operandType, expr->Start());
1015 if ((facts & checker::TypeFacts::TRUTHY) != 0) {
1016 return checker->GlobalFalseType();
1019 if ((facts & checker::TypeFacts::FALSY) != 0) {
1020 return checker->GlobalTrueType();
1023 return checker->GlobalBooleanType();
1033 checker::Type *TSAnalyzer::Check(ir::UpdateExpression *expr) const
1035 TSChecker *checker = GetTSChecker();
1036 checker::Type *operandType = expr->argument_->Check(checker);
1037 checker->CheckNonNullType(operandType, expr->Start());
1039 if (!operandType->HasTypeFlag(checker::TypeFlag::VALID_ARITHMETIC_TYPE)) {
1040 checker->ThrowTypeError("An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type.",
1044 checker->CheckReferenceExpression(
1048 return checker->GetUnaryResultType(operandType);
1051 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::YieldExpression *expr) const
1053 TSChecker *checker = GetTSChecker();
1055 return checker->GlobalAnyType();
1058 checker::Type *TSAnalyzer::Check(ir::BigIntLiteral *expr) const
1060 TSChecker *checker = GetTSChecker();
1061 auto search = checker->BigintLiteralMap().find(expr->Str());
1062 if (search != checker->BigintLiteralMap().end()) {
1066 auto *newBigintLiteralType = checker->Allocator()->New<checker::BigintLiteralType>(expr->Str(), false);
1067 checker->BigintLiteralMap().insert({expr->Str(), newBigintLiteralType});
1071 checker::Type *TSAnalyzer::Check(ir::BooleanLiteral *expr) const
1073 TSChecker *checker = GetTSChecker();
1074 return expr->Value() ? checker->GlobalTrueType() : checker->GlobalFalseType();
1077 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::NullLiteral *expr) const
1079 TSChecker *checker = GetTSChecker();
1080 return checker->GlobalNullType();
1083 checker::Type *TSAnalyzer::Check(ir::NumberLiteral *expr) const
1085 TSChecker *checker = GetTSChecker();
1086 auto search = checker->NumberLiteralMap().find(expr->Number().GetDouble());
1087 if (search != checker->NumberLiteralMap().end()) {
1091 auto *newNumLiteralType = checker->Allocator()->New<checker::NumberLiteralType>(expr->Number().GetDouble());
1092 checker->NumberLiteralMap().insert({expr->Number().GetDouble(), newNumLiteralType});
1096 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::RegExpLiteral *expr) const
1098 TSChecker *checker = GetTSChecker();
1100 return checker->GlobalAnyType();
1103 checker::Type *TSAnalyzer::Check(ir::StringLiteral *expr) const
1105 TSChecker *checker = GetTSChecker();
1106 auto search = checker->StringLiteralMap().find(expr->Str());
1107 if (search != checker->StringLiteralMap().end()) {
1111 auto *newStrLiteralType = checker->Allocator()->New<checker::StringLiteralType>(expr->Str());
1112 checker->StringLiteralMap().insert({expr->Str(), newStrLiteralType});
1117 checker::Type *TSAnalyzer::Check(ir::BlockStatement *st) const
1119 TSChecker *checker = GetTSChecker();
1120 checker::ScopeContext scopeCtx(checker, st->Scope());
1123 it->Check(checker);
1129 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::BreakStatement *st) const
1134 checker::Type *TSAnalyzer::Check(ir::DoWhileStatement *st) const
1136 TSChecker *checker = GetTSChecker();
1137 checker::ScopeContext scopeCtx(checker, st->Scope());
1139 checker::Type *testType = st->Test()->Check(checker);
1140 checker->CheckTruthinessOfType(testType, st->Test()->Start());
1141 st->Body()->Check(checker);
1146 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::EmptyStatement *st) const
1151 checker::Type *TSAnalyzer::Check(ir::ExpressionStatement *st) const
1153 TSChecker *checker = GetTSChecker();
1154 return st->GetExpression()->Check(checker);
1157 checker::Type *TSAnalyzer::Check(ir::ForUpdateStatement *st) const
1159 TSChecker *checker = GetTSChecker();
1160 checker::ScopeContext scopeCtx(checker, st->Scope());
1163 st->Init()->Check(checker);
1167 checker::Type *testType = st->Test()->Check(checker);
1168 checker->CheckTruthinessOfType(testType, st->Start());
1172 st->Update()->Check(checker);
1175 st->Body()->Check(checker);
1180 checker::Type *TSAnalyzer::Check(ir::FunctionDeclaration *st) const
1182 TSChecker *checker = GetTSChecker();
1188 auto result = checker->Scope()->Find(funcName);
1191 checker::ScopeContext scopeCtx(checker, st->Function()->Scope());
1194 checker->InferFunctionDeclarationType(result.variable->Declaration()->AsFunctionDecl(), result.variable);
1197 st->Function()->Body()->Check(checker);
1202 checker::Type *TSAnalyzer::Check(ir::IfStatement *st) const
1204 TSChecker *checker = GetTSChecker();
1205 checker::Type *testType = st->Test()->Check(checker);
1206 checker->CheckTruthinessOfType(testType, st->Start());
1207 checker->CheckTestingKnownTruthyCallableOrAwaitableType(st->Test(), testType, st->Consequent());
1209 st->Consequent()->Check(checker);
1212 st->Alternate()->Check(checker);
1218 checker::Type *TSAnalyzer::Check(ir::ReturnStatement *st) const
1220 TSChecker *checker = GetTSChecker();
1228 checker->ThrowTypeError("Setters cannot return a value", st->Start());
1233 checker::Type *returnType = checker->GlobalUndefinedType();
1234 checker::Type *funcReturnType = containingFunc->ReturnTypeAnnotation()->GetType(checker);
1237 checker->ElaborateElementwise(funcReturnType, st->Argument(), st->Start());
1238 returnType = checker->CheckTypeCached(st->Argument());
1241 checker->IsTypeAssignableTo(returnType, funcReturnType,
1249 checker::Type *TSAnalyzer::Check(ir::SwitchStatement *st) const
1251 TSChecker *checker = GetTSChecker();
1252 checker::ScopeContext scopeCtx(checker, st->Scope());
1254 checker::Type *exprType = st->Discriminant()->Check(checker);
1255 bool exprIsLiteral = checker::TSChecker::IsLiteralType(exprType);
1259 checker::Type *caseType = it->Test()->Check(checker);
1260 bool caseIsLiteral = checker::TSChecker::IsLiteralType(caseType);
1261 checker::Type *comparedExprType = exprType;
1264 caseType = caseIsLiteral ? checker->GetBaseTypeOfLiteralType(caseType) : caseType;
1265 comparedExprType = checker->GetBaseTypeOfLiteralType(exprType);
1268 if (!checker->IsTypeEqualityComparableTo(comparedExprType, caseType) &&
1269 !checker->IsTypeComparableTo(caseType, comparedExprType)) {
1270 checker->ThrowTypeError({"Type ", caseType, " is not comparable to type ", comparedExprType},
1276 caseStmt->Check(checker);
1283 checker::Type *TSAnalyzer::Check(ir::TryStatement *st) const
1285 TSChecker *checker = GetTSChecker();
1286 st->Block()->Check(checker);
1290 catchClause->Check(checker);
1295 st->finalizer_->Check(checker);
1301 static void CheckSimpleVariableDeclaration(checker::TSChecker *checker, ir::VariableDeclarator *declarator)
1304 checker::Type *previousType = bindingVar->TsType();
1311 checker->AddStatus(checker::CheckerStatus::IN_CONST_CONTEXT);
1315 typeAnnotation->Check(checker);
1319 checker::Type *const annotationType = typeAnnotation->GetType(checker);
1320 checker->ElaborateElementwise(annotationType, initializer, declarator->Id()->Start());
1323 bindingVar->SetTsType(typeAnnotation->GetType(checker));
1325 checker::Type *initializerType = checker->CheckTypeCached(initializer);
1328 initializerType = checker->GetBaseTypeOfLiteralType(initializerType);
1332 checker->ThrowTypeError(
1339 checker->ThrowTypeError({"Variable ", declarator->Id()->AsIdentifier()->Name(), " implicitly has an any type."},
1344 checker->IsTypeIdenticalTo(bindingVar->TsType(), previousType,
1351 checker->RemoveStatus(checker::CheckerStatus::IN_CONST_CONTEXT);
1354 checker::Type *TSAnalyzer::Check(ir::VariableDeclarator *st) const
1356 TSChecker *checker = GetTSChecker();
1363 CheckSimpleVariableDeclaration(checker, st);
1369 auto context = checker::SavedCheckerContext(checker, checker::CheckerStatus::FORCE_TUPLE);
1370 checker::ArrayDestructuringContext({checker, st->Id(), false,
1380 auto context = checker::SavedCheckerContext(checker, checker::CheckerStatus::FORCE_TUPLE);
1381 checker::ObjectDestructuringContext({checker, st->Id(), false,
1390 checker::Type *TSAnalyzer::Check(ir::VariableDeclaration *st) const
1392 TSChecker *checker = GetTSChecker();
1394 it->Check(checker);
1400 checker::Type *TSAnalyzer::Check(ir::WhileStatement *st) const
1402 TSChecker *checker = GetTSChecker();
1403 checker::ScopeContext scopeCtx(checker, st->Scope());
1405 checker::Type *testType = st->Test()->Check(checker);
1406 checker->CheckTruthinessOfType(testType, st->Test()->Start());
1408 st->Body()->Check(checker);
1412 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSAnyKeyword *node) const
1417 checker::Type *TSAnalyzer::Check(ir::TSArrayType *node) const
1419 TSChecker *checker = GetTSChecker();
1420 node->elementType_->Check(checker);
1424 static bool IsValidConstAssertionArgument(checker::Checker *checker, const ir::AstNode *arg)
1448 auto result = checker->Scope()->Find(memberExpr->Object()->AsIdentifier()->Name());
1449 constexpr auto ENUM_LITERAL_TYPE = checker::EnumLiteralType::EnumLiteralTypeKind::LITERAL;
1451 result.variable->TsType()->HasTypeFlag(checker::TypeFlag::ENUM_LITERAL) &&
1463 checker::Type *TSAnalyzer::Check(ir::TSAsExpression *expr) const
1465 TSChecker *checker = GetTSChecker();
1467 auto context = checker::SavedCheckerContext(checker, checker::CheckerStatus::IN_CONST_CONTEXT);
1468 checker::Type *exprType = expr->Expr()->Check(checker);
1470 if (!IsValidConstAssertionArgument(checker, expr->Expr())) {
1471 checker->ThrowTypeError(
1480 auto context = checker::SavedCheckerContext(checker, checker::CheckerStatus::NO_OPTS);
1482 expr->TypeAnnotation()->Check(checker);
1483 checker::Type *exprType = checker->GetBaseTypeOfLiteralType(expr->Expr()->Check(checker));
1484 checker::Type *targetType = expr->TypeAnnotation()->GetType(checker);
1486 checker->IsTypeComparableTo(
1496 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSBigintKeyword *node) const
1501 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSBooleanKeyword *node) const
1506 checker::Type *TSAnalyzer::Check(ir::TSConstructorType *node) const
1508 TSChecker *checker = GetTSChecker();
1509 checker::ScopeContext scopeCtx(checker, node->Scope());
1511 auto *signatureInfo = checker->Allocator()->New<checker::SignatureInfo>(checker->Allocator());
1512 checker->CheckFunctionParameterDeclarations(node->Params(), signatureInfo);
1513 node->ReturnType()->Check(checker);
1515 checker->Allocator()->New<checker::Signature>(signatureInfo, node->ReturnType()->GetType(checker));
1517 return checker->CreateConstructorTypeWithSignature(constructSignature);
1520 static varbinder::EnumMemberResult EvaluateIdentifier(checker::TSChecker *checker, varbinder::EnumVariable *enumVar,
1533 checker->ThrowTypeError({"Cannot find name ", expr->AsIdentifier()->Name()},
1540 checker->ThrowTypeError(
1621 varbinder::EnumMemberResult TSAnalyzer::EvaluateBinaryExpression(checker::TSChecker *checker,
1625 varbinder::EnumMemberResult left = EvaluateEnumMember(checker, enumVar, expr->AsBinaryExpression()->Left());
1626 varbinder::EnumMemberResult right = EvaluateEnumMember(checker, enumVar, expr->AsBinaryExpression()->Right());
1636 util::UString res(ss.str(), checker->Allocator());
1643 varbinder::EnumMemberResult TSAnalyzer::EvaluateUnaryExpression(checker::TSChecker *checker,
1647 varbinder::EnumMemberResult value = EvaluateEnumMember(checker, enumVar, expr->Argument());
1670 varbinder::EnumMemberResult TSAnalyzer::EvaluateEnumMember(checker::TSChecker *checker,
1676 return EvaluateUnaryExpression(checker, enumVar, expr->AsUnaryExpression());
1679 return EvaluateBinaryExpression(checker, enumVar, expr->AsBinaryExpression());
1688 return EvaluateIdentifier(checker, enumVar, expr->AsIdentifier());
1691 return EvaluateEnumMember(checker, enumVar, expr->AsMemberExpression());
1713 static void AddEnumValueDeclaration(checker::TSChecker *checker, double number, varbinder::EnumVariable *variable)
1715 variable->SetTsType(checker->GlobalNumberType());
1717 util::StringView memberStr = util::Helpers::ToStringView(checker->Allocator(), number);
1719 varbinder::LocalScope *enumScope = checker->Scope()->AsLocalScope();
1724 auto *decl = checker->Allocator()->New<varbinder::EnumDecl>(memberStr);
1726 enumScope->AddDecl(checker->Allocator(), decl, ScriptExtension::TS);
1731 enumVar->SetTsType(checker->GlobalStringType());
1735 auto *decl = checker->Allocator()->New<varbinder::EnumDecl>(memberStr);
1757 TSChecker *checker = GetTSChecker();
1761 checker->ThrowTypeError("Enum member must have initializer.", variable->Declaration()->Node()->Start());
1766 AddEnumValueDeclaration(checker, *value, variable);
1772 checker->ThrowTypeError(INVALID_COMPUTED_WITH_STRING, init->Start());
1775 varbinder::EnumMemberResult res = EvaluateEnumMember(checker, variable, init);
1778 variable->SetTsType(checker->GlobalStringType());
1785 checker->ThrowTypeError(INVALID_CONST_MEMBER, init->Start());
1797 checker->ThrowTypeError(INVALID_CONST_NAN, init->Start());
1801 checker->ThrowTypeError(INVALID_CONST_INF, init->Start());
1805 AddEnumValueDeclaration(checker, *value, variable);
1808 checker::Type *TSAnalyzer::InferType(checker::TSChecker *checker, bool isConst, ir::TSEnumDeclaration *st) const
1812 varbinder::LocalScope *enumScope = checker->Scope()->AsLocalScope();
1825 checker::Type *enumType = checker->Allocator()->New<checker::EnumLiteralType>(
1826 st->Key()->Name(), checker->Scope(),
1827 isLiteralEnum ? checker::EnumLiteralType::EnumLiteralTypeKind::LITERAL
1828 : checker::EnumLiteralType::EnumLiteralTypeKind::NUMERIC);
1833 checker::Type *TSAnalyzer::Check(ir::TSEnumDeclaration *st) const
1835 TSChecker *checker = GetTSChecker();
1840 checker::ScopeContext scopeCtx(checker, st->Scope());
1841 checker::Type *enumType = InferType(checker, st->IsConst(), st);
1849 checker::Type *TSAnalyzer::Check(ir::TSFunctionType *node) const
1851 TSChecker *checker = GetTSChecker();
1852 checker::ScopeContext scopeCtx(checker, node->Scope());
1854 auto *signatureInfo = checker->Allocator()->New<checker::SignatureInfo>(checker->Allocator());
1855 checker->CheckFunctionParameterDeclarations(node->Params(), signatureInfo);
1856 node->ReturnType()->Check(checker);
1858 checker->Allocator()->New<checker::Signature>(signatureInfo, node->ReturnType()->GetType(checker));
1860 return checker->CreateFunctionTypeWithSignature(callSignature);
1863 checker::Type *TSAnalyzer::Check(ir::TSIndexedAccessType *node) const
1865 TSChecker *checker = GetTSChecker();
1866 node->objectType_->Check(checker);
1867 node->indexType_->Check(checker);
1868 checker::Type *resolved = node->GetType(checker);
1874 checker::Type *indexType = checker->CheckTypeCached(node->indexType_);
1876 if (!indexType->HasTypeFlag(checker::TypeFlag::STRING_LIKE | checker::TypeFlag::NUMBER_LIKE)) {
1877 checker->ThrowTypeError({"Type ", indexType, " cannot be used as index type"}, node->IndexType()->Start());
1881 checker->ThrowTypeError("Type has no matching signature for type 'number'", node->Start());
1884 checker->ThrowTypeError("Type has no matching signature for type 'string'", node->Start());
1888 checker::Type *TSAnalyzer::Check(ir::TSInterfaceBody *expr) const
1890 TSChecker *checker = GetTSChecker();
1892 it->Check(checker);
1898 static void CheckInheritedPropertiesAreIdentical(checker::TSChecker *checker, checker::InterfaceType *type,
1901 checker->GetBaseTypes(type);
1908 checker->ResolveDeclaredMembers(type);
1910 checker::InterfacePropertyMap properties;
1917 checker->ResolveStructuredTypeMembers(base);
1918 ArenaVector<varbinder::LocalVariable *> inheritedProperties(checker->Allocator()->Adapter());
1926 checker::Type *sourceType = checker->GetTypeOfVariable(inheritedProp);
1927 checker::Type *targetType = checker->GetTypeOfVariable(res->second.first);
1928 checker->IsTypeIdenticalTo(sourceType, targetType,
1937 checker::Type *TSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const
1939 TSChecker *checker = GetTSChecker();
1944 checker::Type *resolvedType = var->TsType();
1947 checker::ObjectDescriptor *desc =
1948 checker->Allocator()->New<checker::ObjectDescriptor>(checker->Allocator());
1950 checker->Allocator()->New<checker::InterfaceType>(checker->Allocator(), st->Id()->Name(), desc);
1955 checker::InterfaceType *resolvedInterface = resolvedType->AsObjectType()->AsInterfaceType();
1956 CheckInheritedPropertiesAreIdentical(checker, resolvedInterface, st->Id()->Start());
1959 checker->IsTypeAssignableTo(
1964 checker->CheckIndexConstraints(resolvedInterface);
1967 st->Body()->Check(checker);
1972 checker::Type *TSAnalyzer::Check(ir::TSLiteralType *node) const
1974 TSChecker *checker = GetTSChecker();
1975 node->GetType(checker);
1979 checker::Type *TSAnalyzer::Check(ir::TSNamedTupleMember *node) const
1981 TSChecker *checker = GetTSChecker();
1982 node->ElementType()->Check(checker);
1986 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSNeverKeyword *node) const
1991 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSNullKeyword *node) const
1996 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSNumberKeyword *node) const
2001 checker::Type *TSAnalyzer::Check(ir::TSParenthesizedType *node) const
2003 TSChecker *checker = GetTSChecker();
2004 node->type_->Check(checker);
2008 checker::Type *TSAnalyzer::Check(ir::TSQualifiedName *expr) const
2010 TSChecker *checker = GetTSChecker();
2011 checker::Type *baseType = checker->CheckNonNullType(expr->Left()->Check(checker), expr->Left()->Start());
2012 varbinder::Variable *prop = checker->GetPropertyOfType(baseType, expr->Right()->Name());
2015 return checker->GetTypeOfVariable(prop);
2019 checker::ObjectType *objType = baseType->AsObjectType();
2026 checker->ThrowTypeError({"Property ", expr->Right()->Name(), " does not exist on this type."},
2031 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSStringKeyword *node) const
2036 checker::Type *TSAnalyzer::Check(ir::TSTupleType *node) const
2038 TSChecker *checker = GetTSChecker();
2040 it->Check(checker);
2043 node->GetType(checker);
2047 checker::Type *TSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const
2049 TSChecker *checker = GetTSChecker();
2050 st->TypeAnnotation()->Check(checker);
2054 checker::Type *TSAnalyzer::Check(ir::TSTypeLiteral *node) const
2056 TSChecker *checker = GetTSChecker();
2059 it->Check(checker);
2062 checker::Type *type = node->GetType(checker);
2063 checker->CheckIndexConstraints(type);
2068 checker::Type *TSAnalyzer::Check(ir::TSTypeQuery *node) const
2070 TSChecker *checker = GetTSChecker();
2075 node->SetTsType(node->exprName_->Check(checker));
2079 checker::Type *TSAnalyzer::Check(ir::TSTypeReference *node) const
2081 TSChecker *checker = GetTSChecker();
2082 node->GetType(checker);
2086 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSUndefinedKeyword *node) const
2091 checker::Type *TSAnalyzer::Check(ir::TSUnionType *node) const
2093 TSChecker *checker = GetTSChecker();
2095 it->Check(checker);
2098 node->GetType(checker);
2102 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSUnknownKeyword *node) const
2107 checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSVoidKeyword *node) const
2111 } // namespace ark::es2panda::checker