• Home
  • Raw
  • Download

Lines Matching +full:checker +full:-

2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
7 * http://www.apache.org/licenses/LICENSE-2.0
19 #include "checker/ETSchecker.h"
20 #include "checker/ets/castingContext.h"
21 #include "checker/ets/typeRelationContext.h"
22 #include "checker/types/globalTypesHolder.h"
23 #include "checker/types/ets/etsTupleType.h"
24 #include "checker/types/ets/etsAsyncFuncReturnType.h"
28 namespace ark::es2panda::checker { namespace
36 checker::Type *ETSAnalyzer::Check(ir::CatchClause *st) const in Check()
38 ETSChecker *checker = GetETSChecker(); in Check() local
39 checker::ETSObjectType *exceptionType = checker->GlobalETSObjectType(); in Check()
41 ir::Identifier *paramIdent = st->Param()->AsIdentifier(); in Check()
43 if (paramIdent->TypeAnnotation() != nullptr) { in Check()
44 checker::Type *catchParamAnnotationType = paramIdent->TypeAnnotation()->GetType(checker); in Check()
46 …exceptionType = checker->CheckExceptionOrErrorType(catchParamAnnotationType, st->Param()->Start()); in Check()
49 paramIdent->Variable()->SetTsType(exceptionType); in Check()
51 st->Body()->Check(checker); in Check()
53 st->SetTsType(exceptionType); in Check()
57 checker::Type *ETSAnalyzer::Check(ir::ClassDefinition *node) const in Check()
59 ETSChecker *checker = GetETSChecker(); in Check() local
61 if (node->TsType() == nullptr) { in Check()
62 checker->BuildBasicClassProperties(node); in Check()
65 if (!node->IsClassDefinitionChecked()) { in Check()
66 checker->CheckClassDefinition(node); in Check()
69 return node->TsType(); in Check()
72 checker::Type *ETSAnalyzer::Check(ir::ClassProperty *st) const in Check()
74 ASSERT(st->Id() != nullptr); in Check()
75 ETSChecker *checker = GetETSChecker(); in Check() local
77 if (st->TsType() != nullptr) { in Check()
78 return st->TsType(); in Check()
81 checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), in Check()
82 checker->Context().ContainingClass(), in Check()
83 checker->Context().ContainingSignature()); in Check()
85 if (st->IsStatic()) { in Check()
86 checker->AddStatus(checker::CheckerStatus::IN_STATIC_CONTEXT); in Check()
89 …st->SetTsType(checker->CheckVariableDeclaration(st->Id(), st->TypeAnnotation(), st->Value(), st->M… in Check()
91 return st->TsType(); in Check()
94 checker::Type *ETSAnalyzer::Check(ir::ClassStaticBlock *st) const in Check()
96 ETSChecker *checker = GetETSChecker(); in Check() local
98 if (checker->HasStatus(checker::CheckerStatus::INNER_CLASS)) { in Check()
99 checker->LogTypeError("Static initializer is not allowed in inner class.", st->Start()); in Check()
100 st->SetTsType(checker->GlobalTypeError()); in Check()
101 return st->TsType(); in Check()
104 auto *func = st->Function(); in Check()
105 checker->BuildFunctionSignature(func); in Check()
106 if (func->Signature() == nullptr) { in Check()
107 return checker->InvalidateType(st->AsTyped()); in Check()
109 st->SetTsType(checker->BuildNamedFunctionType(func)); in Check()
110 checker::ScopeContext scopeCtx(checker, func->Scope()); in Check()
111 checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), in Check()
112 checker->Context().ContainingClass()); in Check()
113checker->AddStatus(checker::CheckerStatus::IN_STATIC_BLOCK | checker::CheckerStatus::IN_STATIC_CON… in Check()
114 func->Body()->Check(checker); in Check()
115 return st->TsType(); in Check()
118 // Satisfy the Chinese code checker
119 static void HandleNativeAndAsyncMethods(ETSChecker *checker, ir::MethodDefinition *node) in HandleNativeAndAsyncMethods() argument
121 auto *scriptFunc = node->Function(); in HandleNativeAndAsyncMethods()
122 if (node->IsNative()) { in HandleNativeAndAsyncMethods()
123 if (scriptFunc->ReturnTypeAnnotation() == nullptr) { in HandleNativeAndAsyncMethods()
124checker->LogTypeError("'Native' method should have explicit return type", scriptFunc->Start()); in HandleNativeAndAsyncMethods()
125 node->SetTsType(checker->GlobalTypeError()); in HandleNativeAndAsyncMethods()
127 ASSERT(!scriptFunc->IsGetter() && !scriptFunc->IsSetter()); in HandleNativeAndAsyncMethods()
131 if (scriptFunc->ReturnTypeAnnotation() != nullptr) { in HandleNativeAndAsyncMethods()
132 auto *asyncFuncReturnType = scriptFunc->Signature()->ReturnType(); in HandleNativeAndAsyncMethods()
134 if (!asyncFuncReturnType->IsETSObjectType() || in HandleNativeAndAsyncMethods()
135 …asyncFuncReturnType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType… in HandleNativeAndAsyncMethods()
136checker->LogTypeError("Return type of async function must be 'Promise'.", scriptFunc->Start()); in HandleNativeAndAsyncMethods()
137 scriptFunc->Signature()->SetReturnType(checker->GlobalTypeError()); in HandleNativeAndAsyncMethods()
142 if (node->Function()->HasBody()) { in HandleNativeAndAsyncMethods()
143 ComposeAsyncImplMethod(checker, node); in HandleNativeAndAsyncMethods()
147 void ETSAnalyzer::CheckClassProperty(ETSChecker *checker, ir::ScriptFunction *scriptFunc) const in CheckClassProperty() argument
149 if (checker->CheckDuplicateAnnotations(scriptFunc->Annotations())) { in CheckClassProperty()
150 for (auto *it : scriptFunc->Annotations()) { in CheckClassProperty()
151 it->Check(checker); in CheckClassProperty()
156 checker::Type *ETSAnalyzer::Check(ir::MethodDefinition *node) const in Check()
158 ETSChecker *checker = GetETSChecker(); in Check() local
160 auto *scriptFunc = node->Function(); in Check()
162 CheckClassProperty(checker, scriptFunc); in Check()
165 checker->LogTypeError("Invalid function expression", node->Start()); in Check()
166 node->SetTsType(checker->GlobalTypeError()); in Check()
167 return node->TsType(); in Check()
170 if (scriptFunc->IsProxy()) { in Check()
175 if (!scriptFunc->HasBody() && !(node->IsAbstract() || node->IsNative() || node->IsDeclare() || in Check()
176 checker->HasStatus(checker::CheckerStatus::IN_INTERFACE))) { in Check()
177checker->LogTypeError("Only abstract or native methods can't have body.", scriptFunc->Start()); in Check()
178 node->SetTsType(checker->GlobalTypeError()); in Check()
179 return node->TsType(); in Check()
182 if (scriptFunc->ReturnTypeAnnotation() == nullptr && in Check()
183 (node->IsNative() || (node->IsDeclare() && !node->IsConstructor()))) { in Check()
184checker->LogTypeError("Native and Declare methods should have explicit return type.", scriptFunc->… in Check()
185 node->SetTsType(checker->GlobalTypeError()); in Check()
186 return node->TsType(); in Check()
189 if (node->TsType() == nullptr) { in Check()
190 node->SetTsType(checker->BuildMethodSignature(node)); in Check()
193 this->CheckMethodModifiers(node); in Check()
194 HandleNativeAndAsyncMethods(checker, node); in Check()
195 DoBodyTypeChecking(checker, node, scriptFunc); in Check()
196 CheckPredefinedMethodReturnType(checker, scriptFunc); in Check()
197 if (node->TsType()->IsTypeError()) { in Check()
198 return node->TsType(); in Check()
202 if ((node->Parent()->Modifiers() & ir::ModifierFlags::FUNCTIONAL) == 0) { in Check()
203checker->CheckOverride(node->TsType()->AsETSFunctionType()->FindSignature(node->Function())); in Check()
206 for (auto *overload : node->Overloads()) { in Check()
207 overload->Check(checker); in Check()
210 if (scriptFunc->IsRethrowing()) { in Check()
211 checker->CheckRethrowingFunction(scriptFunc); in Check()
214 return node->TsType(); in Check()
219 ETSChecker *checker = GetETSChecker(); in CheckMethodModifiers() local
223 if (node->IsAbstract() && (node->flags_ & notValidInAbstract) != 0U) { in CheckMethodModifiers()
224 checker->LogTypeError( in CheckMethodModifiers()
227 node->Start()); in CheckMethodModifiers()
228 node->SetTsType(checker->GlobalTypeError()); in CheckMethodModifiers()
232 if (node->Function() == nullptr) { in CheckMethodModifiers()
233 checker->LogTypeError("Invalid function expression", node->Start()); in CheckMethodModifiers()
234 node->SetTsType(checker->GlobalTypeError()); in CheckMethodModifiers()
238 …if ((node->IsAbstract() || (!node->Function()->HasBody() && !node->IsNative() && !node->IsDeclare(… in CheckMethodModifiers()
239 !(checker->HasStatus(checker::CheckerStatus::IN_ABSTRACT) || in CheckMethodModifiers()
240 checker->HasStatus(checker::CheckerStatus::IN_INTERFACE))) { in CheckMethodModifiers()
241 checker->LogTypeError("Non abstract class has abstract method.", node->Start()); in CheckMethodModifiers()
242 node->SetTsType(checker->GlobalTypeError()); in CheckMethodModifiers()
247 if (node->IsFinal() && (node->flags_ & notValidInFinal) != 0U) { in CheckMethodModifiers()
248checker->LogTypeError("Invalid method modifier(s): a final method can't have abstract or static mo… in CheckMethodModifiers()
249 node->Start()); in CheckMethodModifiers()
250 node->SetTsType(checker->GlobalTypeError()); in CheckMethodModifiers()
255 if (node->IsStatic() && (node->flags_ & notValidInStatic) != 0U) { in CheckMethodModifiers()
256 checker->LogTypeError( in CheckMethodModifiers()
258 node->Start()); in CheckMethodModifiers()
259 node->SetTsType(checker->GlobalTypeError()); in CheckMethodModifiers()
263 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::Property *expr) const in Check()
268 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::SpreadElement *expr) const in Check()
270 ETSChecker *checker = GetETSChecker(); in Check() local
271 Type *exprType = expr->AsSpreadElement()->Argument()->Check(checker); in Check()
272 if (!exprType->IsETSArrayType()) { in Check()
273 checker->LogTypeError( in Check()
275 expr->Start()); in Check()
276 expr->SetTsType(checker->GlobalTypeError()); in Check()
277 return expr->TsType(); in Check()
279 checker::Type *elementType = exprType->AsETSArrayType()->ElementType(); in Check()
280 expr->SetTsType(elementType); in Check()
281 return expr->TsType(); in Check()
284 checker::Type *ETSAnalyzer::Check(ir::TemplateElement *expr) const in Check()
286 ETSChecker *checker = GetETSChecker(); in Check() local
287 expr->SetTsType(checker->CreateETSStringLiteralType(expr->Raw())); in Check()
288 return expr->TsType(); in Check()
291 checker::Type *ETSAnalyzer::Check(ir::ETSClassLiteral *expr) const in Check()
293 ETSChecker *checker = GetETSChecker(); in Check() local
294 auto *const literal = expr->Expr(); in Check()
296 checker->LogTypeError("Class literal is not yet supported.", literal->Start()); in Check()
297 expr->SetTsType(checker->GlobalTypeError()); in Check()
298 return expr->TsType(); in Check()
300 auto *exprType = literal->Check(checker); in Check()
302 if (exprType->IsETSVoidType()) { in Check()
303 checker->LogTypeError("Invalid .class reference", literal->Start()); in Check()
304 expr->SetTsType(checker->GlobalTypeError()); in Check()
305 return expr->TsType(); in Check()
308 ArenaVector<checker::Type *> typeArgTypes(checker->Allocator()->Adapter()); in Check()
311checker::InstantiationContext ctx(checker, checker->GlobalBuiltinTypeType(), std::move(typeArgType… in Check()
312 expr->Range().start); in Check()
313 expr->SetTsType(ctx.Result()); in Check()
315 return expr->TsType(); in Check()
318 checker::Type *ETSAnalyzer::Check(ir::ETSFunctionType *node) const in Check()
320 if (node->TsType() != nullptr) { in Check()
321 return node->TsType(); in Check()
323 ETSChecker *checker = GetETSChecker(); in Check() local
325 size_t optionalParameterIndex = node->DefaultParamIndex(); in Check()
326 …auto *genericInterfaceType = checker->GlobalBuiltinFunctionType(node->Params().size(), node->Flags… in Check()
327 node->SetFunctionalInterface(genericInterfaceType->GetDeclNode()->AsTSInterfaceDeclaration()); in Check()
329 auto *tsType = checker->GetCachedFunctionalInterface(node); in Check()
330 node->SetTsType(tsType); in Check()
337 if (optionalParameterIndex == node->Params().size()) { in Check()
338 interfaceType = CreateInterfaceTypeForETSFunctionType(checker, node, genericInterfaceType); in Check()
341 …CreateOptionalSignaturesForFunctionalType(checker, node, genericInterfaceType, optionalParameterIn… in Check()
344 node->SetTsType(interfaceType); in Check()
348 checker::Type *ETSAnalyzer::Check(ir::ETSLaunchExpression *expr) const in Check()
350 ETSChecker *checker = GetETSChecker(); in Check() local
351 expr->expr_->Check(checker); in Check()
356 auto exprType = [&checker](auto *tsType) { in Check()
357 if (tsType->IsETSPrimitiveType()) { in Check()
358 return checker->MaybeBoxInRelation(tsType); in Check()
362 }(expr->expr_->TsType()); in Check()
364 expr->SetTsType(checker->CreatePromiseOf(exprType)); in Check()
365 return expr->TsType(); in Check()
368 checker::Type *ETSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const in Check()
370 ETSChecker *checker = GetETSChecker(); in Check() local
372 auto *elementType = expr->TypeReference()->GetType(checker); in Check()
373 checker->ValidateArrayIndex(expr->Dimension(), true); in Check()
374 if (!elementType->IsETSPrimitiveType()) { in Check()
375 … if (elementType->IsETSUnionType() && !elementType->AsETSUnionType()->HasNullishType(checker)) { in Check()
376checker->LogTypeError({"Union types in array declaration must include a nullish type."}, expr->Sta… in Check()
377 expr->SetTsType(checker->GlobalTypeError()); in Check()
378 return expr->TsType(); in Check()
380 if (elementType->IsETSObjectType()) { in Check()
381 auto *calleeObj = elementType->AsETSObjectType(); in Check()
382 … const auto flags = checker::ETSObjectFlags::ABSTRACT | checker::ETSObjectFlags::INTERFACE; in Check()
383 if (!calleeObj->HasObjectFlag(flags)) { in Check()
385 expr->SetSignature( in Check()
386checker->CollectParameterlessConstructor(calleeObj->ConstructSignatures(), expr->Start())); in Check()
387checker->ValidateSignatureAccessibility(calleeObj, nullptr, expr->Signature(), expr->Start()); in Check()
389checker->LogTypeError("Cannot use array creation expression with abstract classes and interfaces.", in Check()
390 expr->Start()); in Check()
391 expr->SetTsType(checker->GlobalTypeError()); in Check()
392 return expr->TsType(); in Check()
396 if (elementType->IsETSNeverType()) { in Check()
397checker->LogTypeError("Cannot use array creation expression with never type.", expr->Start()); in Check()
400 expr->SetTsType(checker->CreateETSArrayType(elementType)); in Check()
401 checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), 1); in Check()
402 return expr->TsType(); in Check()
407 ETSChecker *checker = GetETSChecker(); in CheckInstantatedClass() local
408 if (expr->ClassDefinition() != nullptr) { in CheckInstantatedClass()
409 …if (calleeObj->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT) && calleeObj->GetDeclNode()->IsFin… in CheckInstantatedClass()
410checker->LogTypeError({"Class ", calleeObj->Name(), " cannot be both 'abstract' and 'final'."}, in CheckInstantatedClass()
411 calleeObj->GetDeclNode()->Start()); in CheckInstantatedClass()
412 expr->SetTsType(checker->GlobalTypeError()); in CheckInstantatedClass()
416 bool fromInterface = calleeObj->HasObjectFlag(checker::ETSObjectFlags::INTERFACE); in CheckInstantatedClass()
417 auto *classType = checker->BuildAnonymousClassProperties( in CheckInstantatedClass()
418 expr->ClassDefinition(), fromInterface ? checker->GlobalETSObjectType() : calleeObj); in CheckInstantatedClass()
420 classType->AddInterface(calleeObj); in CheckInstantatedClass()
421 calleeObj = checker->GlobalETSObjectType(); in CheckInstantatedClass()
423 expr->ClassDefinition()->SetTsType(classType); in CheckInstantatedClass()
424 checker->CheckClassDefinition(expr->ClassDefinition()); in CheckInstantatedClass()
425 checker->CheckInnerClassMembers(classType); in CheckInstantatedClass()
426 expr->SetTsType(classType); in CheckInstantatedClass()
427 } else if (calleeObj->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT)) { in CheckInstantatedClass()
428checker->LogTypeError({calleeObj->Name(), " is abstract therefore cannot be instantiated."}, expr- in CheckInstantatedClass()
429 expr->SetTsType(checker->GlobalTypeError()); in CheckInstantatedClass()
432 if (calleeObj->HasObjectFlag(ETSObjectFlags::REQUIRED) && in CheckInstantatedClass()
433 !expr->HasAstNodeFlags(ir::AstNodeFlags::ALLOW_REQUIRED_INSTANTIATION)) { in CheckInstantatedClass()
434 checker->LogTypeError("Required type can be instantiated only with object literal", in CheckInstantatedClass()
435 expr->GetTypeRef()->Start()); in CheckInstantatedClass()
436 expr->SetTsType(checker->GlobalTypeError()); in CheckInstantatedClass()
440 checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const in Check()
442 if (expr->TsType() != nullptr) { in Check()
443 return expr->TsType(); in Check()
445 ETSChecker *checker = GetETSChecker(); in Check() local
446 auto *calleeType = GetCalleeType(checker, expr); in Check()
448 return expr->TsType(); in Check()
451 if (calleeType->IsTypeError()) { in Check()
452 expr->SetTsType(calleeType); in Check()
453 return expr->TsType(); in Check()
455 auto *calleeObj = calleeType->AsETSObjectType(); in Check()
456 expr->SetTsType(calleeObj); in Check()
460 if (calleeType->IsETSDynamicType() && !calleeType->AsETSDynamicType()->HasDecl()) { in Check()
461 auto lang = calleeType->AsETSDynamicType()->Language(); in Check()
462 …expr->SetSignature(checker->ResolveDynamicCallExpression(expr->GetTypeRef(), expr->GetArguments(),… in Check()
464 …auto *signature = checker->ResolveConstructExpression(calleeObj, expr->GetArguments(), expr->Start… in Check()
467 return checker->InvalidateType(expr); in Check()
470 checker->CheckObjectLiteralArguments(signature, expr->GetArguments()); in Check()
472 checker->ValidateSignatureAccessibility(calleeObj, nullptr, signature, expr->Start()); in Check()
474 ASSERT(signature->Function() != nullptr); in Check()
476 if (signature->Function()->IsThrowing() || signature->Function()->IsRethrowing()) { in Check()
477 checker->CheckThrowingStatements(expr); in Check()
480 if (calleeType->IsETSDynamicType()) { in Check()
481 ASSERT(signature->Function()->IsDynamic()); in Check()
482 auto lang = calleeType->AsETSDynamicType()->Language(); in Check()
483 expr->SetSignature( in Check()
484checker->ResolveDynamicCallExpression(expr->GetTypeRef(), signature->Params(), lang, true)); in Check()
486 ASSERT(!signature->Function()->IsDynamic()); in Check()
487 expr->SetSignature(signature); in Check()
491 return expr->TsType(); in Check()
494 checker::Type *ETSAnalyzer::Check(ir::ETSNewMultiDimArrayInstanceExpression *expr) const in Check()
496 ETSChecker *checker = GetETSChecker(); in Check() local
497 auto *elementType = expr->TypeReference()->GetType(checker); in Check()
499 for (auto *dim : expr->Dimensions()) { in Check()
500 checker->ValidateArrayIndex(dim, true); in Check()
501 elementType = checker->CreateETSArrayType(elementType); in Check()
504 expr->SetTsType(elementType); in Check()
505 …expr->SetSignature(checker->CreateBuiltinArraySignature(elementType->AsETSArrayType(), expr->Dimen… in Check()
506 return expr->TsType(); in Check()
509 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSPackageDeclaration *st) const in Check()
514 checker::Type *ETSAnalyzer::Check(ir::ETSParameterExpression *expr) const in Check()
516 ETSChecker *checker = GetETSChecker(); in Check() local
517 if (expr->TsType() == nullptr) { in Check()
518 checker::Type *paramType; in Check()
520 if (expr->Ident()->TsType() != nullptr) { in Check()
521 paramType = expr->Ident()->TsType(); in Check()
523 …paramType = !expr->IsRestParameter() ? expr->Ident()->Check(checker) : expr->spread_->Check(checke… in Check()
524 if (expr->IsDefault()) { in Check()
526 [[maybe_unused]] auto *const initType = expr->Initializer()->Check(checker); in Check()
530 expr->SetTsType(paramType); in Check()
533 return expr->TsType(); in Check()
536 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSPrimitiveType *node) const in Check()
538 ETSChecker *checker = GetETSChecker(); in Check() local
539 return node->GetType(checker); in Check()
542 checker::Type *ETSAnalyzer::Check(ir::ETSStructDeclaration *node) const in Check()
544 ETSChecker *checker = GetETSChecker(); in Check() local
545 node->Definition()->Check(checker); in Check()
549 checker::Type *ETSAnalyzer::Check(ir::ETSTypeReference *node) const in Check()
551 ETSChecker *checker = GetETSChecker(); in Check() local
552 return node->GetType(checker); in Check()
555 checker::Type *ETSAnalyzer::Check(ir::ETSTypeReferencePart *node) const in Check()
557 ETSChecker *checker = GetETSChecker(); in Check() local
558 return node->GetType(checker); in Check()
561 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNullType *node) const in Check()
566 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSUndefinedType *node) const in Check()
571 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNeverType *node) const in Check()
576 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSStringLiteralType *node) const in Check()
578 ETSChecker *checker = GetETSChecker(); in Check() local
579 return node->GetType(checker); in Check()
584 checker::Type *ETSAnalyzer::GetPreferredType(ir::ArrayExpression *expr) const in GetPreferredType()
586 return expr->preferredType_; in GetPreferredType()
589 static bool CheckArrayElement(ETSChecker *checker, checker::Type *elementType, in CheckArrayElement() argument
590 … std::vector<checker::Type *> targetElementType, ir::Expression *currentElement, in CheckArrayElement()
593 if ((targetElementType[0]->IsETSArrayType() && in CheckArrayElement()
594 targetElementType[0]->AsETSArrayType()->ElementType()->IsETSArrayType() && in CheckArrayElement()
595 !(targetElementType[0]->AsETSArrayType()->ElementType()->IsETSTupleType() && in CheckArrayElement()
597 …(!checker::AssignmentContext(checker->Relation(), currentElement, elementType, targetElementType[0… in CheckArrayElement()
598 currentElement->Start(), in CheckArrayElement()
602 // CC-OFFNXT(G.FMT.02) project code style in CheckArrayElement()
604 !(targetElementType[0]->IsETSArrayType() && currentElement->IsArrayExpression()))) { in CheckArrayElement()
606checker->LogTypeError({"Array element type '", elementType, "' is not assignable to explicit type … in CheckArrayElement()
608 currentElement->Start()); in CheckArrayElement()
612 if (!(targetElementType[0]->IsETSArrayType() && currentElement->IsArrayExpression()) && in CheckArrayElement()
613 …!checker::AssignmentContext(checker->Relation(), currentElement, elementType, targetElementType[1], in CheckArrayElement()
614 currentElement->Start(), in CheckArrayElement()
618 // CC-OFFNXT(G.FMT.02) project code style in CheckArrayElement()
620checker->LogTypeError({"Array element type '", elementType, "' is not assignable to explicit type … in CheckArrayElement()
622 currentElement->Start()); in CheckArrayElement()
630 static bool AddSpreadElementTypes(ETSChecker *checker, ir::Expression *const element, in AddSpreadElementTypes() argument
633 Type *elementType = element->Check(checker); in AddSpreadElementTypes()
634 Type *argumentType = element->AsSpreadElement()->Argument()->Check(checker); in AddSpreadElementTypes()
635 if (argumentType->IsETSTupleType()) { in AddSpreadElementTypes()
636 for (Type *type : argumentType->AsETSTupleType()->GetTupleTypesList()) { in AddSpreadElementTypes()
641 if (!argumentType->IsETSTupleType() && isPreferredTuple) { in AddSpreadElementTypes()
642checker->LogTypeError({"'", argumentType, "' cannot be spread in tuple."}, element->Start()); in AddSpreadElementTypes()
650 …td::pair<Type *, ir::Expression *>> GetElementTypes(ir::ArrayExpression *expr, ETSChecker *checker, in GetElementTypes() argument
653 ArenaVector<std::pair<Type *, ir::Expression *>> elementTypes(checker->Allocator()->Adapter()); in GetElementTypes()
654 for (std::size_t idx = 0; idx < expr->Elements().size(); ++idx) { in GetElementTypes()
655 ir::Expression *const element = expr->Elements()[idx]; in GetElementTypes()
657 if (element->IsArrayExpression() && in GetElementTypes()
658 …!expr->HandleNestedArrayExpression(checker, element->AsArrayExpression(), isPreferredTuple, idx)) { in GetElementTypes()
663 if (element->IsObjectExpression()) { in GetElementTypes()
664 …element->AsObjectExpression()->SetPreferredType(expr->GetPreferredType()->AsETSArrayType()->Elemen… in GetElementTypes()
667 if (element->IsSpreadElement()) { in GetElementTypes()
668 if (!AddSpreadElementTypes(checker, element, elementTypes, isPreferredTuple)) { in GetElementTypes()
674 Type *elementType = element->Check(checker); in GetElementTypes()
681 static bool CheckElement(ir::ArrayExpression *expr, ETSChecker *checker, std::vector<checker::Type … in CheckElement() argument
688 GetElementTypes(expr, checker, isPreferredTuple, checkResult); in CheckElement()
696 if (!elementType->IsETSArrayType() && isPreferredTuple) { in CheckElement()
697 auto const *const tupleType = expr->GetPreferredType()->AsETSTupleType(); in CheckElement()
699 auto *compareType = tupleType->GetTypeAtIndex(idx); in CheckElement()
701checker->LogTypeError({"Too many elements in array initializer for tuple with size of ", in CheckElement()
702 static_cast<uint32_t>(tupleType->GetTupleSize())}, in CheckElement()
703 currentElement->Start()); in CheckElement()
707 // clang-format off in CheckElement()
708 if (!AssignmentContext(checker->Relation(), currentElement, elementType, compareType, in CheckElement()
709 … currentElement->Start(), {}, TypeRelationFlag::NO_THROW).IsAssignable()) { in CheckElement()
710checker->LogTypeError({"Array initializer's type is not assignable to tuple type at index: ", idx}, in CheckElement()
711 currentElement->Start()); in CheckElement()
715 // clang-format on in CheckElement()
724 …if (!CheckArrayElement(checker, elementType, targetElementType, currentElement, isSecondaryChosen)… in CheckElement()
735 ASSERT(expr->preferredType_->IsETSUnionType()); in GetUnionPreferredType()
736 checker::Type *preferredType = nullptr; in GetUnionPreferredType()
737 for (auto &type : expr->preferredType_->AsETSUnionType()->ConstituentTypes()) { in GetUnionPreferredType()
738 if (type->IsETSArrayType()) { in GetUnionPreferredType()
743 preferredType = type->AsETSArrayType(); in GetUnionPreferredType()
747 expr->preferredType_ = preferredType; in GetUnionPreferredType()
750 checker::Type *ETSAnalyzer::Check(ir::ArrayExpression *expr) const in Check()
752 ETSChecker *checker = GetETSChecker(); in Check() local
753 if (expr->TsType() != nullptr) { in Check()
754 return expr->TsType(); in Check()
757 if (expr->preferredType_ != nullptr) { in Check()
758 if (expr->preferredType_->IsETSTypeAliasType()) { in Check()
759 expr->preferredType_ = expr->preferredType_->AsETSTypeAliasType()->GetTargetType(); in Check()
762 if (expr->preferredType_->IsETSUnionType()) { in Check()
767 if (expr->preferredType_ != nullptr && !expr->preferredType_->IsETSArrayType() && in Check()
768 !checker->Relation()->IsSupertypeOf(expr->preferredType_, checker->GlobalETSObjectType())) { in Check()
769checker->LogTypeError({"Expected type for array literal should be an array type, got ", expr->pref… in Check()
770 expr->Start()); in Check()
771 return checker->InvalidateType(expr); in Check()
774 …const bool isArray = (expr->preferredType_ != nullptr) && expr->preferredType_->IsETSArrayType() && in Check()
775 !expr->preferredType_->IsETSTupleType(); in Check()
777 if (!expr->Elements().empty()) { in Check()
778 … if (expr->preferredType_ == nullptr || expr->preferredType_ == checker->GlobalETSObjectType()) { in Check()
784 expr->preferredType_ = in Check()
785checker->CreateETSArrayType(checker->GetNonConstantType(expr->Elements()[0]->Check(checker))); in Check()
788 const bool isPreferredTuple = expr->preferredType_->IsETSTupleType(); in Check()
791 checker->GetNonConstantType(expr->GetPreferredType()->AsETSArrayType()->ElementType()); in Check()
794 targetElementTypeSecondary = expr->GetPreferredType()->AsETSTupleType()->ElementType(); in Check()
797 …if (!CheckElement(expr, checker, {targetElementType, targetElementTypeSecondary}, isPreferredTuple… in Check()
798 return checker->InvalidateType(expr); in Check()
802 if (expr->preferredType_ == nullptr) { in Check()
803 return checker->TypeError(expr, "Can't resolve array type", expr->Start()); in Check()
806 expr->SetTsType(expr->preferredType_); in Check()
807 auto *const arrayType = expr->TsType()->AsETSArrayType(); in Check()
808 checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); in Check()
809 return expr->TsType(); in Check()
812 checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const in Check()
814 ETSChecker *checker = GetETSChecker(); in Check() local
816 if (expr->TsType() != nullptr) { in Check()
817 return expr->TsType(); in Check()
819 checker::ScopeContext scopeCtx(checker, expr->Function()->Scope()); in Check()
821 if (checker->HasStatus(checker::CheckerStatus::IN_INSTANCE_EXTENSION_METHOD)) { in Check()
836 checker->Context().SetContainingClass( in Check()
837checker->Scope()->Find(varbinder::VarBinder::MANDATORY_PARAM_THIS).variable->TsType()->AsETSObject… in Check()
840 checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), in Check()
841 checker->Context().ContainingClass()); in Check()
843 checker->AddStatus(checker::CheckerStatus::IN_LAMBDA); in Check()
844 checker->Context().SetContainingLambda(expr); in Check()
846 checker->BuildFunctionSignature(expr->Function(), false); in Check()
847 if (expr->Function()->Signature() == nullptr) { in Check()
848 return checker->InvalidateType(expr); in Check()
850 auto *signature = expr->Function()->Signature(); in Check()
852 checker->Context().SetContainingSignature(signature); in Check()
853 expr->Function()->Body()->Check(checker); in Check()
855 ArenaVector<Signature *> signatures(checker->Allocator()->Adapter()); in Check()
857 for (auto &sigInfo : checker->ComposeSignatureInfosForArrowFunction(expr)) { in Check()
858 … auto sig = checker->ComposeSignature(expr->Function(), sigInfo, signature->ReturnType(), nullptr); in Check()
859 sig->AddSignatureFlag(signature->GetFlags()); in Check()
863 … auto *funcType = checker->CreateETSFunctionType(expr->Function(), std::move(signatures), nullptr); in Check()
864 checker->Context().SetContainingSignature(nullptr); in Check()
866 if (expr->Function()->IsAsyncFunc()) { in Check()
867 auto *retType = signature->ReturnType(); in Check()
868 if (!retType->IsETSObjectType() || in Check()
869 … retType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType()) { in Check()
870checker->LogTypeError("Return type of async lambda must be 'Promise'", expr->Function()->Start()); in Check()
871 expr->SetTsType(checker->GlobalTypeError()); in Check()
872 return expr->TsType(); in Check()
876 expr->SetTsType(funcType); in Check()
877 return expr->TsType(); in Check()
880 …atic bool IsInvalidArrayMemberAssignment(ir::AssignmentExpression *const expr, ETSChecker *checker) in IsInvalidArrayMemberAssignment() argument
882 if (expr->Left()->IsMemberExpression() && in IsInvalidArrayMemberAssignment()
883 expr->Left()->AsMemberExpression()->Object()->TsType()->IsETSArrayType()) { in IsInvalidArrayMemberAssignment()
884 auto *const leftExpr = expr->Left()->AsMemberExpression(); in IsInvalidArrayMemberAssignment()
885 …if (leftExpr->Property()->IsIdentifier() && leftExpr->Property()->AsIdentifier()->Name().Is("lengt… in IsInvalidArrayMemberAssignment()
886checker->LogTypeError("Setting the length of an array is not permitted", expr->Left()->Start()); in IsInvalidArrayMemberAssignment()
889 if (leftExpr->Object()->TsType()->HasTypeFlag(TypeFlag::READONLY)) { in IsInvalidArrayMemberAssignment()
890checker->LogTypeError("Cannot modify an array or tuple content that has the readonly parameter", in IsInvalidArrayMemberAssignment()
891 expr->Left()->Start()); in IsInvalidArrayMemberAssignment()
898 checker::Type *ETSAnalyzer::GetSmartType(ir::AssignmentExpression *expr, checker::Type *leftType, in GetSmartType()
899 checker::Type *rightType) const in GetSmartType()
901 ETSChecker *checker = GetETSChecker(); in GetSmartType() local
902 checker::Type *smartType = leftType; in GetSmartType()
904 if (expr->Left()->IsIdentifier()) { in GetSmartType()
905 …o define the actual type of Identifier so that smart cast can be used in further checker processing in GetSmartType()
906 smartType = checker->ResolveSmartType(rightType, leftType); in GetSmartType()
907 auto const *const variable = expr->Target(); in GetSmartType()
910 // (excluding the variables defined at top-level scope or captured in lambda-functions!) in GetSmartType()
911 auto const *const variableScope = variable->GetScope(); in GetSmartType()
913 …variableScope != nullptr && (variableScope->IsGlobalScope() || (variableScope->Parent() != nullptr… in GetSmartType()
914 … variableScope->Parent()->IsGlobalScope())); in GetSmartType()
916 if (checker->Relation()->IsIdenticalTo(leftType, smartType)) { in GetSmartType()
917 checker->Context().RemoveSmartCast(variable); in GetSmartType()
919 expr->Left()->SetTsType(smartType); in GetSmartType()
920 checker->Context().SetSmartCast(variable, smartType); in GetSmartType()
927 checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const in Check()
929 if (expr->TsType() != nullptr) { in Check()
930 return expr->TsType(); in Check()
933 ETSChecker *checker = GetETSChecker(); in Check() local
935 auto *const leftType = expr->Left()->Check(checker); in Check()
937 if (IsInvalidArrayMemberAssignment(expr, checker)) { in Check()
938 expr->SetTsType(checker->GlobalTypeError()); in Check()
939 return expr->TsType(); in Check()
942 if (expr->Left()->IsIdentifier()) { in Check()
943 expr->target_ = expr->Left()->AsIdentifier()->Variable(); in Check()
944 } else if (expr->Left()->IsMemberExpression()) { in Check()
945 expr->target_ = expr->Left()->AsMemberExpression()->PropVar(); in Check()
947checker->LogTypeError("Invalid left-hand side of assignment expression", expr->Left()->Start()); in Check()
948 expr->SetTsType(checker->GlobalTypeError()); in Check()
949 return expr->TsType(); in Check()
952 if (expr->target_ != nullptr && !expr->IsIgnoreConstAssign()) { in Check()
953 checker->ValidateUnaryOperatorOperand(expr->target_); in Check()
958 expr->SetTsType(checker->GlobalTypeError()); in Check()
959 return checker->GlobalTypeError(); in Check()
962 const checker::Type *targetType = checker->TryGettingFunctionTypeFromInvokeFunction(leftType); in Check()
963 const checker::Type *sourceType = checker->TryGettingFunctionTypeFromInvokeFunction(rightType); in Check()
965checker::AssignmentContext(checker->Relation(), relationNode, rightType, leftType, expr->Right()->… in Check()
968 checker::Type *smartType = GetSmartType(expr, leftType, rightType); in Check()
970 expr->SetTsType(smartType); in Check()
971 return expr->TsType(); in Check()
977 ETSChecker *checker = GetETSChecker(); in CheckAssignmentExprOperatorType() local
978 checker::Type *sourceType {}; in CheckAssignmentExprOperatorType()
979 ir::Expression *relationNode = expr->Right(); in CheckAssignmentExprOperatorType()
980 switch (expr->OperatorType()) { in CheckAssignmentExprOperatorType()
993 std::tie(std::ignore, expr->operationType_) = checker->CheckBinaryOperator( in CheckAssignmentExprOperatorType()
994 expr->Left(), expr->Right(), expr, expr->OperatorType(), expr->Start(), true); in CheckAssignmentExprOperatorType()
996 auto unboxedLeft = checker->MaybeUnboxInRelation(leftType); in CheckAssignmentExprOperatorType()
1003 if (leftType->IsETSArrayType() && expr->Right()->IsArrayExpression()) { in CheckAssignmentExprOperatorType()
1004 checker->ModifyPreferredType(expr->Right()->AsArrayExpression(), leftType); in CheckAssignmentExprOperatorType()
1007 if (expr->Right()->IsObjectExpression()) { in CheckAssignmentExprOperatorType()
1008 expr->Right()->AsObjectExpression()->SetPreferredType(leftType); in CheckAssignmentExprOperatorType()
1011 sourceType = expr->Right()->Check(checker); in CheckAssignmentExprOperatorType()
1023 checker::Type *ETSAnalyzer::Check(ir::AwaitExpression *expr) const in Check()
1025 ETSChecker *checker = GetETSChecker(); in Check() local
1026 if (expr->TsType() != nullptr) { in Check()
1027 return expr->TsType(); in Check()
1030 checker::Type *argType = checker->GetApparentType(expr->argument_->Check(checker)); in Check()
1032 if (!argType->IsETSObjectType() || in Check()
1033 … (argType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType())) { in Check()
1034checker->LogTypeError("'await' expressions require Promise object as argument.", expr->Argument()- in Check()
1035 expr->SetTsType(checker->GlobalTypeError()); in Check()
1036 return expr->TsType(); in Check()
1039 Type *type = argType->AsETSObjectType()->TypeArguments().at(0); in Check()
1040 expr->SetTsType(UnwrapPromiseType(type)); in Check()
1041 return expr->TsType(); in Check()
1044 checker::Type *ETSAnalyzer::Check(ir::ImportExpression *expr) const in Check()
1046 ETSChecker *checker = GetETSChecker(); in Check() local
1047 if (expr->TsType() != nullptr) { in Check()
1048 return expr->TsType(); in Check()
1051 Type *const argType = expr->Source()->Check(checker); in Check()
1052 if (argType->IsTypeError()) { in Check()
1053 expr->SetTsType(checker->GlobalTypeError()); in Check()
1054 return expr->TsType(); in Check()
1056 if (!checker->Relation()->IsSupertypeOf(checker->GlobalBuiltinETSStringType(), argType)) { in Check()
1057 checker->LogTypeError("'import' expressions require string as argument.", expr->Start()); in Check()
1058 expr->SetTsType(checker->GlobalTypeError()); in Check()
1059 return expr->TsType(); in Check()
1062 expr->SetTsType(checker->CreatePromiseOf(checker->GlobalBuiltinJSValueType())); in Check()
1063 return expr->TsType(); in Check()
1066 checker::Type *ETSAnalyzer::UnwrapPromiseType(checker::Type *type) const in UnwrapPromiseType()
1068 ETSChecker *checker = GetETSChecker(); in UnwrapPromiseType() local
1069 checker::Type *promiseType = checker->GlobalBuiltinPromiseType(); in UnwrapPromiseType()
1070 … while (type->IsETSObjectType() && type->AsETSObjectType()->GetOriginalBaseType() == promiseType) { in UnwrapPromiseType()
1071 type = type->AsETSObjectType()->TypeArguments().at(0); in UnwrapPromiseType()
1073 if (!type->IsETSUnionType()) { in UnwrapPromiseType()
1076 const auto &ctypes = type->AsETSUnionType()->ConstituentTypes(); in UnwrapPromiseType()
1077 auto it = std::find_if(ctypes.begin(), ctypes.end(), [promiseType](checker::Type *t) { in UnwrapPromiseType()
1078 …return t == promiseType || (t->IsETSObjectType() && t->AsETSObjectType()->GetBaseType() == promise… in UnwrapPromiseType()
1085 size_t index = it - ctypes.begin(); in UnwrapPromiseType()
1088 it = std::find_if(it, ctypes.end(), [promiseType](checker::Type *t) { in UnwrapPromiseType()
1089 return t == promiseType || t->AsETSObjectType()->GetBaseType() == promiseType; in UnwrapPromiseType()
1092 return checker->CreateETSUnionType(std::move(newCTypes)); in UnwrapPromiseType()
1095 checker::Type *ETSAnalyzer::Check(ir::BinaryExpression *expr) const in Check()
1097 if (expr->TsType() != nullptr) { in Check()
1098 return expr->TsType(); in Check()
1101 ETSChecker *checker = GetETSChecker(); in Check() local
1102 checker::Type *newTsType {nullptr}; in Check()
1103 std::tie(newTsType, expr->operationType_) = in Check()
1104checker->CheckBinaryOperator(expr->Left(), expr->Right(), expr, expr->OperatorType(), expr->Start(… in Check()
1105 expr->SetTsType(newTsType); in Check()
1107 checker->Context().CheckBinarySmartCastCondition(expr); in Check()
1109 return expr->TsType(); in Check()
1112 checker::Type *ETSAnalyzer::Check(ir::BlockExpression *st) const in Check()
1114 ETSChecker *checker = GetETSChecker(); in Check() local
1115 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
1117 if (st->TsType() == nullptr) { in Check()
1118 // NOLINTNEXTLINE(modernize-loop-convert) in Check()
1119 for (std::size_t idx = 0; idx < st->Statements().size(); idx++) { in Check()
1120 st->Statements()[idx]->Check(checker); in Check()
1123 auto lastStmt = st->Statements().back(); in Check()
1124 ASSERT(lastStmt->IsExpressionStatement()); in Check()
1125 st->SetTsType(lastStmt->AsExpressionStatement()->GetExpression()->TsType()); in Check()
1128 return st->TsType(); in Check()
1131 checker::Signature *ETSAnalyzer::ResolveSignature(ETSChecker *checker, ir::CallExpression *expr, in ResolveSignature() argument
1132checker::Type *calleeType, bool isFunctionalInterface, in ResolveSignature()
1135 …bool extensionFunctionType = expr->Callee()->IsMemberExpression() && checker->ExtensionETSFunction… in ResolveSignature()
1137 if (calleeType->IsETSExtensionFuncHelperType()) { in ResolveSignature()
1138 …turn ResolveCallForETSExtensionFuncHelperType(calleeType->AsETSExtensionFuncHelperType(), checker,… in ResolveSignature()
1141 return ResolveCallExtensionFunction(calleeType->AsETSFunctionType(), checker, expr); in ResolveSignature()
1143 …auto &signatures = ChooseSignatures(checker, calleeType, expr->IsETSConstructorCall(), isFunctiona… in ResolveSignature()
1146 if (expr->Callee()->IsMemberExpression() && in ResolveSignature()
1148 !expr->Callee()->AsMemberExpression()->Object()->TsType()->IsETSEnumType() && in ResolveSignature()
1149 (expr->Callee()->AsMemberExpression()->Object()->IsSuperExpression() || in ResolveSignature()
1150 (expr->Callee()->AsMemberExpression()->Object()->IsIdentifier() && in ResolveSignature()
1151 expr->Callee()->AsMemberExpression()->Object()->AsIdentifier()->Variable()->HasFlag( in ResolveSignature()
1155 … [](checker::Signature *signature) { return signature->Function()->IsStatic(); }), in ResolveSignature()
1159checker::Signature *signature = checker->ResolveCallExpressionAndTrailingLambda(signatures, expr, … in ResolveSignature()
1164 if (signature->Function()->IsExtensionMethod()) { in ResolveSignature()
1165 checker->LogTypeError({"No matching call signature"}, expr->Start()); in ResolveSignature()
1171 checker::Type *ETSAnalyzer::GetReturnType(ir::CallExpression *expr, checker::Type *calleeType) const in GetReturnType()
1173 ETSChecker *checker = GetETSChecker(); in GetReturnType() local
1175 if (calleeType->IsTypeError()) { in GetReturnType()
1176 return checker->GlobalTypeError(); in GetReturnType()
1179 bool isConstructorCall = expr->IsETSConstructorCall(); in GetReturnType()
1181 calleeType->IsETSUnionType() && in GetReturnType()
1182 calleeType->AsETSUnionType()->HasObjectType(checker::ETSObjectFlags::FUNCTIONAL_INTERFACE); in GetReturnType()
1183 …bool isFunctionalInterface = calleeType->IsETSObjectType() && calleeType->AsETSObjectType()->HasOb… in GetReturnType()
1184 … // CC-OFFNXT(G.FMT.06-CPP) project code style in GetReturnType()
1185checker::ETSObjectFlags::FUNCTIONAL_INTERFACE); in GetReturnType()
1186 bool etsExtensionFuncHelperType = calleeType->IsETSExtensionFuncHelperType(); in GetReturnType()
1188 if (expr->Callee()->IsArrowFunctionExpression()) { in GetReturnType()
1189 calleeType = InitAnonymousLambdaCallee(checker, expr->Callee(), calleeType); in GetReturnType()
1193 if (!isFunctionalInterface && !calleeType->IsETSFunctionType() && !isConstructorCall && in GetReturnType()
1195 checker->LogTypeError({"Type '", calleeType, "' has no call signatures."}, expr->Start()); in GetReturnType()
1196 return checker->GlobalTypeError(); in GetReturnType()
1199 checker::Signature *signature = in GetReturnType()
1200 …ResolveSignature(checker, expr, calleeType, isFunctionalInterface, isUnionTypeWithFunctionalInterf… in GetReturnType()
1202 return checker->GlobalTypeError(); in GetReturnType()
1205 checker->CheckObjectLiteralArguments(signature, expr->Arguments()); in GetReturnType()
1208checker::ETSObjectType *calleeObj = ChooseCalleeObj(checker, expr, calleeType, isConstructorCall); in GetReturnType()
1209 checker->ValidateSignatureAccessibility(calleeObj, expr, signature, expr->Start()); in GetReturnType()
1212 ASSERT(signature->Function() != nullptr); in GetReturnType()
1213 if (signature->Function()->IsThrowing() || signature->Function()->IsRethrowing()) { in GetReturnType()
1214 checker->CheckThrowingStatements(expr); in GetReturnType()
1217 if (signature->Function()->IsDynamic()) { in GetReturnType()
1218 ASSERT(signature->Function()->IsDynamic()); in GetReturnType()
1219 auto lang = signature->Function()->Language(); in GetReturnType()
1220 …expr->SetSignature(checker->ResolveDynamicCallExpression(expr->Callee(), signature->Params(), lang… in GetReturnType()
1222 ASSERT(!signature->Function()->IsDynamic()); in GetReturnType()
1223 expr->SetSignature(signature); in GetReturnType()
1226 auto *returnType = signature->ReturnType(); in GetReturnType()
1228 if (signature->HasSignatureFlag(SignatureFlags::THIS_RETURN_TYPE)) { in GetReturnType()
1229 returnType = ChooseCalleeObj(checker, expr, calleeType, isConstructorCall); in GetReturnType()
1235 static void CheckAbstractCall(ETSChecker *checker, ir::CallExpression *expr) in CheckAbstractCall() argument
1237 if (expr->Callee()->IsMemberExpression()) { in CheckAbstractCall()
1238 auto obj = expr->Callee()->AsMemberExpression()->Object(); in CheckAbstractCall()
1239 if (obj != nullptr && obj->IsSuperExpression()) { in CheckAbstractCall()
1240 …if ((expr->Signature() != nullptr) && (expr->Signature()->HasSignatureFlag(SignatureFlags::ABSTRAC… in CheckAbstractCall()
1241 checker->LogTypeError("Cannot call abstract method!", expr->Start()); in CheckAbstractCall()
1242 expr->SetTsType(checker->GlobalTypeError()); in CheckAbstractCall()
1248 static void CheckCallee(ETSChecker *checker, ir::CallExpression *expr) in CheckCallee() argument
1250 checker->CheckNonNullish(expr->Callee()); in CheckCallee()
1251 …if (expr->Callee()->IsMemberExpression() && expr->Callee()->AsMemberExpression()->Object() != null… in CheckCallee()
1252 expr->Callee()->AsMemberExpression()->Object()->TsType()->IsETSObjectType() && in CheckCallee()
1253 expr->Callee()->AsMemberExpression()->Object()->TsType()->AsETSObjectType()->HasObjectFlag( in CheckCallee()
1255 checker->LogTypeError("Cannot call readonly type methods.", expr->Start()); in CheckCallee()
1256 expr->SetTsType(checker->GlobalTypeError()); in CheckCallee()
1261 static checker::SavedCheckerContext ReconstructOwnerClassContext(ETSChecker *checker, ETSObjectType… in ReconstructOwnerClassContext() argument
1264 return SavedCheckerContext(checker, CheckerStatus::NO_OPTS, nullptr); in ReconstructOwnerClassContext()
1266 ASSERT(!owner->HasObjectFlag(ETSObjectFlags::ENUM)); in ReconstructOwnerClassContext()
1268 …(owner->HasObjectFlag(ETSObjectFlags::CLASS) ? CheckerStatus::IN_CLASS : CheckerStatus::IN_INTERFA… in ReconstructOwnerClassContext()
1269 …(owner->HasObjectFlag(ETSObjectFlags::ABSTRACT) ? CheckerStatus::IN_ABSTRACT : CheckerStatus::NO_O… in ReconstructOwnerClassContext()
1270 …(owner->HasObjectFlag(ETSObjectFlags::INNER) ? CheckerStatus::INNER_CLASS : CheckerStatus::NO_OPTS… in ReconstructOwnerClassContext()
1271 … (owner->GetDeclNode()->IsClassDefinition() && owner->GetDeclNode()->AsClassDefinition()->IsLocal() in ReconstructOwnerClassContext()
1275 return SavedCheckerContext(checker, status, owner); in ReconstructOwnerClassContext()
1278 checker::Type *ETSAnalyzer::GetCallExpressionReturnType(ir::CallExpression *expr, checker::Type *ca… in GetCallExpressionReturnType()
1280 ETSChecker *checker = GetETSChecker(); in GetCallExpressionReturnType() local
1281 checker::Type *returnType = nullptr; in GetCallExpressionReturnType()
1282 if (calleeType->IsETSDynamicType() && !calleeType->AsETSDynamicType()->HasDecl()) { in GetCallExpressionReturnType()
1284 checker->EnsureValidCurlyBrace(expr); in GetCallExpressionReturnType()
1285 auto lang = calleeType->AsETSDynamicType()->Language(); in GetCallExpressionReturnType()
1286 …expr->SetSignature(checker->ResolveDynamicCallExpression(expr->Callee(), expr->Arguments(), lang, … in GetCallExpressionReturnType()
1287 returnType = expr->Signature()->ReturnType(); in GetCallExpressionReturnType()
1292 if (returnType->IsTypeError()) { in GetCallExpressionReturnType()
1293 return checker->GlobalTypeError(); in GetCallExpressionReturnType()
1296 auto const signature = expr->Signature(); in GetCallExpressionReturnType()
1297 if (signature->RestVar() != nullptr) { in GetCallExpressionReturnType()
1298 auto *const elementType = signature->RestVar()->TsType()->AsETSArrayType()->ElementType(); in GetCallExpressionReturnType()
1299 auto *const arrayType = checker->CreateETSArrayType(elementType)->AsETSArrayType(); in GetCallExpressionReturnType()
1300 checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); in GetCallExpressionReturnType()
1303 if (signature->HasSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE)) { in GetCallExpressionReturnType()
1304 …auto owner = const_cast<ETSObjectType *>(util::Helpers::GetContainingObjectType(signature->Functio… in GetCallExpressionReturnType()
1305 SavedCheckerContext savedCtx(ReconstructOwnerClassContext(checker, owner)); in GetCallExpressionReturnType()
1306 signature->OwnerVar()->Declaration()->Node()->Check(checker); in GetCallExpressionReturnType()
1307 if (signature->Function()->HasBody()) { in GetCallExpressionReturnType()
1308 checker::ScopeContext scopeCtx(checker, signature->Function()->Body()->Scope()); in GetCallExpressionReturnType()
1309 checker->CollectReturnStatements(signature->Function()); in GetCallExpressionReturnType()
1311 return signature->ReturnType(); in GetCallExpressionReturnType()
1318 checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const in Check()
1320 ETSChecker *checker = GetETSChecker(); in Check() local
1321 if (expr->TsType() != nullptr) { in Check()
1322 return expr->TsType(); in Check()
1324 ASSERT(!expr->IsOptional()); in Check()
1326 auto *oldCallee = expr->Callee(); in Check()
1327 checker::Type *calleeType = checker->GetApparentType(expr->Callee()->Check(checker)); in Check()
1328 if (calleeType->IsTypeError()) { in Check()
1329 return checker->InvalidateType(expr); in Check()
1332 if (expr->Callee() != oldCallee) { in Check()
1335 calleeType = checker->GetApparentType(expr->Callee()->Check(checker)); in Check()
1338 CheckCallee(checker, expr); in Check()
1340 checker::Type *const returnType = GetCallExpressionReturnType(expr, calleeType); in Check()
1341 expr->SetTsType(returnType); in Check()
1342 if (returnType->IsTypeError()) { in Check()
1346 expr->SetUncheckedType(checker->GuaranteedTypeForUncheckedCallReturn(expr->Signature())); in Check()
1347 if (expr->UncheckedType() != nullptr) { in Check()
1348 checker->ComputeApparentType(returnType); in Check()
1351 if (returnType->IsTypeError()) { in Check()
1352 expr->SetTsType(returnType); in Check()
1353 return expr->TsType(); in Check()
1356 CheckVoidTypeExpression(checker, expr); in Check()
1357 CheckAbstractCall(checker, expr); in Check()
1358 return expr->TsType(); in Check()
1361 checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const in Check()
1363 if (expr->TsType() != nullptr) { in Check()
1364 return expr->TsType(); in Check()
1367 ETSChecker *const checker = GetETSChecker(); in Check() local
1369 SmartCastArray smartCasts = checker->Context().EnterTestExpression(); in Check()
1370 checker->CheckTruthinessOfType(expr->Test()); in Check()
1371 SmartCastTypes testedTypes = checker->Context().ExitTestExpression(); in Check()
1374 checker->ApplySmartCast(variable, consequentType); in Check()
1378 auto *consequent = expr->Consequent(); in Check()
1379 auto *consequentType = consequent->Check(checker); in Check()
1381 SmartCastArray consequentSmartCasts = checker->Context().CloneSmartCasts(); in Check()
1382 checker->Context().RestoreSmartCasts(smartCasts); in Check()
1386 checker->ApplySmartCast(variable, alternateType); in Check()
1390 auto *alternate = expr->Alternate(); in Check()
1391 auto *alternateType = alternate->Check(checker); in Check()
1394 checker->Context().CombineSmartCasts(consequentSmartCasts); in Check()
1396 if (checker->IsTypeIdenticalTo(consequentType, alternateType)) { in Check()
1397 expr->SetTsType(checker->GetNonConstantType(consequentType)); in Check()
1399 … possible and required update number literal type to the proper value (identical to left-side type) in Check()
1400 if (alternate->IsNumberLiteral() && in Check()
1401checker->AdjustNumberLiteralType(alternate->AsNumberLiteral(), alternateType, consequentType)) { in Check()
1402 expr->SetTsType(consequentType); in Check()
1403 } else if (consequent->IsNumberLiteral() && in Check()
1404checker->AdjustNumberLiteralType(consequent->AsNumberLiteral(), consequentType, alternateType)) { in Check()
1405 expr->SetTsType(alternateType); in Check()
1407 expr->SetTsType(checker->CreateETSUnionType({consequentType, alternateType})); in Check()
1408 if (expr->TsType()->IsETSReferenceType()) { in Check()
1409 checker->MaybeBoxExpression(expr->Consequent()); in Check()
1410 checker->MaybeBoxExpression(expr->Alternate()); in Check()
1415 return expr->TsType(); in Check()
1418 checker::Type *ETSAnalyzer::Check(ir::Identifier *expr) const in Check()
1420 if (expr->TsType() == nullptr) { in Check()
1421 ETSChecker *checker = GetETSChecker(); in Check() local
1423 auto *identType = checker->ResolveIdentifier(expr); in Check()
1424 …if (expr->Variable() != nullptr && (expr->Parent() == nullptr || !expr->Parent()->IsAssignmentExpr… in Check()
1425 … expr != expr->Parent()->AsAssignmentExpression()->Left())) { in Check()
1426 …if (auto *const smartType = checker->Context().GetSmartCast(expr->Variable()); smartType != nullpt… in Check()
1430 expr->SetTsType(identType); in Check()
1431 if (!identType->IsTypeError()) { in Check()
1432 checker->Context().CheckIdentifierSmartCastCondition(expr); in Check()
1435 return expr->TsType(); in Check()
1438 std::pair<checker::Type *, util::StringView> SearchReExportsType(ETSObjectType *baseType, ir::Membe… in SearchReExportsType()
1439 … util::StringView &aliasName, ETSChecker *checker) in SearchReExportsType() argument
1443 for (auto *const item : baseType->ReExports()) { in SearchReExportsType()
1444 auto name = item->GetReExportAliasValue(aliasName); in SearchReExportsType()
1445 if (name == aliasName && item->IsReExportHaveAliasValue(name)) { in SearchReExportsType()
1449 if (item->GetProperty(name, PropertySearchFlags::SEARCH_ALL) != nullptr) { in SearchReExportsType()
1451 checker->LogTypeError({"Ambiguous reference to '", aliasName, "'"}, expr->Start()); in SearchReExportsType()
1452 expr->SetTsType(checker->GlobalTypeError()); in SearchReExportsType()
1458 …if (auto reExportType = SearchReExportsType(item, expr, name, checker); reExportType.first != null… in SearchReExportsType()
1466 static void TypeErrorOnMissingProperty(ir::MemberExpression *expr, checker::Type *baseType, in TypeErrorOnMissingProperty()
1467 checker::ETSChecker *checker) in TypeErrorOnMissingProperty() argument
1469 std::ignore = checker->TypeError(expr, in TypeErrorOnMissingProperty()
1470checker->FormatMsg({"Property '", expr->Property()->AsIdentifier()->Name(), in TypeErrorOnMissingProperty()
1472 expr->Object()->Start()); in TypeErrorOnMissingProperty()
1475 checker::Type *ETSAnalyzer::CheckEnumMemberExpression(ETSEnumType *const baseType, in CheckEnumMemberExpression()
1478 ETSChecker *checker = GetETSChecker(); in CheckEnumMemberExpression() local
1479 auto *const boxedClass = baseType->GetDecl()->BoxedClass(); in CheckEnumMemberExpression()
1480 if (!boxedClass->IsClassDefinitionChecked()) { in CheckEnumMemberExpression()
1482 checker->CheckClassDefinition(boxedClass); in CheckEnumMemberExpression()
1485 auto [memberType, memberVar] = expr->ResolveEnumMember(checker, baseType); in CheckEnumMemberExpression()
1486 expr->SetPropVar(memberVar); in CheckEnumMemberExpression()
1487 expr->Property()->SetTsType(memberType == nullptr ? checker->GlobalTypeError() : memberType); in CheckEnumMemberExpression()
1488 return expr->AdjustType(checker, expr->Property()->TsType()); in CheckEnumMemberExpression()
1491 checker::Type *ETSAnalyzer::Check(ir::MemberExpression *expr) const in Check()
1493 if (expr->TsType() != nullptr) { in Check()
1494 return expr->TsType(); in Check()
1496 ASSERT(!expr->IsOptional()); in Check()
1498 ETSChecker *checker = GetETSChecker(); in Check() local
1499 …auto *baseType = checker->GetNonConstantType(checker->GetApparentType(expr->Object()->Check(checke… in Check()
1500 // Note: don't use possible smart cast to null-like types. in Check()
1502 if (baseType->DefinitelyETSNullish() && expr->Object()->IsIdentifier()) { in Check()
1503 baseType = expr->Object()->AsIdentifier()->Variable()->TsType(); in Check()
1506 if (baseType->IsETSObjectType() && !baseType->AsETSObjectType()->ReExports().empty() && in Check()
1507 baseType->AsETSObjectType()->GetProperty(expr->Property()->AsIdentifier()->Name(), in Check()
1509 if (auto reExportType = SearchReExportsType(baseType->AsETSObjectType(), expr, in Check()
1510 … expr->Property()->AsIdentifier()->Name(), checker); in Check()
1513 expr->object_->AsIdentifier()->SetTsType(baseType); in Check()
1514 expr->property_->AsIdentifier()->SetName(reExportType.second); in Check()
1518 if (!checker->CheckNonNullish(expr->Object())) { in Check()
1519 return checker->InvalidateType(expr); in Check()
1522 if (expr->IsComputed()) { in Check()
1523 return expr->AdjustType(checker, expr->CheckComputed(checker, baseType)); in Check()
1526 if (baseType->IsETSArrayType()) { in Check()
1527 if (expr->Property()->AsIdentifier()->Name().Is("length")) { in Check()
1528 return expr->AdjustType(checker, checker->GlobalIntType()); in Check()
1531 return expr->SetAndAdjustType(checker, checker->GlobalETSObjectType()); in Check()
1534 if (baseType->IsETSObjectType()) { in Check()
1535 return expr->SetAndAdjustType(checker, baseType->AsETSObjectType()); in Check()
1539 if (baseType->IsETSEnumType()) { in Check()
1540 return CheckEnumMemberExpression(baseType->AsETSEnumType(), expr); in Check()
1543 if (baseType->IsETSUnionType()) { in Check()
1544 return expr->AdjustType(checker, expr->CheckUnionMember(checker, baseType)); in Check()
1546 TypeErrorOnMissingProperty(expr, baseType, checker); in Check()
1547 return expr->TsType(); in Check()
1550 checker::Type *ETSAnalyzer::PreferredType(ir::ObjectExpression *expr) const in PreferredType()
1552 return expr->preferredType_; in PreferredType()
1555 checker::Type *ETSAnalyzer::CheckDynamic(ir::ObjectExpression *expr) const in CheckDynamic()
1557 ETSChecker *checker = GetETSChecker(); in CheckDynamic() local
1558 for (ir::Expression *propExpr : expr->Properties()) { in CheckDynamic()
1559 ASSERT(propExpr->IsProperty()); in CheckDynamic()
1560 ir::Property *prop = propExpr->AsProperty(); in CheckDynamic()
1561 ir::Expression *value = prop->Value(); in CheckDynamic()
1562 value->Check(checker); in CheckDynamic()
1563 ASSERT(value->TsType()); in CheckDynamic()
1566 expr->SetTsType(expr->PreferredType()); in CheckDynamic()
1567 return expr->PreferredType(); in CheckDynamic()
1570 static bool ValidatePreferredType(ir::ObjectExpression *expr, ETSChecker *checker) in ValidatePreferredType() argument
1572 auto preferredType = expr->PreferredType(); in ValidatePreferredType()
1574 checker->LogTypeError({"need to specify target type for class composite"}, expr->Start()); in ValidatePreferredType()
1578 if (!preferredType->IsETSObjectType()) { in ValidatePreferredType()
1579 checker->LogTypeError( in ValidatePreferredType()
1580 …type for class composite needs to be an object type, found '", preferredType, "'"}, expr->Start()); in ValidatePreferredType()
1587 static void SetTypeforRecordProperties(const ir::ObjectExpression *expr, checker::ETSObjectType *ob… in SetTypeforRecordProperties()
1588 ETSChecker *checker) in SetTypeforRecordProperties() argument
1590 auto recordProperties = expr->Properties(); in SetTypeforRecordProperties()
1591 auto typeArguments = objType->TypeArguments(); in SetTypeforRecordProperties()
1595 if (!recordProperty->AsProperty()->Value()->IsObjectExpression()) { in SetTypeforRecordProperties()
1598 auto recordPropertyExpr = recordProperty->AsProperty()->Value()->AsObjectExpression(); in SetTypeforRecordProperties()
1599 recordPropertyExpr->SetPreferredType(valueType); in SetTypeforRecordProperties()
1600 recordPropertyExpr->Check(checker); in SetTypeforRecordProperties()
1604 checker::Type *ETSAnalyzer::Check(ir::ObjectExpression *expr) const in Check()
1606 ETSChecker *checker = GetETSChecker(); in Check() local
1607 if (expr->TsType() != nullptr) { in Check()
1608 return expr->TsType(); in Check()
1611 if (!ValidatePreferredType(expr, checker)) { in Check()
1612 expr->SetTsType(checker->GlobalTypeError()); in Check()
1613 return expr->TsType(); in Check()
1616 if (expr->PreferredType()->IsETSDynamicType()) { in Check()
1620 checker::ETSObjectType *objType = expr->PreferredType()->AsETSObjectType(); in Check()
1621 if (objType->HasObjectFlag(checker::ETSObjectFlags::INTERFACE)) { in Check()
1625 // Here we just set the type to pass the checker in Check()
1626 CheckObjectExprProps(expr, checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD | in Check()
1627 checker::PropertySearchFlags::SEARCH_IN_INTERFACES); in Check()
1628 expr->SetTsType(objType); in Check()
1632 if (objType->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT)) { in Check()
1633checker->LogTypeError({"target type for class composite ", objType->Name(), " is not instantiable"… in Check()
1634 expr->Start()); in Check()
1635 expr->SetTsType(checker->GlobalTypeError()); in Check()
1636 return expr->TsType(); in Check()
1639 if (expr->PreferredType()->ToAssemblerName().str() == "escompat.Record" || in Check()
1640 expr->PreferredType()->ToAssemblerName().str() == "escompat.Map") { in Check()
1643 // Here we just set the type to pass the checker in Check()
1645 expr->SetTsType(objType); in Check()
1646 SetTypeforRecordProperties(expr, objType, checker); in Check()
1651 for (checker::Signature *sig : objType->ConstructSignatures()) { in Check()
1652 if (sig->Params().empty()) { in Check()
1654 checker->ValidateSignatureAccessibility(objType, nullptr, sig, expr->Start()); in Check()
1659checker->LogTypeError({"type ", objType->Name(), " has no parameterless constructor"}, expr->Start… in Check()
1660 expr->SetTsType(checker->GlobalTypeError()); in Check()
1661 return expr->TsType(); in Check()
1664 CheckObjectExprProps(expr, checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD | in Check()
1665 checker::PropertySearchFlags::SEARCH_IN_BASE | in Check()
1666 checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD); in Check()
1668 expr->SetTsType(objType); in Check()
1672 void ETSAnalyzer::CheckObjectExprProps(const ir::ObjectExpression *expr, checker::PropertySearchFla… in CheckObjectExprProps()
1674 ETSChecker *checker = GetETSChecker(); in CheckObjectExprProps() local
1675 checker::ETSObjectType *objType = expr->PreferredType()->AsETSObjectType(); in CheckObjectExprProps()
1677 for (ir::Expression *propExpr : expr->Properties()) { in CheckObjectExprProps()
1678 if (!propExpr->IsProperty()) { in CheckObjectExprProps()
1679checker->LogTypeError({"The object literal properties must be key-value pairs"}, expr->Start()); in CheckObjectExprProps()
1682 ir::Property *prop = propExpr->AsProperty(); in CheckObjectExprProps()
1683 ir::Expression *key = prop->Key(); in CheckObjectExprProps()
1684 ir::Expression *value = prop->Value(); in CheckObjectExprProps()
1687 if (key->IsStringLiteral()) { in CheckObjectExprProps()
1688 pname = key->AsStringLiteral()->Str(); in CheckObjectExprProps()
1689 } else if (key->IsIdentifier()) { in CheckObjectExprProps()
1690 pname = key->AsIdentifier()->Name(); in CheckObjectExprProps()
1692checker->LogTypeError({"key in class composite should be either identifier or string literal"}, in CheckObjectExprProps()
1693 expr->Start()); in CheckObjectExprProps()
1696 varbinder::LocalVariable *lv = objType->GetProperty(pname, searchFlags); in CheckObjectExprProps()
1698checker->LogTypeError({"type ", objType->Name(), " has no property named ", pname}, propExpr->Star… in CheckObjectExprProps()
1701 checker->ValidatePropertyAccess(lv, objType, propExpr->Start()); in CheckObjectExprProps()
1703 if (key->IsIdentifier()) { in CheckObjectExprProps()
1704 key->AsIdentifier()->SetVariable(lv); in CheckObjectExprProps()
1707 auto *propType = checker->GetTypeOfVariable(lv); in CheckObjectExprProps()
1708 key->SetTsType(propType); in CheckObjectExprProps()
1710 if (value->IsObjectExpression()) { in CheckObjectExprProps()
1711 value->AsObjectExpression()->SetPreferredType(propType); in CheckObjectExprProps()
1713 value->SetTsType(value->Check(checker)); in CheckObjectExprProps()
1715 auto *const valueType = value->TsType(); in CheckObjectExprProps()
1716 … const checker::Type *sourceType = checker->TryGettingFunctionTypeFromInvokeFunction(valueType); in CheckObjectExprProps()
1717 … const checker::Type *targetType = checker->TryGettingFunctionTypeFromInvokeFunction(propType); in CheckObjectExprProps()
1719 checker::AssignmentContext( in CheckObjectExprProps()
1720 checker->Relation(), value, valueType, propType, value->Start(), in CheckObjectExprProps()
1724 if (objType->HasObjectFlag(ETSObjectFlags::REQUIRED)) { in CheckObjectExprProps()
1725 checker->ValidateObjectLiteralForRequiredType(objType, expr); in CheckObjectExprProps()
1729 checker::Type *ETSAnalyzer::Check(ir::OpaqueTypeNode *expr) const in Check()
1731 return expr->TsType(); in Check()
1734 checker::Type *ETSAnalyzer::Check(ir::SequenceExpression *expr) const in Check()
1736 ETSChecker *checker = GetETSChecker(); in Check() local
1737 if (expr->TsType() != nullptr) { in Check()
1738 return expr->TsType(); in Check()
1741 for (auto *it : expr->Sequence()) { in Check()
1742 it->Check(checker); in Check()
1744 ASSERT(!expr->Sequence().empty()); in Check()
1745 expr->SetTsType(expr->Sequence().back()->TsType()); in Check()
1749 checker::Type *ETSAnalyzer::Check(ir::SuperExpression *expr) const in Check()
1751 ETSChecker *checker = GetETSChecker(); in Check() local
1752 if (expr->TsType() != nullptr) { in Check()
1753 return expr->TsType(); in Check()
1756 …expr->SetTsType(checker->CheckThisOrSuperAccess(expr, checker->Context().ContainingClass()->SuperT… in Check()
1757 return expr->TsType(); in Check()
1760 checker::Type *ETSAnalyzer::Check(ir::TemplateLiteral *expr) const in Check()
1762 ETSChecker *checker = GetETSChecker(); in Check() local
1763 if (expr->TsType() != nullptr) { in Check()
1764 return expr->TsType(); in Check()
1767 if (expr->Quasis().size() != expr->Expressions().size() + 1U) { in Check()
1768 checker->LogTypeError("Invalid string template expression", expr->Start()); in Check()
1769 expr->SetTsType(checker->GlobalTypeError()); in Check()
1770 return expr->TsType(); in Check()
1773 for (auto *it : expr->Expressions()) { in Check()
1774 it->Check(checker); in Check()
1777 for (auto *it : expr->Quasis()) { in Check()
1778 it->Check(checker); in Check()
1781 expr->SetTsType(checker->GlobalBuiltinETSStringType()); in Check()
1782 return expr->TsType(); in Check()
1785 checker::Type *ETSAnalyzer::Check(ir::ThisExpression *expr) const in Check()
1787 ETSChecker *checker = GetETSChecker(); in Check() local
1788 if (expr->TsType() != nullptr) { in Check()
1789 return expr->TsType(); in Check()
1813 …auto *variable = checker->AsETSChecker()->Scope()->Find(varbinder::VarBinder::MANDATORY_PARAM_THIS… in Check()
1814 if (checker->HasStatus(checker::CheckerStatus::IN_INSTANCE_EXTENSION_METHOD)) { in Check()
1816 expr->SetTsType(variable->TsType()); in Check()
1818 …expr->SetTsType(checker->CheckThisOrSuperAccess(expr, checker->Context().ContainingClass(), "this"… in Check()
1821 return expr->TsType(); in Check()
1825 static checker::Type *GetTypeOfStringType(checker::Type *argType, ETSChecker *checker) in GetTypeOfStringType() argument
1827 if (auto unboxed = checker->MaybeUnboxType(argType); unboxed->IsETSPrimitiveType()) { in GetTypeOfStringType()
1828 switch (checker->TypeKind(unboxed)) { in GetTypeOfStringType()
1830 return checker->CreateETSStringLiteralType("boolean"); in GetTypeOfStringType()
1838 return checker->CreateETSStringLiteralType("number"); in GetTypeOfStringType()
1840 … return checker->CreateETSStringLiteralType(argType == unboxed ? "number" : "object"); in GetTypeOfStringType()
1842 … return checker->CreateETSStringLiteralType(argType == unboxed ? "string" : "object"); in GetTypeOfStringType()
1847 if (argType->IsETSUndefinedType()) { in GetTypeOfStringType()
1848 return checker->CreateETSStringLiteralType("undefined"); in GetTypeOfStringType()
1850 if (argType->IsETSArrayType() || argType->IsETSNullType()) { in GetTypeOfStringType()
1851 return checker->CreateETSStringLiteralType("object"); in GetTypeOfStringType()
1853 if (argType->IsETSStringType() || argType->IsETSStringEnumType()) { in GetTypeOfStringType()
1854 return checker->CreateETSStringLiteralType("string"); in GetTypeOfStringType()
1856 if (argType->IsETSBigIntType()) { in GetTypeOfStringType()
1857 return checker->CreateETSStringLiteralType("bigint"); in GetTypeOfStringType()
1859 if (argType->IsETSFunctionType()) { in GetTypeOfStringType()
1860 return checker->CreateETSStringLiteralType("function"); in GetTypeOfStringType()
1863 return checker->GlobalBuiltinETSStringType(); in GetTypeOfStringType()
1866 static checker::Type *ComputeTypeOfType(ETSChecker *checker, checker::Type *argType) in ComputeTypeOfType() argument
1868 checker::Type *ret = nullptr; in ComputeTypeOfType()
1869 ArenaVector<checker::Type *> types(checker->Allocator()->Adapter()); in ComputeTypeOfType()
1870 if (argType->IsETSUnionType()) { in ComputeTypeOfType()
1871 for (auto *it : argType->AsETSUnionType()->ConstituentTypes()) { in ComputeTypeOfType()
1872 checker::Type *elType = ComputeTypeOfType(checker, it); in ComputeTypeOfType()
1875 ret = checker->CreateETSUnionType(std::move(types)); in ComputeTypeOfType()
1877 ret = GetTypeOfStringType(argType, checker); in ComputeTypeOfType()
1882 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TypeofExpression *expr) const in Check()
1884 ETSChecker *checker = GetETSChecker(); in Check() local
1885 if (expr->TsType() != nullptr) { in Check()
1886 return expr->TsType(); in Check()
1889 expr->Argument()->Check(checker); in Check()
1890 expr->SetTsType(ComputeTypeOfType(checker, expr->Argument()->TsType())); in Check()
1891 return expr->TsType(); in Check()
1894 checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const in Check()
1896 ETSChecker *checker = GetETSChecker(); in Check() local
1898 if (expr->TsType() != nullptr) { in Check()
1899 return expr->TsType(); in Check()
1902 auto argType = expr->argument_->Check(checker); in Check()
1903 const auto isCondExpr = expr->OperatorType() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK; in Check()
1904checker::Type *operandType = checker->ApplyUnaryOperatorPromotion(argType, true, true, isCondExpr); in Check()
1906 …isCondExpr ? checker->MaybeUnboxConditionalInRelation(argType) : checker->MaybeUnboxInRelation(arg… in Check()
1908 …if (argType != nullptr && argType->IsETSBigIntType() && argType->HasTypeFlag(checker::TypeFlag::BI… in Check()
1909 switch (expr->OperatorType()) { in Check()
1911checker::Type *type = checker->CreateETSBigIntLiteralType(argType->AsETSBigIntType()->GetValue()); in Check()
1914 type->RemoveTypeFlag(checker::TypeFlag::CONSTANT); in Check()
1915 expr->argument_->SetTsType(type); in Check()
1916 expr->SetTsType(type); in Check()
1917 return expr->TsType(); in Check()
1926 if (argType != nullptr && argType->IsETSBigIntType()) { in Check()
1927 switch (expr->OperatorType()) { in Check()
1931 expr->SetTsType(argType); in Check()
1932 return expr->TsType(); in Check()
1939 SetTsTypeForUnaryExpression(checker, expr, operandType); in Check()
1941 if ((argType != nullptr) && argType->IsETSObjectType() && (unboxedOperandType != nullptr) && in Check()
1942 unboxedOperandType->IsETSPrimitiveType()) { in Check()
1943 expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedOperandType)); in Check()
1946 checker->Context().CheckUnarySmartCastCondition(expr); in Check()
1948 return expr->TsType(); in Check()
1951 checker::Type *ETSAnalyzer::Check(ir::UpdateExpression *expr) const in Check()
1953 ETSChecker *checker = GetETSChecker(); in Check() local
1954 if (expr->TsType() != nullptr) { in Check()
1955 return expr->TsType(); in Check()
1958 checker::Type *operandType = expr->argument_->Check(checker); in Check()
1959 if (expr->Argument()->IsIdentifier()) { in Check()
1960 checker->ValidateUnaryOperatorOperand(expr->Argument()->AsIdentifier()->Variable()); in Check()
1961 } else if (expr->Argument()->IsTSAsExpression()) { in Check()
1962 …if (auto *const asExprVar = expr->Argument()->AsTSAsExpression()->Variable(); asExprVar != nullptr… in Check()
1963 checker->ValidateUnaryOperatorOperand(asExprVar); in Check()
1965 } else if (expr->Argument()->IsTSNonNullExpression()) { in Check()
1966 if (auto *const nonNullExprVar = expr->Argument()->AsTSNonNullExpression()->Variable(); in Check()
1968 checker->ValidateUnaryOperatorOperand(nonNullExprVar); in Check()
1971 ASSERT(expr->Argument()->IsMemberExpression()); in Check()
1972 varbinder::LocalVariable *propVar = expr->argument_->AsMemberExpression()->PropVar(); in Check()
1974 checker->ValidateUnaryOperatorOperand(propVar); in Check()
1978 if (operandType->IsETSBigIntType()) { in Check()
1979 expr->SetTsType(operandType); in Check()
1980 return expr->TsType(); in Check()
1983 auto unboxedType = checker->MaybeUnboxInRelation(operandType); in Check()
1984 …if (unboxedType == nullptr || !unboxedType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUME… in Check()
1985 checker->LogTypeError("Bad operand type, the type of the operand must be numeric type.", in Check()
1986 expr->Argument()->Start()); in Check()
1987 expr->SetTsType(checker->GlobalTypeError()); in Check()
1988 return expr->TsType(); in Check()
1991 if (operandType->IsETSObjectType()) { in Check()
1992 expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedType) | in Check()
1993 checker->GetBoxingFlag(unboxedType)); in Check()
1996 expr->SetTsType(operandType); in Check()
1997 return expr->TsType(); in Check()
2001 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::BigIntLiteral *expr) const in Check()
2003 ETSChecker *checker = GetETSChecker(); in Check() local
2004 expr->SetTsType(checker->CreateETSBigIntLiteralType(expr->Str())); in Check()
2005 return expr->TsType(); in Check()
2008 checker::Type *ETSAnalyzer::Check(ir::BooleanLiteral *expr) const in Check()
2010 ETSChecker *checker = GetETSChecker(); in Check() local
2011 if (expr->TsType() == nullptr) { in Check()
2012 expr->SetTsType(checker->CreateETSBooleanType(expr->Value())); in Check()
2014 return expr->TsType(); in Check()
2017 checker::Type *ETSAnalyzer::Check(ir::CharLiteral *expr) const in Check()
2019 ETSChecker *checker = GetETSChecker(); in Check() local
2020 if (expr->TsType() == nullptr) { in Check()
2021 expr->SetTsType(checker->Allocator()->New<checker::CharType>(expr->Char())); in Check()
2023 return expr->TsType(); in Check()
2026 checker::Type *ETSAnalyzer::Check(ir::NullLiteral *expr) const in Check()
2028 ETSChecker *checker = GetETSChecker(); in Check() local
2029 if (expr->TsType() == nullptr) { in Check()
2030 expr->SetTsType(checker->GlobalETSNullType()); in Check()
2032 return expr->TsType(); in Check()
2035 checker::Type *ETSAnalyzer::Check(ir::NamespaceDeclaration *st) const in Check()
2037 ETSChecker *checker = GetETSChecker(); in Check() local
2038 st->Definition()->Check(checker); in Check()
2042 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::NamespaceDefinition *st) const in Check()
2047 checker::Type *ETSAnalyzer::Check(ir::NumberLiteral *expr) const in Check()
2049 ETSChecker *checker = GetETSChecker(); in Check() local
2050 if (expr->Number().IsInt()) { in Check()
2051 expr->SetTsType(checker->CreateIntType(expr->Number().GetInt())); in Check()
2052 return expr->TsType(); in Check()
2055 if (expr->Number().IsLong()) { in Check()
2056 expr->SetTsType(checker->CreateLongType(expr->Number().GetLong())); in Check()
2057 return expr->TsType(); in Check()
2060 if (expr->Number().IsFloat()) { in Check()
2061 expr->SetTsType(checker->CreateFloatType(expr->Number().GetFloat())); in Check()
2062 return expr->TsType(); in Check()
2065 expr->SetTsType(checker->CreateDoubleType(expr->Number().GetDouble())); in Check()
2066 return expr->TsType(); in Check()
2069 checker::Type *ETSAnalyzer::Check(ir::StringLiteral *expr) const in Check()
2071 ETSChecker *checker = GetETSChecker(); in Check() local
2072 if (expr->TsType() == nullptr) { in Check()
2073 expr->SetTsType(checker->CreateETSStringLiteralType(expr->Str())); in Check()
2075 return expr->TsType(); in Check()
2078 checker::Type *ETSAnalyzer::Check(ir::ImportDeclaration *st) const in Check()
2080 ETSChecker *checker = GetETSChecker(); in Check() local
2081 checker::Type *type = nullptr; in Check()
2082 for (auto *spec : st->Specifiers()) { in Check()
2083 if (spec->IsImportNamespaceSpecifier()) { in Check()
2084 type = spec->AsImportNamespaceSpecifier()->Check(checker); in Check()
2091 checker::Type *ETSAnalyzer::Check(ir::ImportNamespaceSpecifier *st) const in Check()
2093 ETSChecker *checker = GetETSChecker(); in Check() local
2094 if (st->Local()->Name().Empty()) { in Check()
2098 if (st->Local()->AsIdentifier()->TsType() != nullptr) { in Check()
2099 return st->Local()->TsType(); in Check()
2102 auto *importDecl = st->Parent()->AsETSImportDeclaration(); in Check()
2104 if (importDecl->IsPureDynamic()) { in Check()
2105 auto *type = checker->GlobalBuiltinDynamicType(importDecl->Language()); in Check()
2106 checker->SetrModuleObjectTsType(st->Local(), type); in Check()
2110 return checker->GetImportSpecifierObjectType(importDecl, st->Local()->AsIdentifier()); in Check()
2114 checker::Type *ETSAnalyzer::Check(ir::AssertStatement *st) const in Check()
2116 ETSChecker *checker = GetETSChecker(); in Check() local
2117 if (!(st->Test()->Check(checker)->HasTypeFlag(TypeFlag::ETS_BOOLEAN | TypeFlag::BOOLEAN_LIKE) || in Check()
2118 st->Test()->Check(checker)->ToString() == "Boolean")) { in Check()
2119checker->LogTypeError("Bad operand type, the type of the operand must be boolean type.", st->Test(… in Check()
2122 if (st->Second() != nullptr) { in Check()
2123 auto *msgType = st->second_->Check(checker); in Check()
2125 if (!msgType->IsETSStringType()) { in Check()
2126 checker->LogTypeError("Assert message must be string", st->Second()->Start()); in Check()
2133 checker::Type *ETSAnalyzer::Check(ir::BlockStatement *st) const in Check()
2135 ETSChecker *checker = GetETSChecker(); in Check() local
2136 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
2140 //---- Don't modify this to iterator, as it may break things during checking in Check()
2141 for (std::size_t idx = 0; idx < st->Statements().size(); ++idx) { in Check()
2142 auto *stmt = st->Statements()[idx]; in Check()
2143 stmt->Check(checker); in Check()
2146 if (auto const tb = st->trailingBlocks_.find(stmt); tb != st->trailingBlocks_.end()) { in Check()
2147 auto *const trailingBlock = tb->second; in Check()
2148 trailingBlock->Check(checker); in Check()
2149 st->Statements().emplace(std::next(st->Statements().begin() + idx), trailingBlock); in Check()
2153 if (UNLIKELY(checker->GetDebugInfoPlugin() != nullptr)) { in Check()
2154 // Compilation in eval-mode might require to create additional statements. in Check()
2156 checker->GetDebugInfoPlugin()->AddPrologueEpilogue(st); in Check()
2160 if (auto const *const scope = st->Scope(); in Check()
2161 scope->IsFunctionScope() && st->Parent()->Parent()->Parent()->IsMethodDefinition()) { in Check()
2163 checker->Context().ClearSmartCasts(); in Check()
2164 } else if (!scope->IsGlobalScope()) { in Check()
2166 for (auto const *const decl : scope->Decls()) { in Check()
2167 if (decl->IsLetOrConstDecl() && decl->Node()->IsIdentifier()) { in Check()
2168 checker->Context().RemoveSmartCast(decl->Node()->AsIdentifier()->Variable()); in Check()
2176 checker::Type *ETSAnalyzer::Check(ir::BreakStatement *st) const in Check()
2178 ETSChecker *checker = GetETSChecker(); in Check() local
2179 auto node = checker->FindJumpTarget(st); in Check()
2181 return checker->GlobalTypeError(); in Check()
2183 st->SetTarget(*node); in Check()
2185 checker->Context().OnBreakStatement(st); in Check()
2189 checker::Type *ETSAnalyzer::Check(ir::ClassDeclaration *st) const in Check()
2191 ETSChecker *checker = GetETSChecker(); in Check() local
2192 st->Definition()->Check(checker); in Check()
2196 checker::Type *ETSAnalyzer::Check(ir::AnnotationDeclaration *st) const in Check()
2198 ETSChecker *checker = GetETSChecker(); in Check() local
2200 if (!st->Expr()->IsIdentifier()) { in Check()
2201 st->Expr()->Check(checker); in Check()
2204 for (auto *it : st->Properties()) { in Check()
2205 auto *property = it->AsClassProperty(); in Check()
2206 property->Check(checker); in Check()
2207 checker->CheckAnnotationPropertyType(property); in Check()
2210 … auto *annoDecl = st->GetBaseName()->Variable()->Declaration()->Node()->AsAnnotationDeclaration(); in Check()
2211 if (annoDecl != st && annoDecl->IsDeclare()) { in Check()
2212 checker->CheckAmbientAnnotation(st, annoDecl); in Check()
2217 checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const in Check()
2219 ETSChecker *checker = GetETSChecker(); in Check() local
2221 if (!st->GetBaseName()->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { in Check()
2222checker->LogTypeError({"'", st->GetBaseName()->Name(), "' is not an annotation."}, st->GetBaseName… in Check()
2226 … auto *annoDecl = st->GetBaseName()->Variable()->Declaration()->Node()->AsAnnotationDeclaration(); in Check()
2227 annoDecl->Check(checker); in Check()
2229 if (!st->Expr()->IsIdentifier()) { in Check()
2230 st->Expr()->Check(checker); in Check()
2233 for (auto *it : st->Properties()) { in Check()
2234 it->Check(checker); in Check()
2235 auto property = it->AsClassProperty(); in Check()
2236 if (property->Value() != nullptr && property->Value()->IsMemberExpression() && in Check()
2237 !property->TsType()->IsETSEnumType()) { in Check()
2238checker->LogTypeError("Invalid value for annotation field, expected a constant literal.", in Check()
2239 property->Value()->Start()); in Check()
2243 …ArenaUnorderedMap<util::StringView, ir::ClassProperty *> fieldMap {checker->Allocator()->Adapter()… in Check()
2244 for (auto *it : annoDecl->Properties()) { in Check()
2245 auto *field = it->AsClassProperty(); in Check()
2246 fieldMap.insert(std::make_pair(field->Id()->Name(), field)); in Check()
2249 if (annoDecl->Properties().size() < st->Properties().size()) { in Check()
2250 checker->LogTypeError( in Check()
2251 …mber of arguments provided for the annotation exceeds the number of fields defined.", st->Start()); in Check()
2255 if (st->Properties().size() == 1 && in Check()
2256 …st->Properties().at(0)->AsClassProperty()->Id()->Name() == compiler::Signatures::ANNOTATION_KEY_VA… in Check()
2257 checker->CheckSinglePropertyAnnotation(st, annoDecl); in Check()
2260 checker->CheckMultiplePropertiesAnnotation(st, annoDecl, fieldMap); in Check()
2263 checker->ProcessRequiredFields(fieldMap, st, checker); in Check()
2268 checker::Type *ETSAnalyzer::Check(ir::ContinueStatement *st) const in Check()
2270 ETSChecker *checker = GetETSChecker(); in Check() local
2271 auto node = checker->FindJumpTarget(st); in Check()
2273 return checker->GlobalTypeError(); in Check()
2275 st->SetTarget(*node); in Check()
2277 checker->AddStatus(CheckerStatus::MEET_CONTINUE); in Check()
2281 checker::Type *ETSAnalyzer::Check(ir::DoWhileStatement *st) const in Check()
2283 ETSChecker *checker = GetETSChecker(); in Check() local
2284 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
2287 auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st); in Check()
2289 checker->CheckTruthinessOfType(st->Test()); in Check()
2290 st->Body()->Check(checker); in Check()
2292 checker->Context().ExitLoop(smartCasts, clearFlag, st); in Check()
2296 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::EmptyStatement *st) const in Check()
2301 checker::Type *ETSAnalyzer::Check(ir::ExpressionStatement *st) const in Check()
2303 ETSChecker *checker = GetETSChecker(); in Check() local
2304 return st->GetExpression()->Check(checker); in Check()
2307 static bool ValidateAndProcessIteratorType(ETSChecker *checker, Type *elemType, ir::ForOfStatement … in ValidateAndProcessIteratorType() argument
2309 checker::Type *iterType = GetIteratorType(checker, elemType, st->Left()); in ValidateAndProcessIteratorType()
2310 if (iterType->IsTypeError()) { in ValidateAndProcessIteratorType()
2313 auto *const relation = checker->Relation(); in ValidateAndProcessIteratorType()
2314 relation->SetFlags(checker::TypeRelationFlag::ASSIGNMENT_CONTEXT); in ValidateAndProcessIteratorType()
2315 relation->SetNode(st->Left()->IsVariableDeclaration() in ValidateAndProcessIteratorType()
2316 ? st->Left()->AsVariableDeclaration()->Declarators().front()->Id() in ValidateAndProcessIteratorType()
2317 : st->Left()->AsIdentifier()); in ValidateAndProcessIteratorType()
2319 if (!relation->IsAssignableTo(elemType, iterType)) { in ValidateAndProcessIteratorType()
2321 …ss << "Source element type '" << elemType->ToString() << "' is not assignable to the loop iterator… in ValidateAndProcessIteratorType()
2322 << iterType->ToString() << "'."; in ValidateAndProcessIteratorType()
2323 checker->LogTypeError(ss.str(), st->Start()); in ValidateAndProcessIteratorType()
2327 relation->SetNode(nullptr); in ValidateAndProcessIteratorType()
2328 relation->SetFlags(checker::TypeRelationFlag::NONE); in ValidateAndProcessIteratorType()
2330 …if (iterType->Variable() == nullptr && !iterType->IsETSObjectType() && elemType->IsETSObjectType()… in ValidateAndProcessIteratorType()
2331 st->Left()->IsVariableDeclaration()) { in ValidateAndProcessIteratorType()
2332 for (auto &declarator : st->Left()->AsVariableDeclaration()->Declarators()) { in ValidateAndProcessIteratorType()
2333 checker->AddBoxingUnboxingFlagsToNode(declarator->Id(), iterType); in ValidateAndProcessIteratorType()
2338 // NOLINTBEGIN(modernize-avoid-c-arrays)
2340 "Cannot determine source expression type in the 'for-of' statement.";
2342 "'For-of' statement source expression is not of iterable type.";
2343 // NOLINTEND(modernize-avoid-c-arrays)
2345 checker::Type *ETSAnalyzer::Check(ir::ForOfStatement *const st) const in Check()
2347 ETSChecker *checker = GetETSChecker(); in Check() local
2348 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
2351 auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st); in Check()
2353 checker::Type *const exprType = st->Right()->Check(checker); in Check()
2355 checker->LogTypeError(MISSING_SOURCE_EXPR_TYPE, st->Right()->Start()); in Check()
2356 return checker->GlobalTypeError(); in Check()
2359 checker::Type *elemType = nullptr; in Check()
2361 if (exprType->IsETSStringType()) { in Check()
2362 elemType = checker->GetGlobalTypesHolder()->GlobalCharType(); in Check()
2363 } else if (exprType->IsETSArrayType()) { in Check()
2364 elemType = exprType->AsETSArrayType()->ElementType(); in Check()
2365 …} else if (exprType->IsETSObjectType() || exprType->IsETSUnionType() || exprType->IsETSTypeParamet… in Check()
2366 elemType = st->CheckIteratorMethod(checker); in Check()
2370 checker->LogTypeError(INVALID_SOURCE_EXPR_TYPE, st->Right()->Start()); in Check()
2371 return checker->GlobalTypeError(); in Check()
2374 st->Left()->Check(checker); in Check()
2376 if (!ValidateAndProcessIteratorType(checker, elemType, st)) { in Check()
2377 return checker->GlobalTypeError(); in Check()
2380 st->Body()->Check(checker); in Check()
2382 checker->Context().ExitLoop(smartCasts, clearFlag, st); in Check()
2386 checker::Type *ETSAnalyzer::Check(ir::ForUpdateStatement *st) const in Check()
2388 ETSChecker *checker = GetETSChecker(); in Check() local
2389 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
2392 auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st); in Check()
2394 if (st->Init() != nullptr) { in Check()
2395 st->Init()->Check(checker); in Check()
2398 if (st->Test() != nullptr) { in Check()
2399 checker->CheckTruthinessOfType(st->Test()); in Check()
2402 if (st->Update() != nullptr) { in Check()
2403 st->Update()->Check(checker); in Check()
2406 st->Body()->Check(checker); in Check()
2408 checker->Context().ExitLoop(smartCasts, clearFlag, st); in Check()
2412 checker::Type *ETSAnalyzer::Check(ir::IfStatement *st) const in Check()
2414 ETSChecker *const checker = GetETSChecker(); in Check() local
2416 SmartCastArray smartCasts = checker->Context().EnterTestExpression(); in Check()
2417 checker->CheckTruthinessOfType(st->Test()); in Check()
2418 SmartCastTypes testedTypes = checker->Context().ExitTestExpression(); in Check()
2421 checker->ApplySmartCast(variable, consequentType); in Check()
2425 checker->Context().EnterPath(); in Check()
2426 st->Consequent()->Check(checker); in Check()
2427 bool const consequentTerminated = checker->Context().ExitPath(); in Check()
2428 SmartCastArray consequentSmartCasts = checker->Context().CloneSmartCasts(); in Check()
2431 checker->Context().RestoreSmartCasts(smartCasts); in Check()
2435 checker->ApplySmartCast(variable, alternateType); in Check()
2439 if (st->Alternate() != nullptr) { in Check()
2440 checker->Context().EnterPath(); in Check()
2441 st->Alternate()->Check(checker); in Check()
2442 bool const alternateTerminated = checker->Context().ExitPath(); in Check()
2446 checker->Context().RestoreSmartCasts(consequentSmartCasts); in Check()
2449 checker->Context().RestoreSmartCasts(smartCasts); in Check()
2453 checker->Context().CombineSmartCasts(consequentSmartCasts); in Check()
2458 checker->Context().CombineSmartCasts(consequentSmartCasts); in Check()
2465 checker::Type *ETSAnalyzer::Check(ir::LabelledStatement *st) const in Check()
2467 ETSChecker *checker = GetETSChecker(); in Check() local
2468 st->body_->Check(checker); in Check()
2473checker::Type *&funcReturnType, ir::TypeNode *returnTypeAnnotation, in CheckInferredFunctionReturnType()
2474 ETSChecker *checker) const in CheckInferredFunctionReturnType()
2476 funcReturnType = returnTypeAnnotation->GetType(checker); in CheckInferredFunctionReturnType()
2477 …if (returnTypeAnnotation->IsTSThisType() && (st->Argument() == nullptr || !st->Argument()->IsThisE… in CheckInferredFunctionReturnType()
2478checker->LogTypeError("The only allowed return value is 'this' if the method's return type is the … in CheckInferredFunctionReturnType()
2479 st->Start()); in CheckInferredFunctionReturnType()
2485 if (st->argument_ == nullptr) { in CheckInferredFunctionReturnType()
2486 if (!funcReturnType->IsETSVoidType() && funcReturnType != checker->GlobalVoidType() && in CheckInferredFunctionReturnType()
2487 !funcReturnType->IsETSAsyncFuncReturnType()) { in CheckInferredFunctionReturnType()
2488 checker->LogTypeError("Missing return value.", st->Start()); in CheckInferredFunctionReturnType()
2491 funcReturnType = checker->GlobalVoidType(); in CheckInferredFunctionReturnType()
2493 const auto name = containingFunc->Scope()->InternalName().Mutf8(); in CheckInferredFunctionReturnType()
2494 if (!CheckArgumentVoidType(funcReturnType, checker, name, st)) { in CheckInferredFunctionReturnType()
2498 if (st->argument_->IsObjectExpression()) { in CheckInferredFunctionReturnType()
2499 st->argument_->AsObjectExpression()->SetPreferredType(funcReturnType); in CheckInferredFunctionReturnType()
2501 if (st->argument_->IsMemberExpression()) { in CheckInferredFunctionReturnType()
2502checker->SetArrayPreferredTypeForNestedMemberExpressions(st->argument_->AsMemberExpression(), in CheckInferredFunctionReturnType()
2506 if (st->argument_->IsArrayExpression()) { in CheckInferredFunctionReturnType()
2507 st->argument_->AsArrayExpression()->SetPreferredType(funcReturnType); in CheckInferredFunctionReturnType()
2510 checker::Type *argumentType = st->argument_->Check(checker); in CheckInferredFunctionReturnType()
2511 …return CheckReturnType(checker, funcReturnType, argumentType, st->argument_, containingFunc->IsAsy… in CheckInferredFunctionReturnType()
2516 checker::Type *ETSAnalyzer::GetFunctionReturnType(ir::ReturnStatement *st, ir::ScriptFunction *cont… in GetFunctionReturnType()
2518 …ASSERT(containingFunc->ReturnTypeAnnotation() != nullptr || containingFunc->Signature()->ReturnTyp… in GetFunctionReturnType()
2520 ETSChecker *checker = GetETSChecker(); in GetFunctionReturnType() local
2521 checker::Type *funcReturnType = nullptr; in GetFunctionReturnType()
2523 …if (auto *const returnTypeAnnotation = containingFunc->ReturnTypeAnnotation(); returnTypeAnnotatio… in GetFunctionReturnType()
2524 …eckInferredFunctionReturnType(st, containingFunc, funcReturnType, returnTypeAnnotation, checker)) { in GetFunctionReturnType()
2525 return checker->GlobalTypeError(); in GetFunctionReturnType()
2529 … if (containingFunc->Signature()->HasSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE)) { in GetFunctionReturnType()
2530 InferReturnType(checker, containingFunc, funcReturnType, in GetFunctionReturnType()
2531 … st->argument_); // This removes the NEED_RETURN_TYPE flag, so only the first return in GetFunctionReturnType()
2535 ProcessReturnStatements(checker, containingFunc, funcReturnType, st, in GetFunctionReturnType()
2536 … st->argument_); // and the remaining return statements will get processed here. in GetFunctionReturnType()
2540 …if ((st->argument_ != nullptr) && st->argument_->IsArrayExpression() && funcReturnType->IsArrayTyp… in GetFunctionReturnType()
2541 checker->ModifyPreferredType(st->argument_->AsArrayExpression(), funcReturnType); in GetFunctionReturnType()
2542 st->argument_->Check(checker); in GetFunctionReturnType()
2548 checker::Type *ETSAnalyzer::Check(ir::ReturnStatement *st) const in Check()
2550 ETSChecker *checker = GetETSChecker(); in Check() local
2553 ASSERT(ancestor && ancestor->IsScriptFunction()); in Check()
2554 auto *containingFunc = ancestor->AsScriptFunction(); in Check()
2556 checker->AddStatus(CheckerStatus::MEET_RETURN); in Check()
2558 if (containingFunc->IsConstructor()) { in Check()
2559 if (st->argument_ != nullptr) { in Check()
2560checker->LogTypeError("Return statement with expression isn't allowed in constructor.", st->Start(… in Check()
2561 return checker->GlobalTypeError(); in Check()
2566 st->returnType_ = GetFunctionReturnType(st, containingFunc); in Check()
2568 if (containingFunc->ReturnTypeAnnotation() == nullptr) { in Check()
2569 containingFunc->AddReturnStatement(st); in Check()
2575 checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const in Check()
2577 ETSChecker *checker = GetETSChecker(); in Check() local
2578 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
2579 checker::SavedTypeRelationFlagsContext savedTypeRelationFlagCtx(checker->Relation(), in Check()
2580checker::TypeRelationFlag::NONE); in Check()
2582 auto *comparedExprType = checker->CheckSwitchDiscriminant(st->Discriminant()); in Check()
2583 …auto unboxedDiscType = (st->Discriminant()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UN… in Check()
2584 ? checker->MaybeUnboxInRelation(comparedExprType) in Check()
2587 SmartCastArray smartCasts = checker->Context().CloneSmartCasts(); in Check()
2590 for (auto &it : st->Cases()) { in Check()
2591 checker->Context().EnterPath(); in Check()
2592 …it->CheckAndTestCase(checker, comparedExprType, unboxedDiscType, st->Discriminant(), hasDefaultCas… in Check()
2593 bool const caseTerminated = checker->Context().ExitPath(); in Check()
2595 if (it != st->Cases().back()) { in Check()
2597 checker->Context().CombineSmartCasts(smartCasts); in Check()
2599 checker->Context().RestoreSmartCasts(smartCasts); in Check()
2605 checker->Context().AddBreakSmartCasts(st, checker->Context().CloneSmartCasts()); in Check()
2607 checker->Context().ClearSmartCasts(); in Check()
2613 checker->Context().AddBreakSmartCasts(st, std::move(smartCasts)); in Check()
2616 // Combine smart casts from all [non-terminated] case blocks with 'break' in Check()
2617 checker->Context().CombineBreakSmartCasts(st); in Check()
2619 checker->CheckForSameSwitchCases(st->Cases()); in Check()
2623 checker::Type *ETSAnalyzer::Check(ir::ThrowStatement *st) const in Check()
2625 ETSChecker *checker = GetETSChecker(); in Check() local
2626 auto *argType = st->argument_->Check(checker); in Check()
2627 checker->CheckExceptionOrErrorType(argType, st->Start()); in Check()
2629 if (checker->Relation()->IsAssignableTo(argType, checker->GlobalBuiltinExceptionType())) { in Check()
2630 checker->CheckThrowingStatements(st); in Check()
2633 checker->AddStatus(CheckerStatus::MEET_THROW); in Check()
2637 checker::Type *ETSAnalyzer::Check(ir::TryStatement *st) const in Check()
2639 ETSChecker *checker = GetETSChecker(); in Check() local
2640 std::vector<checker::ETSObjectType *> exceptions {}; in Check()
2643 auto smartCasts = checker->Context().CheckTryBlock(*st->Block()); in Check()
2644 st->Block()->Check(checker); in Check()
2647 for (auto *catchClause : st->CatchClauses()) { in Check()
2649checker->LogTypeError("Default catch clause should be the last in the try statement", catchClause- in Check()
2650 return checker->GlobalTypeError(); in Check()
2653 checker->Context().RestoreSmartCasts(smartCasts); in Check()
2655 if (auto const exceptionType = catchClause->Check(checker); in Check()
2656 exceptionType != nullptr && catchClause->Param() != nullptr) { in Check()
2657 auto *clauseType = exceptionType->AsETSObjectType(); in Check()
2658 checker->CheckExceptionClauseType(exceptions, catchClause, clauseType); in Check()
2662 defaultCatchFound = catchClause->IsDefaultCatchClause(); in Check()
2664 casts.emplace_back(checker->Context().CloneSmartCasts()); in Check()
2667 checker->Context().RestoreSmartCasts(smartCasts); in Check()
2670 checker->Context().CombineSmartCasts(cast); in Check()
2674 if (st->HasFinalizer()) { in Check()
2675 st->FinallyBlock()->Check(checker); in Check()
2681 checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const in Check()
2683 if (st->TsType() != nullptr) { in Check()
2684 return st->TsType(); in Check()
2687 ETSChecker *checker = GetETSChecker(); in Check() local
2688 ASSERT(st->Id()->IsIdentifier()); in Check()
2689 auto *const ident = st->Id()->AsIdentifier(); in Check()
2692 if (ident->Parent()->Parent()->AsVariableDeclaration()->Kind() == in Check()
2697 if (ident->IsOptionalDeclaration()) { in Check()
2701 …auto *const variableType = checker->CheckVariableDeclaration(ident, ident->TypeAnnotation(), st->I… in Check()
2704 …o define the actual type of Identifier so that smart cast can be used in further checker processing in Check()
2705 // NOTE: T_S and K_o_t_l_i_n don't act in such way, but we can try - why not? :) in Check()
2706 …if (auto *const initType = st->Init() != nullptr ? st->Init()->TsType() : nullptr; initType != nul… in Check()
2707 smartType = checker->ResolveSmartType(initType, variableType); in Check()
2709 // Top-level and captured variables are not processed here! in Check()
2710 if (!checker->Relation()->IsIdenticalTo(variableType, smartType)) { in Check()
2711 ident->SetTsType(smartType); in Check()
2712 checker->Context().SetSmartCast(ident->Variable(), smartType); in Check()
2716 st->SetTsType(smartType); in Check()
2720 checker::Type *ETSAnalyzer::Check(ir::VariableDeclaration *st) const in Check()
2722 ETSChecker *checker = GetETSChecker(); in Check() local
2723 for (auto *it : st->Declarators()) { in Check()
2724 it->Check(checker); in Check()
2730 checker::Type *ETSAnalyzer::Check(ir::WhileStatement *st) const in Check()
2732 ETSChecker *checker = GetETSChecker(); in Check() local
2733 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
2736 auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st); in Check()
2738 checker->CheckTruthinessOfType(st->Test()); in Check()
2739 st->Body()->Check(checker); in Check()
2741 checker->Context().ExitLoop(smartCasts, clearFlag, st); in Check()
2745 checker::Type *ETSAnalyzer::Check(ir::TSArrayType *node) const in Check()
2747 ETSChecker *checker = GetETSChecker(); in Check() local
2748 node->elementType_->Check(checker); in Check()
2749 node->SetTsType(node->GetType(checker)); in Check()
2751 const auto arrayType = node->TsType()->AsETSArrayType(); in Check()
2752 checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); in Check()
2756 checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const in Check()
2758 ETSChecker *checker = GetETSChecker(); in Check() local
2760 if (expr->TsType() != nullptr) { in Check()
2761 return expr->TsType(); in Check()
2764 auto *const targetType = expr->TypeAnnotation()->AsTypeNode()->GetType(checker); in Check()
2767 if (expr->Expr()->IsObjectExpression()) { in Check()
2768 expr->Expr()->AsObjectExpression()->SetPreferredType(targetType); in Check()
2771 if (expr->Expr()->IsArrayExpression()) { in Check()
2772 expr->Expr()->AsArrayExpression()->SetPreferredType(targetType); in Check()
2775 auto *const sourceType = expr->Expr()->Check(checker); in Check()
2776 if (sourceType->IsTypeError()) { in Check()
2777 expr->SetTsType(checker->GlobalTypeError()); in Check()
2778 return expr->TsType(); in Check()
2782 if (targetType->IsETSPrimitiveType() && sourceType->IsETSReferenceType()) { in Check()
2783 auto *const boxedTargetType = checker->MaybeBoxInRelation(targetType); in Check()
2784 if (!checker->Relation()->IsIdenticalTo(sourceType, boxedTargetType)) { in Check()
2785 expr->Expr()->AddAstNodeFlags(ir::AstNodeFlags::CHECKCAST); in Check()
2789 if (sourceType->DefinitelyETSNullish() && !targetType->PossiblyETSNullish()) { in Check()
2790checker->LogTypeError("Cannot cast 'null' or 'undefined' to non-nullish type.", expr->Expr()->Star… in Check()
2791 expr->SetTsType(checker->GlobalTypeError()); in Check()
2792 return expr->TsType(); in Check()
2795 const checker::CastingContext ctx( in Check()
2796 checker->Relation(), in Check()
2798checker::CastingContext::ConstructorData {expr->Expr(), sourceType, targetType, expr->Expr()->Star… in Check()
2800 if (sourceType->IsETSDynamicType() && targetType->IsLambdaObject()) { in Check()
2803 checker->BuildLambdaObjectClass(targetType->AsETSObjectType(), in Check()
2804 expr->TypeAnnotation()->AsETSFunctionType()->ReturnType()); in Check()
2806 expr->isUncheckedCast_ = ctx.UncheckedCast(); in Check()
2810 if (!expr->isUncheckedCast_ && targetType->IsETSArrayType()) { in Check()
2811 auto *const targetArrayType = targetType->AsETSArrayType(); in Check()
2812 checker->CreateBuiltinArraySignature(targetArrayType, targetArrayType->Rank()); in Check()
2815 if (targetType == checker->GetGlobalTypesHolder()->GlobalETSNeverType()) { in Check()
2816 checker->LogTypeError("Cast to 'never' is prohibited", expr->Start()); in Check()
2817 expr->SetTsType(checker->GlobalTypeError()); in Check()
2818 return expr->TsType(); in Check()
2821 checker->ComputeApparentType(targetType); in Check()
2822 expr->SetTsType(targetType); in Check()
2823 return expr->TsType(); in Check()
2826 checker::Type *ETSAnalyzer::Check(ir::TSEnumDeclaration *st) const in Check()
2828 ETSChecker *checker = GetETSChecker(); in Check() local
2829 varbinder::Variable *enumVar = st->Key()->Variable(); in Check()
2832 if (enumVar->TsType() == nullptr) { in Check()
2833 Check(st->BoxedClass()); in Check()
2834 …if (auto *const itemInit = st->Members().front()->AsTSEnumMember()->Init(); itemInit->IsNumberLite… in Check()
2835 checker->CreateEnumIntTypeFromEnumDeclaration(st); in Check()
2836 } else if (itemInit->IsStringLiteral()) { in Check()
2837 checker->CreateEnumStringTypeFromEnumDeclaration(st); in Check()
2839 checker->LogTypeError("Invalid enumeration value type.", st->Start()); in Check()
2840 st->SetTsType(checker->GlobalTypeError()); in Check()
2841 return st->TsType(); in Check()
2843 } else if (st->TsType() == nullptr) { in Check()
2844 st->SetTsType(enumVar->TsType()); in Check()
2847 return st->TsType(); in Check()
2850 checker::Type *ETSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const in Check()
2852 if (st->TsType() == nullptr) { in Check()
2853 ETSChecker *checker = GetETSChecker(); in Check() local
2855 checker::ETSObjectType *interfaceType = checker->BuildBasicInterfaceProperties(st); in Check()
2858 interfaceType->SetSuperType(checker->GlobalETSObjectType()); in Check()
2859 checker->CheckInvokeMethodsLegitimacy(interfaceType); in Check()
2860 st->SetTsType(interfaceType); in Check()
2862 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
2863 …auto savedContext = checker::SavedCheckerContext(checker, checker::CheckerStatus::IN_INTERFACE, in… in Check()
2865 for (auto *it : st->Body()->Body()) { in Check()
2866 it->Check(checker); in Check()
2869 return st->TsType(); in Check()
2872 checker::Type *ETSAnalyzer::Check(ir::TSNonNullExpression *expr) const in Check()
2874 if (expr->TsType() == nullptr) { in Check()
2875 ETSChecker *checker = GetETSChecker(); in Check() local
2876 auto exprType = expr->expr_->Check(checker); in Check()
2879 if (exprType->DefinitelyETSNullish()) { in Check()
2880 checker->LogTypeError( in Check()
2881 … "Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'.", in Check()
2882 expr->Expr()->Start()); in Check()
2883 expr->SetTsType(checker->GlobalTypeError()); in Check()
2884 return expr->TsType(); in Check()
2886 expr->SetTsType(checker->GetNonNullishType(exprType)); in Check()
2888 expr->SetOriginalType(expr->TsType()); in Check()
2889 return expr->TsType(); in Check()
2892 checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const in Check()
2894 ETSChecker *checker = GetETSChecker(); in Check() local
2895 checker::Type *baseType = expr->Left()->Check(checker); in Check()
2897 if (baseType->IsETSObjectType()) { in Check()
2898 auto importDecl = baseType->AsETSObjectType()->GetDeclNode()->Parent()->Parent(); in Check()
2899 // clang-format off in Check()
2901 importDecl->IsETSImportDeclaration() in Check()
2902 ? checker->VarBinder()->AsETSBinder()->FindNameInAliasMap( in Check()
2903 … importDecl->AsETSImportDeclaration()->ResolvedSource()->Str(), expr->Right()->Name()) in Check()
2904 : expr->Right()->Name(); in Check()
2905 // clang-format on in Check()
2906 // NOTE (oeotvos) This should be done differently in the follow-up patch. in Check()
2908 searchName = expr->Right()->Name(); in Check()
2911 … baseType->AsETSObjectType()->GetProperty(searchName, checker::PropertySearchFlags::SEARCH_DECL); in Check()
2915checker->LogTypeError({"'", expr->Right()->Name(), "' type does not exist."}, expr->Right()->Start… in Check()
2916 return checker->GlobalTypeError(); in Check()
2919 …if (expr->Right()->Name().Is(searchName.Mutf8()) && prop->Declaration()->Node()->HasExportAlias())… in Check()
2920checker->LogTypeError({"Cannot find imported element '", searchName, "' exported with alias"}, in Check()
2921 expr->Right()->Start()); in Check()
2922 return checker->GlobalTypeError(); in Check()
2925 expr->Right()->SetVariable(prop); in Check()
2926 return checker->GetTypeOfVariable(prop); in Check()
2929checker->LogTypeError({"'", expr->Right()->Name(), "' type does not exist."}, expr->Right()->Start… in Check()
2930 return checker->GlobalTypeError(); in Check()
2933 checker::Type *ETSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const in Check()
2935 ETSChecker *checker = GetETSChecker(); in Check() local
2936 if (st->TypeParams() == nullptr) { in Check()
2937 const checker::SavedTypeRelationFlagsContext savedFlagsCtx( in Check()
2938 checker->Relation(), checker::TypeRelationFlag::NO_THROW_GENERIC_TYPEALIAS); in Check()
2940 if (st->TypeAnnotation()->TsType() == nullptr) { in Check()
2941 st->TypeAnnotation()->Check(checker); in Check()
2947 if (st->TypeParameterTypes().empty()) { in Check()
2948 auto [typeParamTypes, ok] = checker->CreateUnconstrainedTypeParameters(st->TypeParams()); in Check()
2949 st->SetTypeParameterTypes(std::move(typeParamTypes)); in Check()
2951 checker->AssignTypeParameterConstraints(st->TypeParams()); in Check()
2955 for (auto *const param : st->TypeParams()->Params()) { in Check()
2956 … const auto *const res = st->TypeAnnotation()->FindChild([&param](const ir::AstNode *const node) { in Check()
2957 if (!node->IsIdentifier()) { in Check()
2961 return param->Name()->AsIdentifier()->Variable() == node->AsIdentifier()->Variable(); in Check()
2965 checker->LogTypeError( in Check()
2966 … {"Type alias generic parameter '", param->Name()->Name(), "' is not used in type annotation"}, in Check()
2967 param->Start()); in Check()
2968 return checker->GlobalTypeError(); in Check()
2972 const checker::SavedTypeRelationFlagsContext savedFlagsCtx(checker->Relation(), in Check()
2973checker::TypeRelationFlag::NO_THROW_GENERIC_TYPEALIAS); in Check()
2975 if (st->TypeAnnotation()->TsType() == nullptr) { in Check()
2976 st->TypeAnnotation()->Check(checker); in Check()
2981 } // namespace ark::es2panda::checker