Lines Matching refs:checker
20 #include "checker/ETSchecker.h"
21 #include "checker/ets/castingContext.h"
22 #include "checker/ets/typeRelationContext.h"
23 #include "checker/types/globalTypesHolder.h"
24 #include "checker/types/ets/etsTupleType.h"
25 #include "checker/types/ets/etsAsyncFuncReturnType.h"
30 namespace ark::es2panda::checker {
38 checker::Type *ETSAnalyzer::Check(ir::CatchClause *st) const
40 ETSChecker *checker = GetETSChecker();
41 checker::ETSObjectType *exceptionType = checker->GlobalETSObjectType();
46 checker::Type *catchParamAnnotationType = paramIdent->TypeAnnotation()->GetType(checker);
48 exceptionType = checker->CheckExceptionOrErrorType(catchParamAnnotationType, st->Param()->Start());
53 st->Body()->Check(checker);
59 checker::Type *ETSAnalyzer::Check(ir::ClassDefinition *node) const
61 ETSChecker *checker = GetETSChecker();
64 checker->BuildBasicClassProperties(node);
68 checker->CheckClassDefinition(node);
74 checker::Type *ETSAnalyzer::Check(ir::ClassProperty *st) const
77 ETSChecker *checker = GetETSChecker();
83 checker::SavedCheckerContext savedContext(checker, checker->Context().Status(),
84 checker->Context().ContainingClass(),
85 checker->Context().ContainingSignature());
88 checker->AddStatus(checker::CheckerStatus::IN_STATIC_CONTEXT);
91 st->SetTsType(checker->CheckVariableDeclaration(st->Id(), st->TypeAnnotation(), st->Value(), st->Modifiers()));
96 checker::Type *ETSAnalyzer::Check(ir::ClassStaticBlock *st) const
98 ETSChecker *checker = GetETSChecker();
100 if (checker->HasStatus(checker::CheckerStatus::INNER_CLASS)) {
101 checker->LogTypeError("Static initializer is not allowed in inner class.", st->Start());
102 st->SetTsType(checker->GlobalTypeError());
107 checker->BuildFunctionSignature(func);
109 st->SetTsType(checker->GlobalTypeError());
112 st->SetTsType(checker->BuildNamedFunctionType(func));
113 checker::ScopeContext scopeCtx(checker, func->Scope());
114 checker::SavedCheckerContext savedContext(checker, checker->Context().Status(),
115 checker->Context().ContainingClass());
116 checker->AddStatus(checker::CheckerStatus::IN_STATIC_BLOCK | checker::CheckerStatus::IN_STATIC_CONTEXT);
117 func->Body()->Check(checker);
121 // Satisfy the Chinese code checker
122 static void HandleNativeAndAsyncMethods(ETSChecker *checker, ir::MethodDefinition *node)
127 checker->LogTypeError("'Native' method should have explicit return type", scriptFunc->Start());
128 node->SetTsType(checker->GlobalTypeError());
138 asyncFuncReturnType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType()) {
139 checker->LogTypeError("Return type of async function must be 'Promise'.", scriptFunc->Start());
140 scriptFunc->Signature()->SetReturnType(checker->GlobalTypeError());
146 ComposeAsyncImplMethod(checker, node);
151 checker::Type *ETSAnalyzer::Check(ir::MethodDefinition *node) const
153 ETSChecker *checker = GetETSChecker();
158 checker->LogTypeError("Invalid function expression", node->Start());
159 node->SetTsType(checker->GlobalTypeError());
169 checker->HasStatus(checker::CheckerStatus::IN_INTERFACE))) {
170 checker->LogTypeError("Only abstract or native methods can't have body.", scriptFunc->Start());
171 node->SetTsType(checker->GlobalTypeError());
177 checker->LogTypeError("Native and Declare methods should have explicit return type.", scriptFunc->Start());
178 node->SetTsType(checker->GlobalTypeError());
183 node->SetTsType(checker->BuildMethodSignature(node));
187 HandleNativeAndAsyncMethods(checker, node);
188 DoBodyTypeChecking(checker, node, scriptFunc);
189 CheckPredefinedMethodReturnType(checker, scriptFunc);
196 checker->CheckOverride(node->TsType()->AsETSFunctionType()->FindSignature(node->Function()));
200 overload->Check(checker);
204 checker->CheckRethrowingFunction(scriptFunc);
212 ETSChecker *checker = GetETSChecker();
217 checker->LogTypeError(
221 node->SetTsType(checker->GlobalTypeError());
226 checker->LogTypeError("Invalid function expression", node->Start());
227 node->SetTsType(checker->GlobalTypeError());
232 !(checker->HasStatus(checker::CheckerStatus::IN_ABSTRACT) ||
233 checker->HasStatus(checker::CheckerStatus::IN_INTERFACE))) {
234 checker->LogTypeError("Non abstract class has abstract method.", node->Start());
235 node->SetTsType(checker->GlobalTypeError());
241 checker->LogTypeError(
244 node->SetTsType(checker->GlobalTypeError());
250 checker->LogTypeError(
253 node->SetTsType(checker->GlobalTypeError());
257 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::Property *expr) const
262 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::SpreadElement *expr) const
264 ETSChecker *checker = GetETSChecker();
265 checker::Type *elementType =
266 expr->AsSpreadElement()->Argument()->AsIdentifier()->Check(checker)->AsETSArrayType()->ElementType();
271 checker::Type *ETSAnalyzer::Check(ir::TemplateElement *expr) const
273 ETSChecker *checker = GetETSChecker();
274 expr->SetTsType(checker->CreateETSStringLiteralType(expr->Raw()));
278 checker::Type *ETSAnalyzer::Check(ir::ETSClassLiteral *expr) const
280 ETSChecker *checker = GetETSChecker();
283 checker->LogTypeError("Class literal is not yet supported.", literal->Start());
284 expr->SetTsType(checker->GlobalTypeError());
287 auto *exprType = literal->Check(checker);
290 checker->LogTypeError("Invalid .class reference", literal->Start());
291 expr->SetTsType(checker->GlobalTypeError());
295 ArenaVector<checker::Type *> typeArgTypes(checker->Allocator()->Adapter());
298 checker::InstantiationContext ctx(checker, checker->GlobalBuiltinTypeType(), std::move(typeArgTypes),
305 checker::Type *ETSAnalyzer::Check(ir::ETSFunctionType *node) const
310 ETSChecker *checker = GetETSChecker();
313 auto *genericInterfaceType = checker->GlobalBuiltinFunctionType(node->Params().size(), node->Flags());
316 auto *tsType = checker->GetCachedFunctionalInterface(node);
322 auto *substitution = checker->NewSubstitution();
326 interfaceType = CreateInterfaceTypeForETSFunctionType(checker, node, genericInterfaceType, substitution);
328 interfaceType = CreateOptionalSignaturesForFunctionalType(checker, node, genericInterfaceType, substitution,
336 checker::Type *ETSAnalyzer::Check(ir::ETSLaunchExpression *expr) const
338 ETSChecker *checker = GetETSChecker();
339 expr->expr_->Check(checker);
341 checker->GlobalBuiltinPromiseType()
342 ->Instantiate(checker->Allocator(), checker->Relation(), checker->GetGlobalTypesHolder())
344 launchPromiseType->AddTypeFlag(checker::TypeFlag::GENERIC);
349 auto exprType = [&checker](auto *tsType) {
350 if (tsType->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) {
351 return checker->PrimitiveTypeAsETSBuiltinType(tsType);
357 checker::Substitution *substitution = checker->NewSubstitution();
359 checker::ETSChecker::EmplaceSubstituted(
362 expr->SetTsType(launchPromiseType->Substitute(checker->Relation(), substitution));
366 checker::Type *ETSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const
368 ETSChecker *checker = GetETSChecker();
370 auto *elementType = expr->TypeReference()->GetType(checker);
371 checker->ValidateArrayIndex(expr->Dimension(), true);
373 if (elementType->IsETSUnionType() && !elementType->AsETSUnionType()->HasNullishType(checker)) {
374 checker->LogTypeError({"Union types in array declaration must include a nullish type."}, expr->Start());
375 expr->SetTsType(checker->GlobalTypeError());
380 const auto flags = checker::ETSObjectFlags::ABSTRACT | checker::ETSObjectFlags::INTERFACE;
384 checker->CollectParameterlessConstructor(calleeObj->ConstructSignatures(), expr->Start()));
385 checker->ValidateSignatureAccessibility(calleeObj, nullptr, expr->Signature(), expr->Start());
387 checker->LogTypeError("Cannot use array creation expression with abstract classes and interfaces.",
389 expr->SetTsType(checker->GlobalTypeError());
394 expr->SetTsType(checker->CreateETSArrayType(elementType));
395 checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), 1);
401 ETSChecker *checker = GetETSChecker();
403 if (calleeObj->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT) && calleeObj->GetDeclNode()->IsFinal()) {
404 checker->LogTypeError({"Class ", calleeObj->Name(), " cannot be both 'abstract' and 'final'."},
406 expr->SetTsType(checker->GlobalTypeError());
410 bool fromInterface = calleeObj->HasObjectFlag(checker::ETSObjectFlags::INTERFACE);
411 auto *classType = checker->BuildAnonymousClassProperties(
412 expr->ClassDefinition(), fromInterface ? checker->GlobalETSObjectType() : calleeObj);
415 calleeObj = checker->GlobalETSObjectType();
418 checker->CheckClassDefinition(expr->ClassDefinition());
419 checker->CheckInnerClassMembers(classType);
421 } else if (calleeObj->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT)) {
422 checker->LogTypeError({calleeObj->Name(), " is abstract therefore cannot be instantiated."}, expr->Start());
423 expr->SetTsType(checker->GlobalTypeError());
428 checker->LogTypeError("Required type can be instantiated only with object literal",
430 expr->SetTsType(checker->GlobalTypeError());
434 checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const
436 ETSChecker *checker = GetETSChecker();
437 auto *calleeType = GetCalleeType(checker, expr);
453 expr->SetSignature(checker->ResolveDynamicCallExpression(expr->GetTypeRef(), expr->GetArguments(), lang, true));
455 auto *signature = checker->ResolveConstructExpression(calleeObj, expr->GetArguments(), expr->Start());
458 expr->SetTsType(checker->GlobalTypeError());
462 checker->CheckObjectLiteralArguments(signature, expr->GetArguments());
464 checker->ValidateSignatureAccessibility(calleeObj, nullptr, signature, expr->Start());
469 checker->CheckThrowingStatements(expr);
476 checker->ResolveDynamicCallExpression(expr->GetTypeRef(), signature->Params(), lang, true));
486 checker::Type *ETSAnalyzer::Check(ir::ETSNewMultiDimArrayInstanceExpression *expr) const
488 ETSChecker *checker = GetETSChecker();
489 auto *elementType = expr->TypeReference()->GetType(checker);
492 checker->ValidateArrayIndex(dim, true);
493 elementType = checker->CreateETSArrayType(elementType);
497 expr->SetSignature(checker->CreateBuiltinArraySignature(elementType->AsETSArrayType(), expr->Dimensions().size()));
501 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSPackageDeclaration *st) const
506 checker::Type *ETSAnalyzer::Check(ir::ETSParameterExpression *expr) const
508 ETSChecker *checker = GetETSChecker();
510 checker::Type *paramType;
515 paramType = !expr->IsRestParameter() ? expr->Ident()->Check(checker) : expr->spread_->Check(checker);
518 [[maybe_unused]] auto *const initType = expr->Initializer()->Check(checker);
528 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSPrimitiveType *node) const
530 ETSChecker *checker = GetETSChecker();
531 return node->GetType(checker);
534 checker::Type *ETSAnalyzer::Check(ir::ETSStructDeclaration *node) const
536 ETSChecker *checker = GetETSChecker();
537 node->Definition()->Check(checker);
541 checker::Type *ETSAnalyzer::Check(ir::ETSTypeReference *node) const
543 ETSChecker *checker = GetETSChecker();
544 return node->GetType(checker);
547 checker::Type *ETSAnalyzer::Check(ir::ETSTypeReferencePart *node) const
549 ETSChecker *checker = GetETSChecker();
550 return node->GetType(checker);
553 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNullType *node) const
558 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSUndefinedType *node) const
563 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSStringLiteralType *node) const
565 ETSChecker *checker = GetETSChecker();
566 return node->GetType(checker);
571 checker::Type *ETSAnalyzer::GetPreferredType(ir::ArrayExpression *expr) const
576 static bool CheckArrayElement(ETSChecker *checker, checker::Type *elementType,
577 std::vector<checker::Type *> targetElementType, ir::Expression *currentElement,
584 (!checker::AssignmentContext(checker->Relation(), currentElement, elementType, targetElementType[0],
592 checker->LogTypeError({"Array element type '", elementType, "' is not assignable to explicit type '",
599 !checker::AssignmentContext(checker->Relation(), currentElement, elementType, targetElementType[1],
605 checker->LogTypeError({"Array element type '", elementType, "' is not assignable to explicit type '",
615 static bool CheckElement(ir::ArrayExpression *expr, ETSChecker *checker, std::vector<checker::Type *> targetElementType,
625 if (!expr->HandleNestedArrayExpression(checker, currentElement->AsArrayExpression(), isPreferredTuple,
636 checker::Type *elementType = currentElement->Check(checker);
643 checker->LogTypeError({"Too many elements in array initializer for tuple with size of ",
650 if (!AssignmentContext(checker->Relation(), currentElement, elementType, compareType,
652 checker->LogTypeError({"Array initializer's type is not assignable to tuple type at index: ", idx},
666 if (!CheckArrayElement(checker, elementType, targetElementType, currentElement, isSecondaryChosen)) {
675 checker::Type *ETSAnalyzer::Check(ir::ArrayExpression *expr) const
677 ETSChecker *checker = GetETSChecker();
683 !checker->Relation()->IsSupertypeOf(expr->preferredType_, checker->GlobalETSObjectType())) {
684 checker->LogTypeError({"Expected type for array literal should be an array type, got ", expr->preferredType_},
686 expr->SetTsType(checker->GlobalTypeError());
694 if (expr->preferredType_ == nullptr || expr->preferredType_ == checker->GlobalETSObjectType()) {
695 expr->preferredType_ = checker->CreateETSArrayType(expr->Elements()[0]->Check(checker));
701 checker->GetNonConstantType(expr->GetPreferredType()->AsETSArrayType()->ElementType());
707 if (!CheckElement(expr, checker, {targetElementType, targetElementTypeSecondary}, isPreferredTuple)) {
708 expr->SetTsType(checker->GlobalTypeError());
714 checker->LogTypeError("Can't resolve array type", expr->Start());
715 expr->SetTsType(checker->GlobalTypeError());
721 checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank());
725 checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const
727 ETSChecker *checker = GetETSChecker();
732 checker::ScopeContext scopeCtx(checker, expr->Function()->Scope());
734 if (checker->HasStatus(checker::CheckerStatus::IN_INSTANCE_EXTENSION_METHOD)) {
749 checker->Context().SetContainingClass(
750 checker->Scope()->Find(varbinder::VarBinder::MANDATORY_PARAM_THIS).variable->TsType()->AsETSObjectType());
753 checker::SavedCheckerContext savedContext(checker, checker->Context().Status(),
754 checker->Context().ContainingClass());
756 checker->AddStatus(checker::CheckerStatus::IN_LAMBDA);
757 checker->Context().SetContainingLambda(expr);
759 checker->BuildFunctionSignature(expr->Function(), false);
761 expr->SetTsType(checker->GlobalTypeError());
766 checker->Context().SetContainingSignature(signature);
767 expr->Function()->Body()->Check(checker);
769 ArenaVector<Signature *> signatures(checker->Allocator()->Adapter());
771 for (auto &sigInfo : checker->ComposeSignatureInfosForArrowFunction(expr)) {
772 auto sig = checker->ComposeSignature(expr->Function(), sigInfo, signature->ReturnType(), nullptr);
777 auto *funcType = checker->CreateETSFunctionType(expr->Function(), std::move(signatures), nullptr);
778 checker->Context().SetContainingSignature(nullptr);
783 retType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType()) {
784 checker->LogTypeError("Return type of async lambda must be 'Promise'", expr->Function()->Start());
785 expr->SetTsType(checker->GlobalTypeError());
794 static bool IsInvalidArrayLengthAssignment(ir::AssignmentExpression *const expr, ETSChecker *checker)
800 checker->LogTypeError("Setting the length of an array is not permitted", expr->Left()->Start());
806 checker::Type *ETSAnalyzer::GetSmartType(ir::AssignmentExpression *expr, checker::Type *leftType,
807 checker::Type *rightType) const
809 ETSChecker *checker = GetETSChecker();
810 checker::Type *smartType = leftType;
813 // Now try to define the actual type of Identifier so that smart cast can be used in further checker processing
814 smartType = checker->ResolveSmartType(rightType, leftType);
824 if (checker->Relation()->IsIdenticalTo(leftType, smartType)) {
825 checker->Context().RemoveSmartCast(variable);
828 checker->Context().SetSmartCast(variable, smartType);
835 checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const
841 ETSChecker *checker = GetETSChecker();
842 auto *const leftType = expr->Left()->Check(checker);
844 if (IsInvalidArrayLengthAssignment(expr, checker)) {
845 expr->SetTsType(checker->GlobalTypeError());
854 checker->LogTypeError("Invalid left-hand side of assignment expression", expr->Left()->Start());
855 expr->SetTsType(checker->GlobalTypeError());
860 checker->ValidateUnaryOperatorOperand(expr->target_);
865 expr->SetTsType(checker->GlobalTypeError());
866 return checker->GlobalTypeError();
869 const checker::Type *targetType = checker->TryGettingFunctionTypeFromInvokeFunction(leftType);
870 const checker::Type *sourceType = checker->TryGettingFunctionTypeFromInvokeFunction(rightType);
872 checker::AssignmentContext(checker->Relation(), relationNode, rightType, leftType, expr->Right()->Start(),
875 checker::Type *smartType = GetSmartType(expr, leftType, rightType);
884 ETSChecker *checker = GetETSChecker();
885 checker::Type *sourceType {};
900 std::tie(std::ignore, expr->operationType_) = checker->CheckBinaryOperator(
903 auto unboxedLeft = checker->ETSBuiltinTypeAsPrimitiveType(leftType);
911 checker->ModifyPreferredType(expr->Right()->AsArrayExpression(), leftType);
918 sourceType = expr->Right()->Check(checker);
930 checker::Type *ETSAnalyzer::Check(ir::AwaitExpression *expr) const
932 ETSChecker *checker = GetETSChecker();
937 checker::Type *argType = checker->GetApparentType(expr->argument_->Check(checker));
940 (argType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType())) {
941 checker->LogTypeError("'await' expressions require Promise object as argument.", expr->Argument()->Start());
942 expr->SetTsType(checker->GlobalTypeError());
951 checker::Type *ETSAnalyzer::UnwrapPromiseType(checker::Type *type) const
953 ETSChecker *checker = GetETSChecker();
954 checker::Type *promiseType = checker->GlobalBuiltinPromiseType();
962 auto it = std::find_if(ctypes.begin(), ctypes.end(), [promiseType](checker::Type *t) {
973 it = std::find_if(it, ctypes.end(), [promiseType](checker::Type *t) {
977 return checker->CreateETSUnionType(std::move(newCTypes));
980 checker::Type *ETSAnalyzer::Check(ir::BinaryExpression *expr) const
986 ETSChecker *checker = GetETSChecker();
987 checker::Type *newTsType {nullptr};
989 checker->CheckBinaryOperator(expr->Left(), expr->Right(), expr, expr->OperatorType(), expr->Start());
992 checker->Context().CheckBinarySmartCastCondition(expr);
997 checker::Type *ETSAnalyzer::Check(ir::BlockExpression *st) const
999 ETSChecker *checker = GetETSChecker();
1000 checker::ScopeContext scopeCtx(checker, st->Scope());
1005 st->Statements()[idx]->Check(checker);
1016 checker::Signature *ETSAnalyzer::ResolveSignature(ETSChecker *checker, ir::CallExpression *expr,
1017 checker::Type *calleeType, bool isFunctionalInterface,
1020 bool extensionFunctionType = expr->Callee()->IsMemberExpression() && checker->ExtensionETSFunctionType(calleeType);
1023 return ResolveCallForETSExtensionFuncHelperType(calleeType->AsETSExtensionFuncHelperType(), checker, expr);
1026 return ResolveCallExtensionFunction(calleeType->AsETSFunctionType(), checker, expr);
1028 auto &signatures = ChooseSignatures(checker, calleeType, expr->IsETSConstructorCall(), isFunctionalInterface,
1039 [](checker::Signature *signature) { return signature->Function()->IsStatic(); }),
1043 checker::Signature *signature = checker->ResolveCallExpressionAndTrailingLambda(signatures, expr, expr->Start());
1049 checker->LogTypeError({"No matching call signature"}, expr->Start());
1055 checker::Type *ETSAnalyzer::GetReturnType(ir::CallExpression *expr, checker::Type *calleeType) const
1057 ETSChecker *checker = GetETSChecker();
1060 return checker->GlobalTypeError();
1066 calleeType->AsETSUnionType()->HasObjectType(checker::ETSObjectFlags::FUNCTIONAL_INTERFACE);
1068 checker::ETSObjectFlags::FUNCTIONAL_INTERFACE);
1072 calleeType = InitAnonymousLambdaCallee(checker, expr->Callee(), calleeType);
1078 checker->LogTypeError({"Type '", calleeType, "' has no call signatures."}, expr->Start());
1079 return checker->GlobalTypeError();
1082 checker::Signature *signature =
1083 ResolveSignature(checker, expr, calleeType, isFunctionalInterface, isUnionTypeWithFunctionalInterface);
1085 return checker->GlobalTypeError();
1088 checker->CheckObjectLiteralArguments(signature, expr->Arguments());
1091 checker::ETSObjectType *calleeObj = ChooseCalleeObj(checker, expr, calleeType, isConstructorCall);
1092 checker->ValidateSignatureAccessibility(calleeObj, expr, signature, expr->Start());
1097 checker->CheckThrowingStatements(expr);
1103 expr->SetSignature(checker->ResolveDynamicCallExpression(expr->Callee(), signature->Params(), lang, false));
1112 returnType = ChooseCalleeObj(checker, expr, calleeType, isConstructorCall);
1118 static void CheckAbstractCall(ETSChecker *checker, ir::CallExpression *expr)
1124 checker->LogTypeError("Cannot call abstract method!", expr->Start());
1125 expr->SetTsType(checker->GlobalTypeError());
1131 static void CheckCallee(ETSChecker *checker, ir::CallExpression *expr)
1133 checker->CheckNonNullish(expr->Callee());
1138 checker->LogTypeError("Cannot call readonly type methods.", expr->Start());
1139 expr->SetTsType(checker->GlobalTypeError());
1143 checker::Type *ETSAnalyzer::GetCallExpressionReturnType(ir::CallExpression *expr, checker::Type *calleeType) const
1145 ETSChecker *checker = GetETSChecker();
1146 checker::Type *returnType = nullptr;
1149 checker->EnsureValidCurlyBrace(expr);
1151 expr->SetSignature(checker->ResolveDynamicCallExpression(expr->Callee(), expr->Arguments(), lang, false));
1158 return checker->GlobalTypeError();
1163 auto *const arrayType = checker->CreateETSArrayType(elementType)->AsETSArrayType();
1164 checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank());
1167 if (expr->Signature()->HasSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE)) {
1168 checker::SavedCheckerContext savedCtx(checker, checker->Context().Status(), expr->Signature()->Owner());
1169 expr->Signature()->OwnerVar()->Declaration()->Node()->Check(checker);
1170 if (expr->Signature()->HasSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE) &&
1172 checker::ScopeContext scopeCtx(checker, expr->Signature()->Function()->Body()->Scope());
1173 checker->CollectReturnStatements(expr->Signature()->Function());
1182 checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const
1184 ETSChecker *checker = GetETSChecker();
1191 checker::Type *calleeType = checker->GetApparentType(expr->Callee()->Check(checker));
1193 expr->SetTsType(checker->GlobalTypeError());
1200 calleeType = checker->GetApparentType(expr->Callee()->Check(checker));
1203 CheckCallee(checker, expr);
1205 checker::Type *returnType = GetCallExpressionReturnType(expr, calleeType);
1212 expr->SetUncheckedType(checker->GuaranteedTypeForUncheckedCallReturn(expr->Signature()));
1214 checker->ComputeApparentType(returnType);
1222 CheckVoidTypeExpression(checker, expr);
1223 CheckAbstractCall(checker, expr);
1227 static void HandleTestedTypes(SmartCastTypes testedTypes, ETSChecker *checker)
1231 checker->ApplySmartCast(variable, consequentType);
1236 checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const
1242 ETSChecker *const checker = GetETSChecker();
1244 SmartCastArray smartCasts = checker->Context().EnterTestExpression();
1245 checker->CheckTruthinessOfType(expr->Test());
1246 SmartCastTypes testedTypes = checker->Context().ExitTestExpression();
1247 HandleTestedTypes(testedTypes, checker);
1250 auto *consequentType = consequent->Check(checker);
1256 SmartCastArray consequentSmartCasts = checker->Context().CloneSmartCasts();
1257 checker->Context().RestoreSmartCasts(smartCasts);
1261 checker->ApplySmartCast(variable, alternateType);
1266 auto *alternateType = alternate->Check(checker);
1274 checker->Context().CombineSmartCasts(consequentSmartCasts);
1276 if (checker->IsTypeIdenticalTo(consequentType, alternateType)) {
1277 expr->SetTsType(checker->GetNonConstantType(consequentType));
1281 checker->AdjustNumberLiteralType(alternate->AsNumberLiteral(), alternateType, consequentType)) {
1284 checker->AdjustNumberLiteralType(consequent->AsNumberLiteral(), consequentType, alternateType)) {
1287 expr->SetTsType(checker->CreateETSUnionType({consequentType, alternateType}));
1289 checker->MaybeBoxExpression(expr->Consequent());
1290 checker->MaybeBoxExpression(expr->Alternate());
1298 checker::Type *ETSAnalyzer::Check(ir::Identifier *expr) const
1301 ETSChecker *checker = GetETSChecker();
1303 auto *identType = checker->ResolveIdentifier(expr);
1306 if (auto *const smartType = checker->Context().GetSmartCast(expr->Variable()); smartType != nullptr) {
1312 checker->Context().CheckIdentifierSmartCastCondition(expr);
1317 std::pair<checker::Type *, util::StringView> SearchReExportsType(ETSObjectType *baseType, ir::MemberExpression *expr,
1318 util::StringView &aliasName, ETSChecker *checker)
1330 checker->LogTypeError({"Ambiguous reference to '", aliasName, "'"}, expr->Start());
1331 expr->SetTsType(checker->GlobalTypeError());
1337 if (auto reExportType = SearchReExportsType(item, expr, name, checker); reExportType.first != nullptr) {
1345 static void TypeErrorOnMissingProperty(ir::MemberExpression *expr, checker::Type *baseType,
1346 checker::ETSChecker *checker)
1348 checker->LogTypeError(
1351 expr->SetTsType(checker->GlobalTypeError());
1354 checker::Type *ETSAnalyzer::Check(ir::MemberExpression *expr) const
1361 ETSChecker *checker = GetETSChecker();
1362 auto *baseType = checker->GetNonConstantType(checker->GetApparentType(expr->Object()->Check(checker)));
1373 expr->Property()->AsIdentifier()->Name(), checker);
1381 if (!checker->CheckNonNullish(expr->Object())) {
1382 expr->SetTsType(checker->GlobalTypeError());
1387 return expr->AdjustType(checker, expr->CheckComputed(checker, baseType));
1392 return expr->AdjustType(checker, checker->GlobalIntType());
1395 return expr->SetAndAdjustType(checker, checker->GlobalETSObjectType());
1399 return expr->SetAndAdjustType(checker, baseType->AsETSObjectType());
1403 auto [memberType, memberVar] = expr->ResolveEnumMember(checker, baseType);
1405 expr->Property()->SetTsType(memberType == nullptr ? checker->GlobalTypeError() : memberType);
1406 return expr->AdjustType(checker, expr->Property()->TsTypeOrError());
1410 return expr->AdjustType(checker, expr->CheckUnionMember(checker, baseType));
1412 TypeErrorOnMissingProperty(expr, baseType, checker);
1416 checker::Type *ETSAnalyzer::PreferredType(ir::ObjectExpression *expr) const
1421 static bool ValidatePreferredType(ir::ObjectExpression *expr, ETSChecker *checker)
1425 checker->LogTypeError({"need to specify target type for class composite"}, expr->Start());
1430 checker->LogTypeError(
1438 checker::Type *ETSAnalyzer::Check(ir::ObjectExpression *expr) const
1440 ETSChecker *checker = GetETSChecker();
1445 if (!ValidatePreferredType(expr, checker)) {
1446 expr->SetTsType(checker->GlobalTypeError());
1455 value->Check(checker);
1463 checker::ETSObjectType *objType = expr->PreferredType()->AsETSObjectType();
1464 if (objType->HasObjectFlag(checker::ETSObjectFlags::INTERFACE)) {
1468 // Here we just set the type to pass the checker
1469 CheckObjectExprProps(expr, checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD |
1470 checker::PropertySearchFlags::SEARCH_IN_INTERFACES);
1475 if (objType->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT)) {
1476 checker->LogTypeError({"target type for class composite ", objType->Name(), " is not instantiable"},
1478 expr->SetTsType(checker->GlobalTypeError());
1486 // Here we just set the type to pass the checker
1493 for (checker::Signature *sig : objType->ConstructSignatures()) {
1496 checker->ValidateSignatureAccessibility(objType, nullptr, sig, expr->Start());
1501 checker->LogTypeError({"type ", objType->Name(), " has no parameterless constructor"}, expr->Start());
1502 expr->SetTsType(checker->GlobalTypeError());
1506 CheckObjectExprProps(expr, checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD |
1507 checker::PropertySearchFlags::SEARCH_IN_BASE |
1508 checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD);
1514 void ETSAnalyzer::CheckObjectExprProps(const ir::ObjectExpression *expr, checker::PropertySearchFlags searchFlags) const
1516 ETSChecker *checker = GetETSChecker();
1517 checker::ETSObjectType *objType = expr->PreferredType()->AsETSObjectType();
1531 checker->LogTypeError({"key in class composite should be either identifier or string literal"},
1537 checker->LogTypeError({"type ", objType->Name(), " has no property named ", pname}, propExpr->Start());
1540 checker->ValidatePropertyAccess(lv, objType, propExpr->Start());
1546 auto *propType = checker->GetTypeOfVariable(lv);
1552 value->SetTsType(value->Check(checker));
1555 const checker::Type *sourceType = checker->TryGettingFunctionTypeFromInvokeFunction(valueType);
1556 const checker::Type *targetType = checker->TryGettingFunctionTypeFromInvokeFunction(propType);
1558 checker::AssignmentContext(
1559 checker->Relation(), value, valueType, propType, value->Start(),
1564 checker->ValidateObjectLiteralForRequiredType(objType, expr);
1568 checker::Type *ETSAnalyzer::Check(ir::OpaqueTypeNode *expr) const
1573 checker::Type *ETSAnalyzer::Check(ir::SequenceExpression *expr) const
1575 ETSChecker *checker = GetETSChecker();
1581 it->Check(checker);
1588 checker::Type *ETSAnalyzer::Check(ir::SuperExpression *expr) const
1590 ETSChecker *checker = GetETSChecker();
1595 expr->SetTsType(checker->CheckThisOrSuperAccess(expr, checker->Context().ContainingClass()->SuperType(), "super"));
1599 checker::Type *ETSAnalyzer::Check(ir::TemplateLiteral *expr) const
1601 ETSChecker *checker = GetETSChecker();
1607 checker->LogTypeError("Invalid string template expression", expr->Start());
1608 expr->SetTsType(checker->GlobalTypeError());
1613 it->Check(checker);
1617 it->Check(checker);
1620 expr->SetTsType(checker->GlobalBuiltinETSStringType());
1624 checker::Type *ETSAnalyzer::Check(ir::ThisExpression *expr) const
1626 ETSChecker *checker = GetETSChecker();
1652 auto *variable = checker->AsETSChecker()->Scope()->Find(varbinder::VarBinder::MANDATORY_PARAM_THIS).variable;
1653 if (checker->HasStatus(checker::CheckerStatus::IN_INSTANCE_EXTENSION_METHOD)) {
1657 expr->SetTsType(checker->CheckThisOrSuperAccess(expr, checker->Context().ContainingClass(), "this"));
1664 static checker::Type *GetTypeOfStringType(checker::Type *argType, ETSChecker *checker)
1666 if (auto unboxed = checker->MaybePrimitiveBuiltinType(argType);
1667 unboxed->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) {
1668 switch (checker->TypeKind(unboxed)) {
1670 return checker->CreateETSStringLiteralType("boolean");
1679 return checker->CreateETSStringLiteralType("number");
1686 return checker->CreateETSStringLiteralType(util::StringView("undefined"));
1689 return checker->CreateETSStringLiteralType(util::StringView("object"));
1692 return checker->CreateETSStringLiteralType(util::StringView("number"));
1695 return checker->CreateETSStringLiteralType(util::StringView("string"));
1698 return checker->CreateETSStringLiteralType(util::StringView("bigint"));
1701 return checker->CreateETSStringLiteralType(util::StringView("function"));
1704 return checker->GlobalBuiltinETSStringType();
1707 static checker::Type *ComputeTypeOfType(ETSChecker *checker, checker::Type *argType)
1709 checker::Type *ret = nullptr;
1710 ArenaVector<checker::Type *> types(checker->Allocator()->Adapter());
1713 checker::Type *elType = ComputeTypeOfType(checker, it);
1716 ret = checker->CreateETSUnionType(std::move(types));
1718 ret = GetTypeOfStringType(argType, checker);
1723 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TypeofExpression *expr) const
1725 ETSChecker *checker = GetETSChecker();
1730 expr->Argument()->Check(checker);
1731 expr->SetTsType(ComputeTypeOfType(checker, expr->Argument()->TsType()));
1735 checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const
1737 ETSChecker *checker = GetETSChecker();
1743 auto argType = expr->argument_->Check(checker);
1745 checker::Type *operandType = checker->ApplyUnaryOperatorPromotion(argType, true, true, isCondExpr);
1746 auto unboxedOperandType = isCondExpr ? checker->ETSBuiltinTypeAsConditionalType(argType)
1747 : checker->ETSBuiltinTypeAsPrimitiveType(argType);
1749 if (argType != nullptr && argType->IsETSBigIntType() && argType->HasTypeFlag(checker::TypeFlag::BIGINT_LITERAL)) {
1752 checker::Type *type = checker->CreateETSBigIntLiteralType(argType->AsETSBigIntType()->GetValue());
1755 type->RemoveTypeFlag(checker::TypeFlag::CONSTANT);
1783 SetTsTypeForUnaryExpression(checker, expr, operandType);
1786 unboxedOperandType->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) {
1787 expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedOperandType));
1790 checker->Context().CheckUnarySmartCastCondition(expr);
1795 checker::Type *ETSAnalyzer::Check(ir::UpdateExpression *expr) const
1797 ETSChecker *checker = GetETSChecker();
1802 checker::Type *operandType = expr->argument_->Check(checker);
1804 checker->ValidateUnaryOperatorOperand(expr->Argument()->AsIdentifier()->Variable());
1807 checker->ValidateUnaryOperatorOperand(asExprVar);
1812 checker->ValidateUnaryOperatorOperand(nonNullExprVar);
1818 checker->ValidateUnaryOperatorOperand(propVar);
1827 auto unboxedType = checker->ETSBuiltinTypeAsPrimitiveType(operandType);
1828 if (unboxedType == nullptr || !unboxedType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) {
1829 checker->LogTypeError("Bad operand type, the type of the operand must be numeric type.",
1831 expr->SetTsType(checker->GlobalTypeError());
1836 expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedType) |
1837 checker->GetBoxingFlag(unboxedType));
1845 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::BigIntLiteral *expr) const
1847 ETSChecker *checker = GetETSChecker();
1848 expr->SetTsType(checker->CreateETSBigIntLiteralType(expr->Str()));
1852 checker::Type *ETSAnalyzer::Check(ir::BooleanLiteral *expr) const
1854 ETSChecker *checker = GetETSChecker();
1856 expr->SetTsType(checker->CreateETSBooleanType(expr->Value()));
1861 checker::Type *ETSAnalyzer::Check(ir::CharLiteral *expr) const
1863 ETSChecker *checker = GetETSChecker();
1865 expr->SetTsType(checker->Allocator()->New<checker::CharType>(expr->Char()));
1870 checker::Type *ETSAnalyzer::Check(ir::NullLiteral *expr) const
1872 ETSChecker *checker = GetETSChecker();
1874 expr->SetTsType(checker->GlobalETSNullType());
1879 checker::Type *ETSAnalyzer::Check(ir::NamespaceDeclaration *st) const
1881 ETSChecker *checker = GetETSChecker();
1882 st->Definition()->Check(checker);
1886 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::NamespaceDefinition *st) const
1891 checker::Type *ETSAnalyzer::Check(ir::NumberLiteral *expr) const
1893 ETSChecker *checker = GetETSChecker();
1895 expr->SetTsType(checker->CreateIntType(expr->Number().GetInt()));
1900 expr->SetTsType(checker->CreateLongType(expr->Number().GetLong()));
1905 expr->SetTsType(checker->CreateFloatType(expr->Number().GetFloat()));
1909 expr->SetTsType(checker->CreateDoubleType(expr->Number().GetDouble()));
1913 checker::Type *ETSAnalyzer::Check(ir::StringLiteral *expr) const
1915 ETSChecker *checker = GetETSChecker();
1917 expr->SetTsType(checker->CreateETSStringLiteralType(expr->Str()));
1922 checker::Type *ETSAnalyzer::Check(ir::ImportDeclaration *st) const
1924 ETSChecker *checker = GetETSChecker();
1925 checker::Type *type = nullptr;
1928 type = spec->AsImportNamespaceSpecifier()->Check(checker);
1935 checker::Type *ETSAnalyzer::Check(ir::ImportNamespaceSpecifier *st) const
1937 ETSChecker *checker = GetETSChecker();
1949 auto *type = checker->GlobalBuiltinDynamicType(importDecl->Language());
1950 checker->SetrModuleObjectTsType(st->Local(), type);
1954 return checker->GetImportSpecifierObjectType(importDecl, st->Local()->AsIdentifier());
1958 checker::Type *ETSAnalyzer::Check(ir::AssertStatement *st) const
1960 ETSChecker *checker = GetETSChecker();
1961 if (!(st->Test()->Check(checker)->HasTypeFlag(TypeFlag::ETS_BOOLEAN | TypeFlag::BOOLEAN_LIKE) ||
1962 st->Test()->Check(checker)->ToString() == "Boolean")) {
1963 checker->LogTypeError("Bad operand type, the type of the operand must be boolean type.", st->Test()->Start());
1967 auto *msgType = st->second_->Check(checker);
1970 checker->LogTypeError("Assert message must be string", st->Second()->Start());
1977 checker::Type *ETSAnalyzer::Check(ir::BlockStatement *st) const
1979 ETSChecker *checker = GetETSChecker();
1980 checker::ScopeContext scopeCtx(checker, st->Scope());
1987 stmt->Check(checker);
1992 trailingBlock->Check(checker);
1997 if (UNLIKELY(checker->GetDebugInfoPlugin() != nullptr)) {
2000 checker->GetDebugInfoPlugin()->AddPrologueEpilogue(st);
2007 checker->Context().ClearSmartCasts();
2012 checker->Context().RemoveSmartCast(decl->Node()->AsIdentifier()->Variable());
2020 checker::Type *ETSAnalyzer::Check(ir::BreakStatement *st) const
2022 ETSChecker *checker = GetETSChecker();
2023 auto node = checker->FindJumpTarget(st);
2025 return checker->GlobalTypeError();
2029 checker->Context().OnBreakStatement(st);
2033 checker::Type *ETSAnalyzer::Check(ir::ClassDeclaration *st) const
2035 ETSChecker *checker = GetETSChecker();
2036 st->Definition()->Check(checker);
2040 checker::Type *ETSAnalyzer::Check(ir::ContinueStatement *st) const
2042 ETSChecker *checker = GetETSChecker();
2043 auto node = checker->FindJumpTarget(st);
2045 return checker->GlobalTypeError();
2049 checker->AddStatus(CheckerStatus::MEET_CONTINUE);
2053 checker::Type *ETSAnalyzer::Check(ir::DoWhileStatement *st) const
2055 ETSChecker *checker = GetETSChecker();
2056 checker::ScopeContext scopeCtx(checker, st->Scope());
2059 auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st);
2061 checker->CheckTruthinessOfType(st->Test());
2062 st->Body()->Check(checker);
2064 checker->Context().ExitLoop(smartCasts, clearFlag, st);
2068 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::EmptyStatement *st) const
2073 checker::Type *ETSAnalyzer::Check(ir::ExpressionStatement *st) const
2075 ETSChecker *checker = GetETSChecker();
2076 return st->GetExpression()->Check(checker);
2079 static bool ValidateAndProcessIteratorType(ETSChecker *checker, Type *elemType, ir::ForOfStatement *const st)
2081 checker::Type *iterType = GetIteratorType(checker, elemType, st->Left());
2085 auto *const relation = checker->Relation();
2086 relation->SetFlags(checker::TypeRelationFlag::ASSIGNMENT_CONTEXT);
2095 checker->LogTypeError(ss.str(), st->Start());
2100 relation->SetFlags(checker::TypeRelationFlag::NONE);
2105 checker->AddBoxingUnboxingFlagsToNode(declarator->Id(), iterType);
2117 checker::Type *ETSAnalyzer::Check(ir::ForOfStatement *const st) const
2119 ETSChecker *checker = GetETSChecker();
2120 checker::ScopeContext scopeCtx(checker, st->Scope());
2123 auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st);
2125 checker::Type *const exprType = st->Right()->Check(checker);
2127 checker->LogTypeError(MISSING_SOURCE_EXPR_TYPE, st->Right()->Start());
2128 return checker->GlobalTypeError();
2131 checker::Type *elemType = nullptr;
2134 elemType = checker->GetGlobalTypesHolder()->GlobalCharType();
2136 elemType = exprType->AsETSArrayType()->ElementType()->Instantiate(checker->Allocator(), checker->Relation(),
2137 checker->GetGlobalTypesHolder());
2139 elemType->RemoveTypeFlag(checker::TypeFlag::CONSTANT);
2142 elemType = st->CheckIteratorMethod(checker);
2146 checker->LogTypeError(INVALID_SOURCE_EXPR_TYPE, st->Right()->Start());
2147 return checker->GlobalTypeError();
2150 st->Left()->Check(checker);
2152 if (!ValidateAndProcessIteratorType(checker, elemType, st)) {
2153 return checker->GlobalTypeError();
2156 st->Body()->Check(checker);
2158 checker->Context().ExitLoop(smartCasts, clearFlag, st);
2162 checker::Type *ETSAnalyzer::Check(ir::ForUpdateStatement *st) const
2164 ETSChecker *checker = GetETSChecker();
2165 checker::ScopeContext scopeCtx(checker, st->Scope());
2168 auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st);
2171 st->Init()->Check(checker);
2175 checker->CheckTruthinessOfType(st->Test());
2179 st->Update()->Check(checker);
2182 st->Body()->Check(checker);
2184 checker->Context().ExitLoop(smartCasts, clearFlag, st);
2188 checker::Type *ETSAnalyzer::Check(ir::IfStatement *st) const
2190 ETSChecker *const checker = GetETSChecker();
2192 SmartCastArray smartCasts = checker->Context().EnterTestExpression();
2193 checker->CheckTruthinessOfType(st->Test());
2194 SmartCastTypes testedTypes = checker->Context().ExitTestExpression();
2197 checker->ApplySmartCast(variable, consequentType);
2201 checker->Context().EnterPath();
2202 st->Consequent()->Check(checker);
2203 bool const consequentTerminated = checker->Context().ExitPath();
2204 SmartCastArray consequentSmartCasts = checker->Context().CloneSmartCasts();
2207 checker->Context().RestoreSmartCasts(smartCasts);
2211 checker->ApplySmartCast(variable, alternateType);
2216 checker->Context().EnterPath();
2217 st->Alternate()->Check(checker);
2218 bool const alternateTerminated = checker->Context().ExitPath();
2222 checker->Context().RestoreSmartCasts(consequentSmartCasts);
2225 checker->Context().RestoreSmartCasts(smartCasts);
2229 checker->Context().CombineSmartCasts(consequentSmartCasts);
2234 checker->Context().CombineSmartCasts(consequentSmartCasts);
2241 checker::Type *ETSAnalyzer::Check(ir::LabelledStatement *st) const
2243 ETSChecker *checker = GetETSChecker();
2244 st->body_->Check(checker);
2249 checker::Type *&funcReturnType, ir::TypeNode *returnTypeAnnotation,
2250 ETSChecker *checker) const
2252 funcReturnType = returnTypeAnnotation->GetType(checker);
2254 checker->LogTypeError("The only allowed return value is 'this' if the method's return type is the 'this' type",
2262 if (!funcReturnType->IsETSVoidType() && funcReturnType != checker->GlobalVoidType() &&
2264 checker->LogTypeError("Missing return value.", st->Start());
2267 funcReturnType = checker->GlobalVoidType();
2270 if (!CheckArgumentVoidType(funcReturnType, checker, name, st)) {
2278 checker->SetArrayPreferredTypeForNestedMemberExpressions(st->argument_->AsMemberExpression(),
2286 checker::Type *argumentType = st->argument_->Check(checker);
2287 return CheckReturnType(checker, funcReturnType, argumentType, st->argument_, containingFunc->IsAsyncFunc());
2292 checker::Type *ETSAnalyzer::GetFunctionReturnType(ir::ReturnStatement *st, ir::ScriptFunction *containingFunc) const
2296 ETSChecker *checker = GetETSChecker();
2297 checker::Type *funcReturnType = nullptr;
2300 if (!CheckInferredFunctionReturnType(st, containingFunc, funcReturnType, returnTypeAnnotation, checker)) {
2301 return checker->GlobalTypeError();
2305 if (containingFunc->Signature()->HasSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE)) {
2306 InferReturnType(checker, containingFunc, funcReturnType,
2311 ProcessReturnStatements(checker, containingFunc, funcReturnType, st,
2317 checker->ModifyPreferredType(st->argument_->AsArrayExpression(), funcReturnType);
2318 st->argument_->Check(checker);
2324 checker::Type *ETSAnalyzer::Check(ir::ReturnStatement *st) const
2326 ETSChecker *checker = GetETSChecker();
2332 checker->AddStatus(CheckerStatus::MEET_RETURN);
2336 checker->LogTypeError("Return statement with expression isn't allowed in constructor.", st->Start());
2337 return checker->GlobalTypeError();
2351 checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const
2353 ETSChecker *checker = GetETSChecker();
2354 checker::ScopeContext scopeCtx(checker, st->Scope());
2355 checker::SavedTypeRelationFlagsContext savedTypeRelationFlagCtx(checker->Relation(),
2356 checker::TypeRelationFlag::NONE);
2358 auto *comparedExprType = checker->CheckSwitchDiscriminant(st->Discriminant());
2360 ? checker->ETSBuiltinTypeAsPrimitiveType(comparedExprType)
2363 SmartCastArray smartCasts = checker->Context().CloneSmartCasts();
2367 checker->Context().EnterPath();
2368 it->CheckAndTestCase(checker, comparedExprType, unboxedDiscType, st->Discriminant(), hasDefaultCase);
2369 bool const caseTerminated = checker->Context().ExitPath();
2373 checker->Context().CombineSmartCasts(smartCasts);
2375 checker->Context().RestoreSmartCasts(smartCasts);
2381 checker->Context().AddBreakSmartCasts(st, checker->Context().CloneSmartCasts());
2383 checker->Context().ClearSmartCasts();
2389 checker->Context().AddBreakSmartCasts(st, std::move(smartCasts));
2393 checker->Context().CombineBreakSmartCasts(st);
2395 checker->CheckForSameSwitchCases(st->Cases());
2399 checker::Type *ETSAnalyzer::Check(ir::ThrowStatement *st) const
2401 ETSChecker *checker = GetETSChecker();
2402 auto *argType = st->argument_->Check(checker);
2403 checker->CheckExceptionOrErrorType(argType, st->Start());
2405 if (checker->Relation()->IsAssignableTo(argType, checker->GlobalBuiltinExceptionType())) {
2406 checker->CheckThrowingStatements(st);
2409 checker->AddStatus(CheckerStatus::MEET_THROW);
2413 checker::Type *ETSAnalyzer::Check(ir::TryStatement *st) const
2415 ETSChecker *checker = GetETSChecker();
2416 std::vector<checker::ETSObjectType *> exceptions {};
2419 auto smartCasts = checker->Context().CheckTryBlock(*st->Block());
2420 st->Block()->Check(checker);
2425 checker->LogTypeError("Default catch clause should be the last in the try statement", catchClause->Start());
2426 return checker->GlobalTypeError();
2429 checker->Context().RestoreSmartCasts(smartCasts);
2431 if (auto const exceptionType = catchClause->Check(checker);
2434 checker->CheckExceptionClauseType(exceptions, catchClause, clauseType);
2440 casts.emplace_back(checker->Context().CloneSmartCasts());
2443 checker->Context().RestoreSmartCasts(smartCasts);
2446 checker->Context().CombineSmartCasts(cast);
2451 st->FinallyBlock()->Check(checker);
2457 checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const
2463 ETSChecker *checker = GetETSChecker();
2477 auto *const variableType = checker->CheckVariableDeclaration(ident, ident->TypeAnnotation(), st->Init(), flags);
2480 // Now try to define the actual type of Identifier so that smart cast can be used in further checker processing
2483 smartType = checker->ResolveSmartType(initType, variableType);
2486 if (!checker->Relation()->IsIdenticalTo(variableType, smartType)) {
2488 checker->Context().SetSmartCast(ident->Variable(), smartType);
2496 checker::Type *ETSAnalyzer::Check(ir::VariableDeclaration *st) const
2498 ETSChecker *checker = GetETSChecker();
2500 it->Check(checker);
2506 checker::Type *ETSAnalyzer::Check(ir::WhileStatement *st) const
2508 ETSChecker *checker = GetETSChecker();
2509 checker::ScopeContext scopeCtx(checker, st->Scope());
2512 auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st);
2514 checker->CheckTruthinessOfType(st->Test());
2515 st->Body()->Check(checker);
2517 checker->Context().ExitLoop(smartCasts, clearFlag, st);
2521 checker::Type *ETSAnalyzer::Check(ir::TSArrayType *node) const
2523 ETSChecker *checker = GetETSChecker();
2524 node->elementType_->Check(checker);
2525 node->SetTsType(node->GetType(checker));
2528 checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank());
2532 checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const
2534 ETSChecker *checker = GetETSChecker();
2540 auto *const targetType = expr->TypeAnnotation()->AsTypeNode()->GetType(checker);
2551 auto *const sourceType = expr->Expr()->Check(checker);
2553 expr->SetTsType(checker->GlobalTypeError());
2557 if (targetType->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE) && sourceType->IsETSReferenceType()) {
2558 auto *const boxedTargetType = checker->PrimitiveTypeAsETSBuiltinType(targetType);
2559 if (!checker->Relation()->IsIdenticalTo(sourceType, boxedTargetType)) {
2565 checker->LogTypeError("Cannot cast 'null' or 'undefined' to non-nullish type.", expr->Expr()->Start());
2566 expr->SetTsType(checker->GlobalTypeError());
2570 const checker::CastingContext ctx(
2571 checker->Relation(),
2573 checker::CastingContext::ConstructorData {expr->Expr(), sourceType, targetType, expr->Expr()->Start()});
2578 checker->BuildLambdaObjectClass(targetType->AsETSObjectType(),
2587 checker->CreateBuiltinArraySignature(targetArrayType, targetArrayType->Rank());
2590 if (targetType == checker->GetGlobalTypesHolder()->GlobalBuiltinNeverType()) {
2591 checker->LogTypeError("Cast to 'never' is prohibited", expr->Start());
2592 expr->SetTsType(checker->GlobalTypeError());
2596 checker->ComputeApparentType(targetType);
2601 checker::Type *ETSAnalyzer::Check(ir::TSEnumDeclaration *st) const
2603 ETSChecker *checker = GetETSChecker();
2608 checker::Type *etsEnumType = nullptr;
2611 etsEnumType = checker->CreateEnumIntTypeFromEnumDeclaration(st);
2613 etsEnumType = checker->CreateEnumStringTypeFromEnumDeclaration(st);
2615 checker->LogTypeError("Invalid enumeration value type.", st->Start());
2616 st->SetTsType(checker->GlobalTypeError());
2629 checker::Type *ETSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const
2631 ETSChecker *checker = GetETSChecker();
2633 checker::ETSObjectType *interfaceType {};
2639 interfaceType = checker->BuildBasicInterfaceProperties(st);
2641 interfaceType->SetSuperType(checker->GlobalETSObjectType());
2642 checker->CheckInvokeMethodsLegitimacy(interfaceType);
2645 checker::ScopeContext scopeCtx(checker, st->Scope());
2646 auto savedContext = checker::SavedCheckerContext(checker, checker::CheckerStatus::IN_INTERFACE, interfaceType);
2649 it->Check(checker);
2655 checker::Type *ETSAnalyzer::Check(ir::TSNonNullExpression *expr) const
2658 ETSChecker *checker = GetETSChecker();
2659 auto exprType = expr->expr_->Check(checker);
2663 checker->LogTypeError(
2666 expr->SetTsType(checker->GlobalTypeError());
2669 expr->SetTsType(checker->GetNonNullishType(exprType));
2675 checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const
2677 ETSChecker *checker = GetETSChecker();
2678 checker::Type *baseType = expr->Left()->Check(checker);
2685 ? checker->VarBinder()->AsETSBinder()->FindNameInAliasMap(
2694 baseType->AsETSObjectType()->GetProperty(searchName, checker::PropertySearchFlags::SEARCH_DECL);
2698 checker->LogTypeError({"'", expr->Right()->Name(), "' type does not exist."}, expr->Right()->Start());
2699 return checker->GlobalTypeError();
2703 checker->LogTypeError({"Cannot find imported element '", searchName, "' exported with alias"},
2705 return checker->GlobalTypeError();
2709 return checker->GetTypeOfVariable(prop);
2712 checker->LogTypeError({"'", expr->Right()->Name(), "' type does not exist."}, expr->Right()->Start());
2713 return checker->GlobalTypeError();
2716 checker::Type *ETSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const
2718 ETSChecker *checker = GetETSChecker();
2720 const checker::SavedTypeRelationFlagsContext savedFlagsCtx(
2721 checker->Relation(), checker::TypeRelationFlag::NO_THROW_GENERIC_TYPEALIAS);
2724 st->TypeAnnotation()->Check(checker);
2731 auto [typeParamTypes, ok] = checker->CreateUnconstrainedTypeParameters(st->TypeParams());
2734 checker->AssignTypeParameterConstraints(st->TypeParams());
2748 checker->LogTypeError(
2751 return checker->GlobalTypeError();
2755 const checker::SavedTypeRelationFlagsContext savedFlagsCtx(checker->Relation(),
2756 checker::TypeRelationFlag::NO_THROW_GENERIC_TYPEALIAS);
2759 st->TypeAnnotation()->Check(checker);
2764 } // namespace ark::es2panda::checker