Lines Matching +full:checker +full:-
2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
7 * http://www.apache.org/licenses/LICENSE-2.0
18 #include "checker/ETSchecker.h"
21 #include "checker/types/globalTypesHolder.h"
22 #include "checker/types/ets/etsTupleType.h"
26 #include "checker/types/ets/etsAsyncFuncReturnType.h"
31 namespace ark::es2panda::checker { namespace
39 checker::Type *ETSAnalyzer::Check(ir::CatchClause *st) const in Check()
41 ETSChecker *checker = GetETSChecker(); in Check() local
42 checker::Type *exceptionType = checker->GlobalTypeError(); in Check()
44 if (st->Param() != nullptr) { in Check()
45 ES2PANDA_ASSERT(st->Param()->IsIdentifier()); in Check()
47 ir::Identifier *paramIdent = st->Param()->AsIdentifier(); in Check()
48 if (!paramIdent->IsErrorPlaceHolder()) { in Check()
49 if (paramIdent->TypeAnnotation() != nullptr) { in Check()
50 … checker::Type *catchParamAnnotationType = paramIdent->TypeAnnotation()->GetType(checker); in Check()
51 …exceptionType = checker->CheckExceptionOrErrorType(catchParamAnnotationType, st->Param()->Start()); in Check()
53 exceptionType = checker->GlobalETSObjectType(); in Check()
55 paramIdent->Variable()->SetTsType(exceptionType); in Check()
57 paramIdent->SetTsType(exceptionType); in Check()
59 ES2PANDA_ASSERT(checker->IsAnyError()); in Check()
63 if (st->Param() != nullptr && st->Param()->IsIdentifier()) { in Check()
64 catchVar = st->Param()->AsIdentifier()->Variable(); in Check()
69 st->Body()->Check(checker); in Check()
75 return st->SetTsType(exceptionType); in Check()
78 checker::Type *ETSAnalyzer::Check(ir::ClassDefinition *node) const in Check()
80 ETSChecker *checker = GetETSChecker(); in Check() local
82 if (node->TsType() == nullptr) { in Check()
83 checker->BuildBasicClassProperties(node); in Check()
86 if (!node->IsClassDefinitionChecked()) { in Check()
87 checker->CheckClassDefinition(node); in Check()
90 return node->TsType(); in Check()
93 checker::Type *ETSAnalyzer::Check(ir::ClassProperty *st) const in Check()
95 if (st->TsType() != nullptr) { in Check()
96 return st->TsType(); in Check()
99 ES2PANDA_ASSERT(st->Id() != nullptr); in Check()
101 ETSChecker *checker = GetETSChecker(); in Check() local
103 if (st->Id()->Variable() == nullptr) { in Check()
104 auto ident = st->Id(); in Check()
105 auto [decl, var] = checker->VarBinder()->NewVarDecl<varbinder::LetDecl>( in Check()
106 ident->Start(), compiler::GenName(checker->ProgramAllocator()).View()); in Check()
107 var->SetScope(checker->VarBinder()->GetScope()); in Check()
108 ident->SetVariable(var); in Check()
109 decl->BindNode(ident); in Check()
110 ident->SetTsType(var->SetTsType(checker->GlobalTypeError())); in Check()
113 ES2PANDA_ASSERT(st->Id()->Variable() != nullptr); in Check()
115 checker->CheckAnnotations(st->Annotations()); in Check()
116 if (st->TypeAnnotation() != nullptr) { in Check()
117 st->TypeAnnotation()->Check(checker); in Check()
120 checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), in Check()
121 checker->Context().ContainingClass(), in Check()
122 checker->Context().ContainingSignature()); in Check()
124 if (st->IsStatic()) { in Check()
125 checker->AddStatus(checker::CheckerStatus::IN_STATIC_CONTEXT); in Check()
128 checker::Type *propertyType = in Check()
129 … checker->CheckVariableDeclaration(st->Id(), st->TypeAnnotation(), st->Value(), st->Modifiers()); in Check()
131 propertyType = propertyType != nullptr ? propertyType : checker->GlobalTypeError(); in Check()
132 st->SetTsType(propertyType); in Check()
133 if (st->IsDefinite() && st->TsType()->PossiblyETSNullish()) { in Check()
134 …checker->LogError(diagnostic::LATE_INITIALIZATION_FIELD_HAS_INVALID_TYPE, st->TypeAnnotation()->St… in Check()
140 checker::Type *ETSAnalyzer::Check(ir::ClassStaticBlock *st) const in Check()
142 ETSChecker *checker = GetETSChecker(); in Check() local
144 if (checker->HasStatus(checker::CheckerStatus::INNER_CLASS)) { in Check()
145 checker->LogError(diagnostic::STATIC_INIT_IN_NESTED_CLASS, {}, st->Start()); in Check()
146 st->SetTsType(checker->GlobalTypeError()); in Check()
147 return st->TsType(); in Check()
150 auto *func = st->Function(); in Check()
151 checker->BuildFunctionSignature(func); in Check()
153 if (func->Signature() == nullptr) { in Check()
154 st->SetTsType(checker->GlobalTypeError()); in Check()
156 st->SetTsType(checker->BuildMethodType(func)); in Check()
158 checker::ScopeContext scopeCtx(checker, func->Scope()); in Check()
159 checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), in Check()
160 checker->Context().ContainingClass()); in Check()
161 …checker->AddStatus(checker::CheckerStatus::IN_STATIC_BLOCK | checker::CheckerStatus::IN_STATIC_CON… in Check()
162 func->Body()->Check(checker); in Check()
163 return st->TsType(); in Check()
166 // Satisfy the Chinese code checker
167 static void HandleNativeAndAsyncMethods(ETSChecker *checker, ir::MethodDefinition *node) in HandleNativeAndAsyncMethods() argument
169 auto *scriptFunc = node->Function(); in HandleNativeAndAsyncMethods()
171 if (node->IsNative() && !node->IsConstructor() && !scriptFunc->IsSetter()) { in HandleNativeAndAsyncMethods()
172 if (scriptFunc->ReturnTypeAnnotation() == nullptr) { in HandleNativeAndAsyncMethods()
173 checker->LogError(diagnostic::NATIVE_WITHOUT_RETURN, {}, scriptFunc->Start()); in HandleNativeAndAsyncMethods()
174 node->SetTsType(checker->GlobalTypeError()); in HandleNativeAndAsyncMethods()
179 if (scriptFunc->ReturnTypeAnnotation() != nullptr) { in HandleNativeAndAsyncMethods()
180 auto *asyncFuncReturnType = scriptFunc->Signature()->ReturnType(); in HandleNativeAndAsyncMethods()
182 if (!asyncFuncReturnType->IsETSObjectType() || in HandleNativeAndAsyncMethods()
183 …asyncFuncReturnType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType… in HandleNativeAndAsyncMethods()
184 checker->LogError(diagnostic::ASYNC_FUNCTION_RETURN_TYPE, {}, scriptFunc->Start()); in HandleNativeAndAsyncMethods()
185 scriptFunc->Signature()->SetReturnType(checker->GlobalTypeError()); in HandleNativeAndAsyncMethods()
193 static checker::Type *CheckMethodDefinitionHelper(ETSChecker *checker, ir::MethodDefinition *node) … in CheckMethodDefinitionHelper() argument
197 if ((node->Parent()->Modifiers() & ir::ModifierFlags::FUNCTIONAL) == 0) { in CheckMethodDefinitionHelper()
198 … checker->CheckOverride(node->TsType()->AsETSFunctionType()->FindSignature(node->Function())); in CheckMethodDefinitionHelper()
201 for (auto *overload : node->Overloads()) { in CheckMethodDefinitionHelper()
202 overload->Check(checker); in CheckMethodDefinitionHelper()
205 return node->TsType(); in CheckMethodDefinitionHelper()
214 checker::Type *ETSAnalyzer::Check(ir::MethodDefinition *node) const in Check()
216 ETSChecker *checker = GetETSChecker(); in Check() local
217 auto *scriptFunc = node->Function(); in Check()
219 // CC-OFFNXT(G.FMT.14-CPP) project code style in Check()
220 auto const returnErrorType = [checker, node]() -> checker::Type * { in Check()
221 node->SetTsType(checker->GlobalTypeError()); in Check()
222 return node->TsType(); in Check()
226 checker->LogError(diagnostic::FUNC_EXPR_INVALID, {}, node->Start()); in Check()
229 checker->CheckAnnotations(scriptFunc->Annotations()); in Check()
230 checker->CheckFunctionSignatureAnnotations(scriptFunc->Params(), scriptFunc->TypeParams(), in Check()
231 scriptFunc->ReturnTypeAnnotation()); in Check()
233 if (scriptFunc->IsProxy()) { in Check()
237 ES2PANDA_ASSERT(!(scriptFunc->IsGetter() && scriptFunc->IsSetter())); in Check()
238 if (scriptFunc->IsGetter() || scriptFunc->IsSetter()) { in Check()
239 auto status = scriptFunc->IsGetter() ? CheckerStatus::IN_GETTER : CheckerStatus::IN_SETTER; in Check()
240 checker->AddStatus(status); in Check()
244 if (!scriptFunc->HasBody() && !(node->IsAbstract() || node->IsNative() || node->IsDeclare() || in Check()
245 checker->HasStatus(checker::CheckerStatus::IN_INTERFACE))) { in Check()
246 checker->LogError(diagnostic::FUNCTION_WITHOUT_BODY, {}, scriptFunc->Start()); in Check()
250 if (CheckReturnTypeNecessity(node) && scriptFunc->ReturnTypeAnnotation() == nullptr) { in Check()
251 checker->LogError(diagnostic::MISSING_RETURN_TYPE, {}, scriptFunc->Start()); in Check()
255 if (node->TsType() == nullptr) { in Check()
256 node->SetTsType(checker->BuildMethodSignature(node)); in Check()
259 if (IsInitializerBlockTransfer(scriptFunc->Id()->Name().Utf8())) { in Check()
260 checker->AddStatus(CheckerStatus::IN_STATIC_BLOCK); in Check()
263 this->CheckMethodModifiers(node); in Check()
264 HandleNativeAndAsyncMethods(checker, node); in Check()
265 DoBodyTypeChecking(checker, node, scriptFunc); in Check()
266 CheckPredefinedMethodReturnType(checker, scriptFunc); in Check()
267 if (node->TsType()->IsTypeError()) { in Check()
268 return node->TsType(); in Check()
271 return CheckMethodDefinitionHelper(checker, node); in Check()
276 ETSChecker *checker = GetETSChecker(); in CheckMethodModifiers() local
280 if (node->IsAbstract() && (node->flags_ & notValidInAbstract) != 0U) { in CheckMethodModifiers()
281 checker->LogError(diagnostic::ABSTRACT_METHOD_INVALID_MODIFIER, {}, node->Start()); in CheckMethodModifiers()
282 node->SetTsType(checker->GlobalTypeError()); in CheckMethodModifiers()
286 if (node->Function() == nullptr) { in CheckMethodModifiers()
287 checker->LogError(diagnostic::FUNC_EXPR_INVALID, {}, node->Start()); in CheckMethodModifiers()
288 node->SetTsType(checker->GlobalTypeError()); in CheckMethodModifiers()
292 …if ((node->IsAbstract() || (!node->Function()->HasBody() && !node->IsNative() && !node->IsDeclare(… in CheckMethodModifiers()
293 !(checker->HasStatus(checker::CheckerStatus::IN_ABSTRACT) || in CheckMethodModifiers()
294 checker->HasStatus(checker::CheckerStatus::IN_INTERFACE))) { in CheckMethodModifiers()
295 checker->LogError(diagnostic::ABSTRACT_IN_CONCRETE, {}, node->Start()); in CheckMethodModifiers()
296 node->SetTsType(checker->GlobalTypeError()); in CheckMethodModifiers()
301 if (node->IsFinal() && (node->flags_ & notValidInFinal) != 0U) { in CheckMethodModifiers()
302 checker->LogError(diagnostic::FINAL_METHOD_INVALID_MODIFIER, {}, node->Start()); in CheckMethodModifiers()
303 node->SetTsType(checker->GlobalTypeError()); in CheckMethodModifiers()
308 if (node->IsStatic() && (node->flags_ & notValidInStatic) != 0U) { in CheckMethodModifiers()
309 checker->LogError(diagnostic::STATIC_METHOD_INVALID_MODIFIER, {}, node->Start()); in CheckMethodModifiers()
310 node->SetTsType(checker->GlobalTypeError()); in CheckMethodModifiers()
314 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::Property *expr) const in Check()
316 ETSChecker *checker = GetETSChecker(); in Check() local
317 return checker->GlobalTypeError(); in Check()
320 checker::Type *ETSAnalyzer::Check(ir::SpreadElement *expr) const in Check()
322 if (expr->TsType() != nullptr) { in Check()
323 return expr->TsType(); in Check()
326 ETSChecker *checker = GetETSChecker(); in Check() local
327 Type *exprType = expr->Argument()->Check(checker); in Check()
329 if (exprType->IsETSResizableArrayType()) { in Check()
330 return expr->SetTsType(exprType->AsETSObjectType()->TypeArguments().front()); in Check()
333 if (!exprType->IsETSArrayType() && !exprType->IsETSTupleType()) { in Check()
334 if (!exprType->IsTypeError()) { in Check()
336 checker->LogError(diagnostic::SPREAD_OF_INVALID_TYPE, {exprType}, expr->Start()); in Check()
338 return checker->InvalidateType(expr); in Check()
341 …checker::Type *const elementType = exprType->IsETSTupleType() ? exprType : checker->GetElementType… in Check()
342 return expr->SetTsType(elementType); in Check()
345 checker::Type *ETSAnalyzer::Check(ir::TemplateElement *expr) const in Check()
347 ETSChecker *checker = GetETSChecker(); in Check() local
348 expr->SetTsType(checker->CreateETSStringLiteralType(expr->Raw())); in Check()
349 return expr->TsType(); in Check()
352 checker::Type *ETSAnalyzer::Check(ir::ETSClassLiteral *expr) const in Check()
354 ETSChecker *checker = GetETSChecker(); in Check() local
355 auto *const literal = expr->Expr(); in Check()
357 checker->LogError(diagnostic::UNSUPPORTED_CLASS_LITERAL, {}, literal->Start()); in Check()
358 expr->SetTsType(checker->GlobalTypeError()); in Check()
359 return expr->TsType(); in Check()
361 auto exprType = literal->Check(checker); in Check()
362 if (exprType->IsETSVoidType()) { in Check()
363 checker->LogError(diagnostic::INVALID_DOT_CLASS, {}, literal->Start()); in Check()
364 expr->SetTsType(checker->GlobalTypeError()); in Check()
365 return expr->TsType(); in Check()
368 ArenaVector<checker::Type *> typeArgTypes(checker->ProgramAllocator()->Adapter()); in Check()
371 …checker::InstantiationContext ctx(checker, checker->GlobalBuiltinTypeType(), std::move(typeArgType… in Check()
372 expr->Range().start); in Check()
373 expr->SetTsType(ctx.Result()); in Check()
375 return expr->TsType(); in Check()
378 checker::Type *ETSAnalyzer::Check(ir::ETSFunctionType *node) const in Check()
380 if (node->TsType() != nullptr) { in Check()
381 return node->TsType(); in Check()
383 ETSChecker *checker = GetETSChecker(); in Check() local
384 checker->CheckAnnotations(node->Annotations()); in Check()
385 …checker->CheckFunctionSignatureAnnotations(node->Params(), node->TypeParams(), node->ReturnType()); in Check()
387 auto *signatureInfo = checker->ComposeSignatureInfo(node->TypeParams(), node->Params()); in Check()
388 auto *returnType = node->IsExtensionFunction() && node->ReturnType()->IsTSThisType() in Check()
389 ? signatureInfo->params.front()->TsType() in Check()
390 : checker->ComposeReturnType(node->ReturnType(), node->IsAsync()); in Check()
393 … checker->CreateSignature(signatureInfo, returnType, node->Flags(), node->IsExtensionFunction()); in Check()
395 ES2PANDA_ASSERT(GetChecker()->IsAnyError()); in Check()
396 return node->SetTsType(checker->GlobalTypeError()); in Check()
399 signature->SetOwner(checker->Context().ContainingClass()); in Check()
401 return node->SetTsType(checker->CreateETSArrowType(signature)); in Check()
405 static bool CheckArrayElementType(ETSChecker *checker, T *newArrayInstanceExpr) in CheckArrayElementType() argument
407 ES2PANDA_ASSERT(checker != nullptr); in CheckArrayElementType()
410 checker::Type *elementType = newArrayInstanceExpr->TypeReference()->GetType(checker); in CheckArrayElementType()
412 if (elementType->IsETSPrimitiveType()) { in CheckArrayElementType()
416 if (elementType->IsETSObjectType()) { in CheckArrayElementType()
417 auto *calleeObj = elementType->AsETSObjectType(); in CheckArrayElementType()
418 const auto flags = checker::ETSObjectFlags::ABSTRACT | checker::ETSObjectFlags::INTERFACE; in CheckArrayElementType()
419 if (!calleeObj->HasObjectFlag(flags)) { in CheckArrayElementType()
421 newArrayInstanceExpr->SetSignature(checker->CollectParameterlessConstructor( in CheckArrayElementType()
422 calleeObj->ConstructSignatures(), newArrayInstanceExpr->Start())); in CheckArrayElementType()
423 checker->ValidateSignatureAccessibility(calleeObj, newArrayInstanceExpr->Signature(), in CheckArrayElementType()
424 newArrayInstanceExpr->Start()); in CheckArrayElementType()
426 …checker->LogError(diagnostic::ABSTRACT_CLASS_AS_ARRAY_ELEMENT_TYPE, {}, newArrayInstanceExpr->Star… in CheckArrayElementType()
430 if (!checker->Relation()->IsSupertypeOf(elementType, checker->GlobalETSUndefinedType()) && in CheckArrayElementType()
431 … !checker->Relation()->IsIdenticalTo(checker->GetApparentType(elementType), elementType)) { in CheckArrayElementType()
432 …checker->LogError(diagnostic::TYPE_PARAMETER_AS_ARRAY_ELEMENT_TYPE, {}, newArrayInstanceExpr->Star… in CheckArrayElementType()
435 if (!checker->Relation()->IsSupertypeOf(elementType, checker->GlobalETSUndefinedType())) { in CheckArrayElementType()
436 checker->LogError(diagnostic::NON_SUPERTYPE_OF_UNDEFINED_AS_ARRAY_ELEMENT_TYPE, {}, in CheckArrayElementType()
437 newArrayInstanceExpr->Start()); in CheckArrayElementType()
444 static bool NeedCreateETSResizableArrayType(ETSChecker *checker, Type *type) in NeedCreateETSResizableArrayType() argument
447 …checker->Relation()->IsSupertypeOf(type, checker->GetGlobalTypesHolder()->GlobalArrayBuiltinType()… in NeedCreateETSResizableArrayType()
450 checker::Type *ETSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const in Check()
452 ETSChecker *checker = GetETSChecker(); in Check() local
454 auto *elementType = expr->TypeReference()->GetType(checker); in Check()
455 checker->ValidateArrayIndex(expr->Dimension(), true); in Check()
457 CheckArrayElementType(checker, expr); in Check()
458 GetUnionPreferredType(expr, expr->GetPreferredType()); in Check()
460 auto *preferredType = expr->GetPreferredType(); in Check()
462 if (NeedCreateETSResizableArrayType(checker, expr->GetPreferredType()) || in Check()
463 preferredType->IsETSResizableArrayType()) { in Check()
464 expr->SetTsType(checker->CreateETSResizableArrayType(elementType)); in Check()
466 expr->SetTsType(checker->CreateETSArrayType(elementType)); in Check()
468 if (expr->TsType()->IsETSArrayType()) { in Check()
469 checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), 1); in Check()
472 return expr->TsType(); in Check()
475 static checker::Type *CheckInstantiatedNewType(ETSChecker *checker, ir::ETSNewClassInstanceExpressi… in CheckInstantiatedNewType() argument
477 checker::Type *calleeType = expr->GetTypeRef()->Check(checker); in CheckInstantiatedNewType()
478 if (calleeType->IsTypeError()) { in CheckInstantiatedNewType()
479 return checker->InvalidateType(expr->GetTypeRef()); in CheckInstantiatedNewType()
481 if (calleeType->IsETSUnionType()) { in CheckInstantiatedNewType()
482 … return checker->TypeError(expr->GetTypeRef(), diagnostic::UNION_NONCONSTRUCTIBLE, expr->Start()); in CheckInstantiatedNewType()
485 …return checker->TypeError(expr->GetTypeRef(), diagnostic::CALLEE_NONCONSTRUCTIBLE, {calleeType}, e… in CheckInstantiatedNewType()
487 if (!calleeType->IsETSObjectType()) { in CheckInstantiatedNewType()
488 …return checker->TypeError(expr->GetTypeRef(), diagnostic::EXPR_NONCONSTRUCTIBLE, {}, expr->Start()… in CheckInstantiatedNewType()
491 auto calleeObj = calleeType->AsETSObjectType(); in CheckInstantiatedNewType()
492 if (calleeObj->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT)) { in CheckInstantiatedNewType()
493 checker->LogError(diagnostic::ABSTRACT_INSTANTIATION, {calleeObj->Name()}, expr->Start()); in CheckInstantiatedNewType()
494 return checker->GlobalTypeError(); in CheckInstantiatedNewType()
497 if (calleeObj->HasObjectFlag(checker::ETSObjectFlags::INTERFACE)) { in CheckInstantiatedNewType()
498 checker->LogError(diagnostic::INTERFACE_INSTANTIATION, {calleeObj->Name()}, expr->Start()); in CheckInstantiatedNewType()
499 return checker->GlobalTypeError(); in CheckInstantiatedNewType()
502 if (calleeObj->HasObjectFlag(ETSObjectFlags::REQUIRED) && in CheckInstantiatedNewType()
503 !expr->HasAstNodeFlags(ir::AstNodeFlags::ALLOW_REQUIRED_INSTANTIATION)) { in CheckInstantiatedNewType()
504 checker->LogError(diagnostic::NONLITERAL_INSTANTIATION, {}, expr->GetTypeRef()->Start()); in CheckInstantiatedNewType()
505 return checker->GlobalTypeError(); in CheckInstantiatedNewType()
511 checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const in Check()
513 if (expr->TsType() != nullptr) { in Check()
514 return expr->TsType(); in Check()
516 ETSChecker *checker = GetETSChecker(); in Check() local
517 auto *calleeType = CheckInstantiatedNewType(checker, expr); in Check()
518 if (calleeType->IsTypeError()) { in Check()
519 return checker->InvalidateType(expr); in Check()
521 auto *calleeObj = calleeType->AsETSObjectType(); in Check()
522 expr->SetTsType(calleeObj); in Check()
524 if (calleeType->IsETSDynamicType() && !calleeType->AsETSDynamicType()->HasDecl()) { in Check()
525 auto lang = calleeType->AsETSDynamicType()->Language(); in Check()
526 …expr->SetSignature(checker->ResolveDynamicCallExpression(expr->GetTypeRef(), expr->GetArguments(),… in Check()
528 …auto *signature = checker->ResolveConstructExpression(calleeObj, expr->GetArguments(), expr->Start… in Check()
531 return checker->InvalidateType(expr); in Check()
534 checker->CheckObjectLiteralArguments(signature, expr->GetArguments()); in Check()
536 checker->ValidateSignatureAccessibility(calleeObj, signature, expr->Start()); in Check()
538 if (calleeType->IsETSDynamicType()) { in Check()
539 ES2PANDA_ASSERT(signature->Function()->IsDynamic()); in Check()
540 auto lang = calleeType->AsETSDynamicType()->Language(); in Check()
541 expr->SetSignature( in Check()
542 … checker->ResolveDynamicCallExpression(expr->GetTypeRef(), signature->Params(), lang, true)); in Check()
544 expr->SetSignature(signature); in Check()
548 return expr->TsType(); in Check()
551 checker::Type *ETSAnalyzer::Check(ir::ETSNewMultiDimArrayInstanceExpression *expr) const in Check()
553 ETSChecker *checker = GetETSChecker(); in Check() local
555 CheckArrayElementType(checker, expr); in Check()
556 auto *elementType = expr->TypeReference()->GetType(checker); in Check()
559 for (auto *dim : expr->Dimensions()) { in Check()
560 checker->ValidateArrayIndex(dim, true); in Check()
561 fixedArrayType = checker->CreateETSArrayType(fixedArrayType); in Check()
563 GetUnionPreferredType(expr, expr->GetPreferredType()); in Check()
565 auto *preferredType = expr->GetPreferredType(); in Check()
566 if (NeedCreateETSResizableArrayType(checker, expr->GetPreferredType()) || in Check()
567 preferredType->IsETSResizableArrayType()) { in Check()
568 …expr->SetTsType(checker->CreateETSMultiDimResizableArrayType(elementType, expr->Dimensions().size(… in Check()
570 expr->SetTsType(fixedArrayType); in Check()
573 if (expr->TsType()->IsETSArrayType()) { in Check()
574 expr->SetSignature( in Check()
575 …checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), expr->Dimensions().size())); in Check()
578 return expr->TsType(); in Check()
581 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSPackageDeclaration *st) const in Check()
586 checker::Type *ETSAnalyzer::Check(ir::ETSParameterExpression *expr) const in Check()
588 ETSChecker *checker = GetETSChecker(); in Check() local
589 if (expr->TsType() != nullptr) { in Check()
590 return expr->TsType(); in Check()
592 ASSERT_PRINT(expr->Initializer() == nullptr, "default parameter was not lowered"); in Check()
594 if (expr->Ident()->TsType() != nullptr) { in Check()
595 expr->SetTsType(expr->Ident()->TsType()); in Check()
596 } else if (expr->IsRestParameter()) { in Check()
597 expr->SetTsType(expr->RestParameter()->Check(checker)); in Check()
599 expr->SetTsType(expr->Ident()->Check(checker)); in Check()
601 ES2PANDA_ASSERT(!expr->IsOptional() || in Check()
602 … checker->Relation()->IsSupertypeOf(expr->TsType(), checker->GlobalETSUndefinedType())); in Check()
603 return expr->TsType(); in Check()
606 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSPrimitiveType *node) const in Check()
608 ETSChecker *checker = GetETSChecker(); in Check() local
609 return node->GetType(checker); in Check()
612 checker::Type *ETSAnalyzer::Check(ir::ETSStructDeclaration *node) const in Check()
614 ETSChecker *checker = GetETSChecker(); in Check() local
615 node->Definition()->Check(checker); in Check()
619 checker::Type *ETSAnalyzer::Check(ir::ETSTypeReference *node) const in Check()
621 ETSChecker *checker = GetETSChecker(); in Check() local
622 checker->CheckAnnotations(node->Annotations()); in Check()
623 return node->GetType(checker); in Check()
626 checker::Type *ETSAnalyzer::Check(ir::ETSTypeReferencePart *node) const in Check()
628 ETSChecker *checker = GetETSChecker(); in Check() local
629 return node->GetType(checker); in Check()
632 checker::Type *ETSAnalyzer::Check(ir::ETSNonNullishTypeNode *node) const in Check()
634 if (node->TsType() != nullptr) { in Check()
635 return node->TsType(); in Check()
637 ETSChecker *checker = GetETSChecker(); in Check() local
638 checker::Type *originalType = node->GetTypeNode()->Check(checker); in Check()
639 if (!originalType->IsETSTypeParameter()) { in Check()
640 checker->LogError(diagnostic::ILLEGAL_NON_NULLISH_TYPE, {}, node->GetTypeNode()->Start()); in Check()
642 return node->SetTsType(checker->GetNonNullishType(originalType)); in Check()
645 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNullType *node) const in Check()
647 ETSChecker *checker = GetETSChecker(); in Check() local
648 checker->CheckAnnotations(node->Annotations()); in Check()
649 return node->SetTsType(checker->GlobalETSNullType()); in Check()
652 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSUndefinedType *node) const in Check()
654 ETSChecker *checker = GetETSChecker(); in Check() local
655 checker->CheckAnnotations(node->Annotations()); in Check()
656 return node->SetTsType(checker->GlobalETSUndefinedType()); in Check()
659 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNeverType *node) const in Check()
661 ETSChecker *checker = GetETSChecker(); in Check() local
662 return checker->GlobalETSNeverType(); in Check()
665 checker::Type *ETSAnalyzer::Check(ir::ETSStringLiteralType *node) const in Check()
667 ETSChecker *checker = GetETSChecker(); in Check() local
668 checker->CheckAnnotations(node->Annotations()); in Check()
669 return node->GetType(checker); in Check()
672 checker::Type *ETSAnalyzer::Check(ir::ETSKeyofType *node) const in Check()
674 ETSChecker *checker = GetETSChecker(); in Check() local
675 return node->GetType(checker); in Check()
680 checker::Type *ETSAnalyzer::GetPreferredType(ir::ArrayExpression *expr) const in GetPreferredType()
682 return expr->preferredType_; in GetPreferredType()
685 static void AddSpreadElementTypes(ETSChecker *checker, ir::SpreadElement *const element, in AddSpreadElementTypes() argument
688 Type *const spreadType = element->Check(checker); in AddSpreadElementTypes()
690 if (spreadType->IsTypeError()) { in AddSpreadElementTypes()
695 Type *const spreadArgumentType = element->Argument()->TsType(); in AddSpreadElementTypes()
697 if (spreadArgumentType->IsETSTupleType()) { in AddSpreadElementTypes()
698 for (Type *type : spreadArgumentType->AsETSTupleType()->GetTupleTypesList()) { in AddSpreadElementTypes()
701 } else if (spreadArgumentType->IsETSArrayType()) { in AddSpreadElementTypes()
702 elementTypes.emplace_back(spreadArgumentType->AsETSArrayType()->ElementType(), element); in AddSpreadElementTypes()
704 ES2PANDA_ASSERT(spreadArgumentType->IsETSResizableArrayType()); in AddSpreadElementTypes()
705 …elementTypes.emplace_back(spreadArgumentType->AsETSObjectType()->TypeArguments().front(), element); in AddSpreadElementTypes()
709 static bool ValidArrayExprSizeForTupleSize(ETSChecker *checker, Type *possibleTupleType, in ValidArrayExprSizeForTupleSize() argument
712 if (!possibleArrayExpr->IsArrayExpression() || !possibleTupleType->IsETSTupleType()) { in ValidArrayExprSizeForTupleSize()
716 return checker->IsArrayExprSizeValidForTuple(possibleArrayExpr->AsArrayExpression(), in ValidArrayExprSizeForTupleSize()
717 possibleTupleType->AsETSTupleType()); in ValidArrayExprSizeForTupleSize()
720 static ArenaVector<std::pair<Type *, ir::Expression *>> GetElementTypes(ETSChecker *checker, ir::Ar… in GetElementTypes() argument
722 …ArenaVector<std::pair<Type *, ir::Expression *>> elementTypes(checker->ProgramAllocator()->Adapter… in GetElementTypes()
724 for (std::size_t idx = 0; idx < expr->Elements().size(); ++idx) { in GetElementTypes()
725 ir::Expression *const element = expr->Elements()[idx]; in GetElementTypes()
727 if (element->IsSpreadElement()) { in GetElementTypes()
728 AddSpreadElementTypes(checker, element->AsSpreadElement(), elementTypes); in GetElementTypes()
732 auto *const exprPreferredType = expr->GetPreferredType(); in GetElementTypes()
734 if (expr->GetPreferredType()->IsETSTupleType() && in GetElementTypes()
735 idx < expr->GetPreferredType()->AsETSTupleType()->GetTupleSize() && in GetElementTypes()
736 … !ValidArrayExprSizeForTupleSize(checker, exprPreferredType->AsETSTupleType()->GetTypeAtIndex(idx), in GetElementTypes()
738 elementTypes.emplace_back(checker->GlobalTypeError(), element); in GetElementTypes()
742 if (element->IsArrayExpression() || element->IsObjectExpression()) { in GetElementTypes()
743 auto *const targetPreferredType = exprPreferredType->IsETSTupleType() in GetElementTypes()
744 … ? exprPreferredType->AsETSTupleType()->GetTypeAtIndex(idx) in GetElementTypes()
745 … : checker->GetElementTypeOfArray(exprPreferredType); in GetElementTypes()
749 elementTypes.emplace_back(element->Check(checker), element); in GetElementTypes()
755 static Type *GetArrayElementType(ETSChecker *checker, Type *preferredType) in GetArrayElementType() argument
757 if (preferredType->IsETSArrayType()) { in GetArrayElementType()
758 return checker->GetNonConstantType(checker->GetElementTypeOfArray(preferredType)); in GetArrayElementType()
760 ES2PANDA_ASSERT(preferredType->IsETSResizableArrayType()); in GetArrayElementType()
761 return preferredType->AsETSResizableArrayType()->ElementType(); in GetArrayElementType()
764 static bool CheckElement(ETSChecker *checker, Type *const preferredType, in CheckElement() argument
769 if (elementType->IsTypeError()) { in CheckElement()
775 if (preferredType->IsETSTupleType()) { in CheckElement()
776 const auto *const tupleType = preferredType->AsETSTupleType(); in CheckElement()
777 if (tupleType->GetTupleSize() != arrayExprElementTypes.size()) { in CheckElement()
781 auto *const compareType = tupleType->GetTypeAtIndex(idx); in CheckElement()
783 …checker->LogError(diagnostic::TUPLE_SIZE_MISMATCH, {tupleType->GetTupleSize()}, currentElement->St… in CheckElement()
787 auto ctx = AssignmentContext(checker->Relation(), currentElement, elementType, compareType, in CheckElement()
788 … currentElement->Start(), std::nullopt, TypeRelationFlag::NO_THROW); in CheckElement()
790 checker->LogError(diagnostic::TUPLE_UNASSIGNABLE_ARRAY, {idx}, currentElement->Start()); in CheckElement()
795 checker->Relation(), diagnostic::CAST_FAIL_UNREACHABLE, {}, in CheckElement()
796 … CastingContext::ConstructorData {currentElement, compareType, checker->MaybeBoxType(compareType), in CheckElement()
797 currentElement->Start(), TypeRelationFlag::NO_THROW}); in CheckElement()
801 targetType = GetArrayElementType(checker, preferredType); in CheckElement()
804 …auto ctx = AssignmentContext(checker->Relation(), currentElement, elementType, targetType, current… in CheckElement()
807 … checker->LogError(diagnostic::ARRAY_ELEMENT_INIT_TYPE_INCOMPAT, {idx, elementType, targetType}, in CheckElement()
808 currentElement->Start()); in CheckElement()
815 static Type *InferPreferredTypeFromElements(ETSChecker *checker, ir::ArrayExpression *arrayExpr) in InferPreferredTypeFromElements() argument
817 ArenaVector<Type *> arrayExpressionElementTypes(checker->ProgramAllocator()->Adapter()); in InferPreferredTypeFromElements()
818 for (auto *const element : arrayExpr->Elements()) { in InferPreferredTypeFromElements()
819 auto *elementType = *element->Check(checker); in InferPreferredTypeFromElements()
820 if (element->IsSpreadElement() && elementType->IsETSTupleType()) { in InferPreferredTypeFromElements()
821 for (auto *typeFromTuple : elementType->AsETSTupleType()->GetTupleTypesList()) { in InferPreferredTypeFromElements()
828 if (element->IsSpreadElement() && elementType->IsETSArrayType()) { in InferPreferredTypeFromElements()
829 elementType = elementType->AsETSArrayType()->ElementType(); in InferPreferredTypeFromElements()
839 … [](Type *const typeOfElement) { return typeOfElement->IsETSPrimitiveType(); })) { in InferPreferredTypeFromElements()
840 return checker->CreateETSResizableArrayType(checker->GetNonConstantType( in InferPreferredTypeFromElements()
841 … checker->MaybeUnboxType(checker->CreateETSUnionType(std::move(arrayExpressionElementTypes))))); in InferPreferredTypeFromElements()
846 return checker->CreateETSResizableArrayType( in InferPreferredTypeFromElements()
847 … checker->GetNonConstantType(checker->CreateETSUnionType(std::move(arrayExpressionElementTypes)))); in InferPreferredTypeFromElements()
850 static bool CheckArrayExpressionElements(ETSChecker *checker, ir::ArrayExpression *arrayExpr) in CheckArrayExpressionElements() argument
852 …r<std::pair<Type *, ir::Expression *>> arrayExprElementTypes = GetElementTypes(checker, arrayExpr); in CheckArrayExpressionElements()
855 [](auto &pair) { return pair.first->IsTypeError(); }); in CheckArrayExpressionElements()
858 …allElementsAssignable &= CheckElement(checker, arrayExpr->GetPreferredType(), arrayExprElementType… in CheckArrayExpressionElements()
866 return type->IsETSArrayType() || type->IsETSTupleType() || type->IsETSResizableArrayType(); in IsPossibleArrayExpressionType()
871 if (originalType == nullptr || !originalType->IsETSUnionType()) { in GetUnionPreferredType()
874 checker::Type *preferredType = nullptr; in GetUnionPreferredType()
875 for (auto &type : originalType->AsETSUnionType()->ConstituentTypes()) { in GetUnionPreferredType()
884 if (expr->IsArrayExpression()) { in GetUnionPreferredType()
885 expr->AsArrayExpression()->SetPreferredType(preferredType); in GetUnionPreferredType()
886 } else if (expr->IsETSNewArrayInstanceExpression()) { in GetUnionPreferredType()
887 expr->AsETSNewArrayInstanceExpression()->SetPreferredType(preferredType); in GetUnionPreferredType()
888 } else if (expr->IsETSNewMultiDimArrayInstanceExpression()) { in GetUnionPreferredType()
889 expr->AsETSNewMultiDimArrayInstanceExpression()->SetPreferredType(preferredType); in GetUnionPreferredType()
895 checker::Type *ETSAnalyzer::Check(ir::ArrayExpression *expr) const in Check()
897 ETSChecker *checker = GetETSChecker(); in Check() local
898 if (expr->TsType() != nullptr) { in Check()
899 return expr->TsType(); in Check()
902 if (expr->GetPreferredType() != nullptr) { in Check()
903 if (expr->GetPreferredType()->IsETSTypeAliasType()) { in Check()
904 expr->SetPreferredType(expr->GetPreferredType()->AsETSTypeAliasType()->GetTargetType()); in Check()
907 if (expr->GetPreferredType()->IsETSUnionType()) { in Check()
908 GetUnionPreferredType(expr, expr->GetPreferredType()); in Check()
911 …if (expr->GetPreferredType() != nullptr && !IsPossibleArrayExpressionType(expr->GetPreferredType()… in Check()
912 expr->SetPreferredType(nullptr); in Check()
916 if (!IsArrayExpressionValidInitializerForType(checker, expr->GetPreferredType())) { in Check()
917 checker->LogError(diagnostic::UNEXPECTED_ARRAY, {expr->GetPreferredType()}, expr->Start()); in Check()
918 return checker->InvalidateType(expr); in Check()
921 if (!expr->Elements().empty()) { in Check()
922 …if (expr->GetPreferredType() == nullptr || expr->GetPreferredType() == checker->GlobalETSObjectTyp… in Check()
923 expr->SetPreferredType(InferPreferredTypeFromElements(checker, expr)); in Check()
926 if (!ValidArrayExprSizeForTupleSize(checker, expr->GetPreferredType(), expr) || in Check()
927 !CheckArrayExpressionElements(checker, expr)) { in Check()
928 return checker->InvalidateType(expr); in Check()
932 if (expr->GetPreferredType() == nullptr) { in Check()
933 return checker->TypeError(expr, diagnostic::UNRESOLVABLE_ARRAY, expr->Start()); in Check()
936 expr->SetTsType(expr->GetPreferredType()); in Check()
937 if (!expr->GetPreferredType()->IsETSResizableArrayType() && !expr->TsType()->IsETSTupleType()) { in Check()
938 ES2PANDA_ASSERT(expr->TsType()->IsETSArrayType()); in Check()
939 const auto *const arrayType = expr->TsType()->AsETSArrayType(); in Check()
940 checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); in Check()
942 return expr->TsType(); in Check()
945 …ferPreferredType(ir::ArrowFunctionExpression *expr, checker::Type *preferredType, ETSChecker *chec… in TryInferPreferredType() argument
947 if (!preferredType->IsETSUnionType()) { in TryInferPreferredType()
948 if (preferredType->IsETSArrowType() && in TryInferPreferredType()
949 !preferredType->AsETSFunctionType()->CallSignaturesOfMethodOrArrow().empty()) { in TryInferPreferredType()
950 checker->TryInferTypeForLambdaTypeAlias(expr, preferredType->AsETSFunctionType()); in TryInferPreferredType()
951 checker->BuildFunctionSignature(expr->Function(), false); in TryInferPreferredType()
956 for (auto &ct : preferredType->AsETSUnionType()->ConstituentTypes()) { in TryInferPreferredType()
957 … if (!ct->IsETSArrowType() || ct->AsETSFunctionType()->CallSignaturesOfMethodOrArrow().empty()) { in TryInferPreferredType()
960 checker->TryInferTypeForLambdaTypeAlias(expr, ct->AsETSFunctionType()); in TryInferPreferredType()
961 checker->BuildFunctionSignature(expr->Function(), false); in TryInferPreferredType()
962 if (expr->Function()->Signature() != nullptr) { in TryInferPreferredType()
968 checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const in Check()
970 ETSChecker *checker = GetETSChecker(); in Check() local
971 checker->CheckAnnotations(expr->Annotations()); in Check()
972 if (expr->TsType() != nullptr) { in Check()
973 return expr->TsType(); in Check()
975 checker::ScopeContext scopeCtx(checker, expr->Function()->Scope()); in Check()
977 …if (checker->HasStatus(checker::CheckerStatus::IN_EXTENSION_METHOD) && !expr->Function()->HasRecei… in Check()
992 checker->Context().SetContainingClass( in Check()
993 …checker->Scope()->Find(varbinder::VarBinder::MANDATORY_PARAM_THIS).variable->TsType()->AsETSObject… in Check()
996 auto lambdaSavedSmartCasts = checker->Context().CloneSmartCasts(); in Check()
997 checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), in Check()
998 checker->Context().ContainingClass()); in Check()
1000 if (expr->Parent()->IsCallExpression() && !expr->Function()->IsAsyncFunc()) { in Check()
1001 checker->Context().RestoreSmartCasts(lambdaSavedSmartCasts); in Check()
1004 checker->AddStatus(checker::CheckerStatus::IN_LAMBDA); in Check()
1005 checker->Context().SetContainingLambda(expr); in Check()
1007 auto preferredType = expr->GetPreferredType(); in Check()
1009 TryInferPreferredType(expr, preferredType, checker); in Check()
1011 checker->BuildFunctionSignature(expr->Function(), false); in Check()
1014 if (expr->Function()->Signature() == nullptr) { in Check()
1015 return checker->InvalidateType(expr); in Check()
1018 if (expr->Function()->HasReceiver()) { in Check()
1019 checker->AddStatus(checker::CheckerStatus::IN_EXTENSION_METHOD); in Check()
1020 CheckExtensionMethod(checker, expr->Function(), expr); in Check()
1022 auto *signature = expr->Function()->Signature(); in Check()
1024 checker->Context().SetContainingSignature(signature); in Check()
1025 expr->Function()->Body()->Check(checker); in Check()
1027 auto *funcType = checker->CreateETSArrowType(signature); in Check()
1028 checker->Context().SetContainingSignature(nullptr); in Check()
1030 if (expr->Function()->IsAsyncFunc()) { in Check()
1031 auto *retType = signature->ReturnType(); in Check()
1032 if (!retType->IsETSObjectType() || in Check()
1033 … retType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType()) { in Check()
1034 checker->LogError(diagnostic::ASYNC_DOESNT_PROMISE, {}, expr->Function()->Start()); in Check()
1035 expr->SetTsType(checker->GlobalTypeError()); in Check()
1036 return expr->TsType(); in Check()
1039 expr->SetTsType(funcType); in Check()
1040 return expr->TsType(); in Check()
1043 …ool IsInvalidArrayMemberAssignment(const ir::AssignmentExpression *const expr, ETSChecker *checker) in IsInvalidArrayMemberAssignment() argument
1045 if (!expr->Left()->IsMemberExpression()) { in IsInvalidArrayMemberAssignment()
1049 const auto *const leftExpr = expr->Left()->AsMemberExpression(); in IsInvalidArrayMemberAssignment()
1050 …if (leftExpr->Object()->TsType()->IsETSArrayType() || leftExpr->Object()->TsType()->IsETSTupleType… in IsInvalidArrayMemberAssignment()
1051 leftExpr->Object()->TsType()->IsETSResizableArrayType()) { in IsInvalidArrayMemberAssignment()
1052 … if (leftExpr->Object()->TsType()->IsETSArrayType() && leftExpr->Property()->IsIdentifier() && in IsInvalidArrayMemberAssignment()
1053 leftExpr->Property()->AsIdentifier()->Name().Is("length")) { in IsInvalidArrayMemberAssignment()
1054 checker->LogError(diagnostic::ARRAY_LENGTH_MODIFICATION, {}, expr->Left()->Start()); in IsInvalidArrayMemberAssignment()
1058 if (leftExpr->Object()->TsType()->HasTypeFlag(TypeFlag::READONLY)) { in IsInvalidArrayMemberAssignment()
1059 … checker->LogError(diagnostic::READONLY_ARRAYLIKE_MODIFICATION, {}, expr->Left()->Start()); in IsInvalidArrayMemberAssignment()
1067 checker::Type *ETSAnalyzer::GetSmartType(ir::AssignmentExpression *expr, checker::Type *leftType, in GetSmartType()
1068 checker::Type *rightType) const in GetSmartType()
1070 ETSChecker *checker = GetETSChecker(); in GetSmartType() local
1071 checker::Type *smartType = leftType; in GetSmartType()
1073 if (expr->Left()->IsIdentifier() && expr->Target() != nullptr) { in GetSmartType()
1074 … Now try to define the actual type of Identifier so that smart cast can be used in further checker in GetSmartType()
1076 smartType = checker->ResolveSmartType(rightType, leftType); in GetSmartType()
1077 auto const *const variable = expr->Target(); in GetSmartType()
1080 // (excluding the variables defined at top-level scope or captured in lambda-functions!) in GetSmartType()
1081 auto const *const variableScope = variable->GetScope(); in GetSmartType()
1083 …variableScope != nullptr && (variableScope->IsGlobalScope() || (variableScope->Parent() != nullptr… in GetSmartType()
1084 … variableScope->Parent()->IsGlobalScope())); in GetSmartType()
1086 if (checker->Relation()->IsIdenticalTo(leftType, smartType)) { in GetSmartType()
1087 checker->Context().RemoveSmartCast(variable); in GetSmartType()
1089 expr->Left()->SetTsType(smartType); in GetSmartType()
1090 checker->Context().SetSmartCast(variable, smartType); in GetSmartType()
1097 checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const in Check()
1099 if (expr->TsType() != nullptr) { in Check()
1100 return expr->TsType(); in Check()
1103 ETSChecker *checker = GetETSChecker(); in Check() local
1105 if (checker->HasStatus(CheckerStatus::IN_SETTER) && expr->Left()->IsMemberExpression()) { in Check()
1106 checker->WarnForEndlessLoopInGetterSetter(expr->Left()->AsMemberExpression()); in Check()
1109 const auto leftType = expr->Left()->Check(checker); in Check()
1111 if (IsInvalidArrayMemberAssignment(expr, checker)) { in Check()
1112 expr->SetTsType(checker->GlobalTypeError()); in Check()
1113 return expr->TsType(); in Check()
1116 if (expr->Left()->IsIdentifier()) { in Check()
1117 expr->target_ = expr->Left()->AsIdentifier()->Variable(); in Check()
1118 } else if (expr->Left()->IsMemberExpression()) { in Check()
1119 if (!expr->IsIgnoreConstAssign() && in Check()
1120 … expr->Left()->AsMemberExpression()->Object()->TsType()->HasTypeFlag(TypeFlag::READONLY)) { in Check()
1121 checker->LogError(diagnostic::READONLY_PROPERTY_REASSIGN, {}, expr->Left()->Start()); in Check()
1123 expr->target_ = expr->Left()->AsMemberExpression()->PropVar(); in Check()
1125 checker->LogError(diagnostic::ASSIGNMENT_INVALID_LHS, {}, expr->Left()->Start()); in Check()
1126 expr->SetTsType(checker->GlobalTypeError()); in Check()
1127 return expr->TsType(); in Check()
1130 if (expr->target_ != nullptr && !expr->IsIgnoreConstAssign()) { in Check()
1131 checker->ValidateUnaryOperatorOperand(expr->target_); in Check()
1135 if (rightType->IsTypeError()) { in Check()
1136 return expr->SetTsType(leftType); in Check()
1139 CastPossibleTupleOnRHS(checker, expr); in Check()
1141 checker::Type *smartType = rightType; in Check()
1142 if (!leftType->IsTypeError()) { in Check()
1143 …if (const auto ctx = checker::AssignmentContext(checker->Relation(), relationNode, rightType, left… in Check()
1144 expr->Right()->Start(), in Check()
1151 return expr->SetTsType(smartType); in Check()
1154 static checker::Type *HandleSubstitution(ETSChecker *checker, ir::AssignmentExpression *expr, Type … in HandleSubstitution() argument
1156 …bool possibleInferredTypeOfArray = leftType->IsETSArrayType() || leftType->IsETSResizableArrayType… in HandleSubstitution()
1157 leftType->IsETSTupleType() || leftType->IsETSUnionType(); in HandleSubstitution()
1158 if (expr->Right()->IsArrayExpression() && possibleInferredTypeOfArray) { in HandleSubstitution()
1159 checker->ModifyPreferredType(expr->Right()->AsArrayExpression(), leftType); in HandleSubstitution()
1162 if (expr->Right()->IsETSNewArrayInstanceExpression()) { in HandleSubstitution()
1163 expr->Right()->AsETSNewArrayInstanceExpression()->SetPreferredType(leftType); in HandleSubstitution()
1166 if (expr->Right()->IsETSNewMultiDimArrayInstanceExpression()) { in HandleSubstitution()
1167 expr->Right()->AsETSNewMultiDimArrayInstanceExpression()->SetPreferredType(leftType); in HandleSubstitution()
1170 if (expr->Right()->IsObjectExpression()) { in HandleSubstitution()
1171 expr->Right()->AsObjectExpression()->SetPreferredType(leftType); in HandleSubstitution()
1174 …if (expr->Right()->IsArrowFunctionExpression() && (leftType->IsETSArrowType() || leftType->IsETSUn… in HandleSubstitution()
1175 expr->Right()->AsArrowFunctionExpression()->SetPreferredType(leftType); in HandleSubstitution()
1178 return expr->Right()->Check(checker); in HandleSubstitution()
1184 ETSChecker *checker = GetETSChecker(); in CheckAssignmentExprOperatorType() local
1185 checker::Type *sourceType {}; in CheckAssignmentExprOperatorType()
1186 ir::Expression *relationNode = expr->Right(); in CheckAssignmentExprOperatorType()
1187 switch (expr->OperatorType()) { in CheckAssignmentExprOperatorType()
1200 std::tie(std::ignore, expr->operationType_) = checker->CheckBinaryOperator( in CheckAssignmentExprOperatorType()
1201 expr->Left(), expr->Right(), expr, expr->OperatorType(), expr->Start(), true); in CheckAssignmentExprOperatorType()
1203 auto unboxedLeft = checker->MaybeUnboxInRelation(leftType); in CheckAssignmentExprOperatorType()
1210 sourceType = HandleSubstitution(checker, expr, leftType); in CheckAssignmentExprOperatorType()
1222 static bool IsPromiseType(checker::Type *type, ETSChecker *checker) in IsPromiseType() argument
1224 return type->IsETSObjectType() && in IsPromiseType()
1225 type->AsETSObjectType()->GetOriginalBaseType() == checker->GlobalBuiltinPromiseType(); in IsPromiseType()
1228 checker::Type *ETSAnalyzer::Check(ir::AwaitExpression *expr) const in Check()
1230 ETSChecker *checker = GetETSChecker(); in Check() local
1231 if (expr->TsType() != nullptr) { in Check()
1232 return expr->TsType(); in Check()
1235 checker::Type *argType = checker->GetApparentType(expr->argument_->Check(checker)); in Check()
1237 ArenaVector<Type *> awaitedTypes(checker->ProgramAllocator()->Adapter()); in Check()
1239 if (argType->IsETSUnionType()) { in Check()
1240 for (Type *type : argType->AsETSUnionType()->ConstituentTypes()) { in Check()
1241 if (!IsPromiseType(type, checker)) { in Check()
1242 … return checker->TypeError(expr, diagnostic::AWAITED_NOT_PROMISE, expr->Argument()->Start()); in Check()
1245 Type *typeArg = type->AsETSObjectType()->TypeArguments().at(0); in Check()
1249 if (!IsPromiseType(argType, checker)) { in Check()
1250 … return checker->TypeError(expr, diagnostic::AWAITED_NOT_PROMISE, expr->Argument()->Start()); in Check()
1253 Type *typeArg = argType->AsETSObjectType()->TypeArguments().at(0); in Check()
1257 …expr->SetTsType(argType->IsETSUnionType() ? checker->CreateETSUnionType(std::move(awaitedTypes)) :… in Check()
1258 return expr->TsType(); in Check()
1261 checker::Type *ETSAnalyzer::UnwrapPromiseType(checker::Type *type) const in UnwrapPromiseType()
1263 ETSChecker *checker = GetETSChecker(); in UnwrapPromiseType() local
1264 checker::Type *promiseType = checker->GlobalBuiltinPromiseType(); in UnwrapPromiseType()
1265 … while (type->IsETSObjectType() && type->AsETSObjectType()->GetOriginalBaseType() == promiseType) { in UnwrapPromiseType()
1266 type = type->AsETSObjectType()->TypeArguments().at(0); in UnwrapPromiseType()
1268 if (!type->IsETSUnionType()) { in UnwrapPromiseType()
1271 const auto &ctypes = type->AsETSUnionType()->ConstituentTypes(); in UnwrapPromiseType()
1272 auto it = std::find_if(ctypes.begin(), ctypes.end(), [promiseType](checker::Type *t) { in UnwrapPromiseType()
1273 …return t == promiseType || (t->IsETSObjectType() && t->AsETSObjectType()->GetBaseType() == promise… in UnwrapPromiseType()
1280 size_t index = it - ctypes.begin(); in UnwrapPromiseType()
1283 it = std::find_if(it, ctypes.end(), [promiseType](checker::Type *t) { in UnwrapPromiseType()
1284 return t == promiseType || t->AsETSObjectType()->GetBaseType() == promiseType; in UnwrapPromiseType()
1287 return checker->CreateETSUnionType(std::move(newCTypes)); in UnwrapPromiseType()
1290 checker::Type *ETSAnalyzer::Check(ir::BinaryExpression *expr) const in Check()
1292 if (expr->TsType() != nullptr) { in Check()
1293 return expr->TsType(); in Check()
1296 ETSChecker *checker = GetETSChecker(); in Check() local
1299 if (!checker->Context().IsInTestExpression()) { in Check()
1300 switch (expr->OperatorType()) { in Check()
1309 SmartCastArray smartCasts = checker->Context().EnterTestExpression(); in Check()
1317 checker::Type *newTsType {nullptr}; in Check()
1318 std::tie(newTsType, expr->operationType_) = in Check()
1319 …checker->CheckBinaryOperator(expr->Left(), expr->Right(), expr, expr->OperatorType(), expr->Start(… in Check()
1320 expr->SetTsType(newTsType); in Check()
1322 checker->Context().CheckBinarySmartCastCondition(expr); in Check()
1325 checker->Context().ExitTestExpression(); in Check()
1328 return expr->TsType(); in Check()
1331 checker::Type *ETSAnalyzer::Check(ir::BlockExpression *st) const in Check()
1333 if (st->TsType() != nullptr) { in Check()
1334 return st->TsType(); in Check()
1337 ETSChecker *checker = GetETSChecker(); in Check() local
1338 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
1340 // NOLINTNEXTLINE(modernize-loop-convert) in Check()
1341 for (std::size_t idx = 0; idx < st->Statements().size(); idx++) { in Check()
1342 st->Statements()[idx]->Check(checker); in Check()
1345 auto lastStmt = st->Statements().back(); in Check()
1346 ES2PANDA_ASSERT(lastStmt->IsExpressionStatement()); in Check()
1347 st->SetTsType(lastStmt->AsExpressionStatement()->GetExpression()->TsType()); in Check()
1348 return st->TsType(); in Check()
1353 if (!expr->Callee()->IsMemberExpression()) { in LambdaIsField()
1356 auto *me = expr->Callee()->AsMemberExpression(); in LambdaIsField()
1357 return me->PropVar() != nullptr; in LambdaIsField()
1360 checker::Signature *ETSAnalyzer::ResolveSignature(ETSChecker *checker, ir::CallExpression *expr, in ResolveSignature() argument
1361 checker::Type *calleeType) const in ResolveSignature()
1363 if (calleeType->IsETSFunctionType() && calleeType->AsETSFunctionType()->HasHelperSignature() && in ResolveSignature()
1364 expr->Signature() != nullptr) { in ResolveSignature()
1366 auto *helperSignature = calleeType->AsETSFunctionType()->GetHelperSignature(); in ResolveSignature()
1367 …checker->LogDiagnostic(diagnostic::DUPLICATE_SIGS, {helperSignature->Function()->Id()->Name(), hel… in ResolveSignature()
1368 expr->Start()); in ResolveSignature()
1369 checker->CreateOverloadSigContainer(helperSignature); in ResolveSignature()
1370 …return checker->ResolveCallExpressionAndTrailingLambda(checker->GetOverloadSigContainer(), expr, e… in ResolveSignature()
1373 if (calleeType->IsETSExtensionFuncHelperType()) { in ResolveSignature()
1375 …ResolveCallForETSExtensionFuncHelperType(calleeType->AsETSExtensionFuncHelperType(), checker, expr… in ResolveSignature()
1376 GetChecker()->AsETSChecker()->UpdateDeclarationFromSignature(expr, signature); in ResolveSignature()
1382 if (checker->IsExtensionETSFunctionType(calleeType) && !LambdaIsField(expr)) { in ResolveSignature()
1383 auto *signature = ResolveCallExtensionFunction(calleeType, checker, expr); in ResolveSignature()
1384 if (signature != nullptr && signature->IsExtensionAccessor() && in ResolveSignature()
1385 !checker->HasStatus(CheckerStatus::IN_EXTENSION_ACCESSOR_CHECK)) { in ResolveSignature()
1386 checker->LogError(diagnostic::EXTENSION_ACCESSOR_INVALID_CALL, {}, expr->Start()); in ResolveSignature()
1391 …auto &signatures = expr->IsETSConstructorCall() ? calleeType->AsETSObjectType()->ConstructSignatur… in ResolveSignature()
1392 … : calleeType->AsETSFunctionType()->CallSignaturesOfMethodOrArrow(); in ResolveSignature()
1394 return checker->ResolveCallExpressionAndTrailingLambda(signatures, expr, expr->Start()); in ResolveSignature()
1397 static ETSObjectType *GetCallExpressionCalleeObject(ETSChecker *checker, ir::CallExpression *expr, … in GetCallExpressionCalleeObject() argument
1399 if (expr->IsETSConstructorCall()) { in GetCallExpressionCalleeObject()
1400 return calleeType->AsETSObjectType(); in GetCallExpressionCalleeObject()
1402 auto callee = expr->Callee(); in GetCallExpressionCalleeObject()
1403 if (callee->IsMemberExpression()) { in GetCallExpressionCalleeObject()
1404 return callee->AsMemberExpression()->ObjType(); in GetCallExpressionCalleeObject()
1406 ES2PANDA_ASSERT(callee->IsIdentifier()); in GetCallExpressionCalleeObject()
1407 return checker->Context().ContainingClass(); in GetCallExpressionCalleeObject()
1412 ETSChecker *checker = GetETSChecker(); in GetReturnType() local
1414 if (calleeType->IsTypeError()) { in GetReturnType()
1415 return checker->GlobalTypeError(); in GetReturnType()
1418 if (!calleeType->IsETSFunctionType() && !expr->IsETSConstructorCall() && in GetReturnType()
1419 !calleeType->IsETSExtensionFuncHelperType()) { in GetReturnType()
1420 checker->LogError(diagnostic::NO_CALL_SIGNATURE, {calleeType}, expr->Start()); in GetReturnType()
1421 return checker->GlobalTypeError(); in GetReturnType()
1424 Signature *const signature = ResolveSignature(checker, expr, calleeType); in GetReturnType()
1426 return checker->GlobalTypeError(); in GetReturnType()
1429 checker->CheckObjectLiteralArguments(signature, expr->Arguments()); in GetReturnType()
1431 if (calleeType->IsETSMethodType()) { in GetReturnType()
1432 ETSObjectType *calleeObj = GetCallExpressionCalleeObject(checker, expr, calleeType); in GetReturnType()
1433 checker->ValidateSignatureAccessibility(calleeObj, signature, expr->Start()); in GetReturnType()
1436 if (calleeType->IsETSMethodType() && signature->Function()->IsDynamic()) { in GetReturnType()
1437 ES2PANDA_ASSERT(signature->Function()->IsDynamic()); in GetReturnType()
1438 auto lang = signature->Function()->Language(); in GetReturnType()
1439 …expr->SetSignature(checker->ResolveDynamicCallExpression(expr->Callee(), signature->Params(), lang… in GetReturnType()
1441 expr->SetSignature(signature); in GetReturnType()
1445 if (signature->HasSignatureFlag(SignatureFlags::THIS_RETURN_TYPE)) { in GetReturnType()
1446 return signature->HasSignatureFlag(SignatureFlags::EXTENSION_FUNCTION) in GetReturnType()
1447 ? expr->Arguments()[0]->TsType() in GetReturnType()
1448 : GetCallExpressionCalleeObject(checker, expr, calleeType); in GetReturnType()
1450 return signature->ReturnType(); in GetReturnType()
1453 static void CheckAbstractCall(ETSChecker *checker, ir::CallExpression *expr) in CheckAbstractCall() argument
1455 if (expr->Callee()->IsMemberExpression()) { in CheckAbstractCall()
1456 auto obj = expr->Callee()->AsMemberExpression()->Object(); in CheckAbstractCall()
1457 if (obj != nullptr && obj->IsSuperExpression()) { in CheckAbstractCall()
1458 …if ((expr->Signature() != nullptr) && (expr->Signature()->HasSignatureFlag(SignatureFlags::ABSTRAC… in CheckAbstractCall()
1459 checker->LogError(diagnostic::ABSTRACT_CALL, {}, expr->Start()); in CheckAbstractCall()
1460 expr->SetTsType(checker->GlobalTypeError()); in CheckAbstractCall()
1466 static void CheckCallee(ETSChecker *checker, ir::CallExpression *expr) in CheckCallee() argument
1468 checker->CheckNonNullish(expr->Callee()); in CheckCallee()
1469 …if (expr->Callee()->IsMemberExpression() && expr->Callee()->AsMemberExpression()->Object() != null… in CheckCallee()
1470 expr->Callee()->AsMemberExpression()->Object()->TsType()->IsETSObjectType() && in CheckCallee()
1471 expr->Callee()->AsMemberExpression()->Object()->TsType()->AsETSObjectType()->HasObjectFlag( in CheckCallee()
1473 checker->LogError(diagnostic::READONLY_CALL, {}, expr->Start()); in CheckCallee()
1474 expr->SetTsType(checker->GlobalTypeError()); in CheckCallee()
1479 static checker::SavedCheckerContext ReconstructOwnerClassContext(ETSChecker *checker, ETSObjectType… in ReconstructOwnerClassContext() argument
1482 return SavedCheckerContext(checker, CheckerStatus::NO_OPTS, nullptr); in ReconstructOwnerClassContext()
1484 ES2PANDA_ASSERT(!owner->HasObjectFlag(ETSObjectFlags::ENUM)); in ReconstructOwnerClassContext()
1486 …(owner->HasObjectFlag(ETSObjectFlags::CLASS) ? CheckerStatus::IN_CLASS : CheckerStatus::IN_INTERFA… in ReconstructOwnerClassContext()
1487 …(owner->HasObjectFlag(ETSObjectFlags::ABSTRACT) ? CheckerStatus::IN_ABSTRACT : CheckerStatus::NO_O… in ReconstructOwnerClassContext()
1488 …(owner->HasObjectFlag(ETSObjectFlags::INNER) ? CheckerStatus::INNER_CLASS : CheckerStatus::NO_OPTS… in ReconstructOwnerClassContext()
1489 … (owner->GetDeclNode()->IsClassDefinition() && owner->GetDeclNode()->AsClassDefinition()->IsLocal() in ReconstructOwnerClassContext()
1493 return SavedCheckerContext(checker, status, owner); in ReconstructOwnerClassContext()
1496 checker::Type *ETSAnalyzer::GetCallExpressionReturnType(ir::CallExpression *expr, checker::Type *ca… in GetCallExpressionReturnType()
1498 ETSChecker *checker = GetETSChecker(); in GetCallExpressionReturnType() local
1499 checker::Type *returnType = nullptr; in GetCallExpressionReturnType()
1500 if (UNLIKELY(calleeType->IsETSDynamicType() && !calleeType->AsETSDynamicType()->HasDecl())) { in GetCallExpressionReturnType()
1502 checker->EnsureValidCurlyBrace(expr); in GetCallExpressionReturnType()
1503 auto lang = calleeType->AsETSDynamicType()->Language(); in GetCallExpressionReturnType()
1504 …expr->SetSignature(checker->ResolveDynamicCallExpression(expr->Callee(), expr->Arguments(), lang, … in GetCallExpressionReturnType()
1505 returnType = expr->Signature()->ReturnType(); in GetCallExpressionReturnType()
1510 if (returnType->IsTypeError()) { in GetCallExpressionReturnType()
1511 return checker->GlobalTypeError(); in GetCallExpressionReturnType()
1514 auto *const signature = expr->Signature(); in GetCallExpressionReturnType()
1515 if (signature->RestVar() != nullptr && signature->RestVar()->TsType()->IsETSArrayType()) { in GetCallExpressionReturnType()
1516 auto *elementType = signature->RestVar()->TsType()->AsETSArrayType()->ElementType(); in GetCallExpressionReturnType()
1517 auto *const arrayType = checker->CreateETSArrayType(elementType)->AsETSArrayType(); in GetCallExpressionReturnType()
1518 checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); in GetCallExpressionReturnType()
1521 if (!signature->HasSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE) || in GetCallExpressionReturnType()
1522 (signature->HasSignatureFlag(checker::SignatureFlags::CONSTRUCTOR))) { in GetCallExpressionReturnType()
1526 if (!signature->HasFunction()) { in GetCallExpressionReturnType()
1527 return checker->GlobalTypeError(); in GetCallExpressionReturnType()
1530 …auto owner = const_cast<ETSObjectType *>(util::Helpers::GetContainingObjectType(signature->Functio… in GetCallExpressionReturnType()
1531 SavedCheckerContext savedCtx(ReconstructOwnerClassContext(checker, owner)); in GetCallExpressionReturnType()
1533 ir::AstNode *methodDef = signature->Function(); in GetCallExpressionReturnType()
1534 while (!methodDef->IsMethodDefinition()) { in GetCallExpressionReturnType()
1535 methodDef = methodDef->Parent(); in GetCallExpressionReturnType()
1538 ES2PANDA_ASSERT(methodDef->IsMethodDefinition()); in GetCallExpressionReturnType()
1539 methodDef->Check(checker); in GetCallExpressionReturnType()
1541 if (!signature->Function()->HasBody()) { in GetCallExpressionReturnType()
1542 return signature->ReturnType(); in GetCallExpressionReturnType()
1545 if (signature->Function()->IsExternal()) { in GetCallExpressionReturnType()
1546 …checker->VarBinder()->AsETSBinder()->ResolveReferencesForScopeWithContext(signature->Function()->B… in GetCallExpressionReturnType()
1547 … signature->Function()->Scope()); in GetCallExpressionReturnType()
1549 checker::ScopeContext scopeCtx(checker, signature->Function()->Body()->Scope()); in GetCallExpressionReturnType()
1550 checker->CollectReturnStatements(signature->Function()); in GetCallExpressionReturnType()
1551 return signature->ReturnType(); in GetCallExpressionReturnType()
1555 checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const in Check()
1557 ETSChecker *checker = GetETSChecker(); in Check() local
1558 if (expr->TsType() != nullptr) { in Check()
1559 return expr->TsType(); in Check()
1561 ES2PANDA_ASSERT(!expr->IsOptional()); in Check()
1563 auto *oldCallee = expr->Callee(); in Check()
1564 checker::Type *calleeType = checker->GetApparentType(expr->Callee()->Check(checker)); in Check()
1565 if (calleeType->IsTypeError()) { in Check()
1566 return checker->InvalidateType(expr); in Check()
1569 if (expr->Callee() != oldCallee) { in Check()
1572 calleeType = checker->GetApparentType(expr->Callee()->Check(checker)); in Check()
1575 CheckCallee(checker, expr); in Check()
1577 checker::TypeStackElement tse(checker, expr, {{diagnostic::CYCLIC_CALLEE, {}}}, expr->Start()); in Check()
1579 expr->SetTsType(checker->GlobalTypeError()); in Check()
1580 return checker->GlobalTypeError(); in Check()
1583 checker::Type *const returnType = GetCallExpressionReturnType(expr, calleeType); in Check()
1584 expr->SetTsType(returnType); in Check()
1585 if (returnType->IsTypeError()) { in Check()
1588 if (calleeType->IsETSArrowType()) { in Check()
1589 expr->SetUncheckedType(checker->GuaranteedTypeForUncheckedCast( in Check()
1590 checker->GlobalETSAnyType(), checker->MaybeBoxType(expr->Signature()->ReturnType()))); in Check()
1592 expr->SetUncheckedType(checker->GuaranteedTypeForUncheckedCallReturn(expr->Signature())); in Check()
1595 if (expr->UncheckedType() != nullptr) { in Check()
1596 ES2PANDA_ASSERT(expr->UncheckedType()->IsETSReferenceType()); in Check()
1597 checker->ComputeApparentType(returnType); in Check()
1600 if (returnType->IsTypeError()) { in Check()
1601 expr->SetTsType(returnType); in Check()
1602 return expr->TsType(); in Check()
1605 CheckVoidTypeExpression(checker, expr); in Check()
1606 CheckAbstractCall(checker, expr); in Check()
1607 return expr->TsType(); in Check()
1610 checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const in Check()
1612 if (expr->TsType() != nullptr) { in Check()
1613 return expr->TsType(); in Check()
1616 ETSChecker *const checker = GetETSChecker(); in Check() local
1618 SmartCastArray smartCasts = checker->Context().EnterTestExpression(); in Check()
1619 checker->CheckTruthinessOfType(expr->Test()); in Check()
1620 SmartCastTypes testedTypes = checker->Context().ExitTestExpression(); in Check()
1623 checker->ApplySmartCast(variable, consequentType); in Check()
1627 auto *consequent = expr->Consequent(); in Check()
1628 Type *consequentType = consequent->Check(checker); in Check()
1630 SmartCastArray consequentSmartCasts = checker->Context().CloneSmartCasts(); in Check()
1631 checker->Context().RestoreSmartCasts(smartCasts); in Check()
1635 checker->ApplySmartCast(variable, alternateType); in Check()
1639 auto *alternate = expr->Alternate(); in Check()
1640 Type *alternateType = alternate->Check(checker); in Check()
1643 checker->Context().CombineSmartCasts(consequentSmartCasts); in Check()
1645 if (checker->IsTypeIdenticalTo(consequentType, alternateType)) { in Check()
1646 expr->SetTsType(consequentType); in Check()
1648 … possible and required update number literal type to the proper value (identical to left-side type) in Check()
1649 if (alternate->IsNumberLiteral() && in Check()
1650 … checker->AdjustNumberLiteralType(alternate->AsNumberLiteral(), alternateType, consequentType)) { in Check()
1651 expr->SetTsType(consequentType); in Check()
1652 } else if (consequent->IsNumberLiteral() && in Check()
1653 … checker->AdjustNumberLiteralType(consequent->AsNumberLiteral(), consequentType, alternateType)) { in Check()
1654 expr->SetTsType(alternateType); in Check()
1656 expr->SetTsType(checker->CreateETSUnionType({consequentType, alternateType})); in Check()
1657 if (expr->TsType()->IsETSReferenceType()) { in Check()
1658 checker->MaybeBoxExpression(expr->Consequent()); in Check()
1659 checker->MaybeBoxExpression(expr->Alternate()); in Check()
1665 checker->Context().RestoreSmartCasts(smartCasts); in Check()
1667 return expr->TsType(); in Check()
1671 static Type *TransformTypeForMethodReference(ETSChecker *checker, ir::Expression *const use, Type *… in TransformTypeForMethodReference() argument
1673 ES2PANDA_ASSERT(use->IsIdentifier() || use->IsMemberExpression()); in TransformTypeForMethodReference()
1674 if (!type->IsETSMethodType()) { in TransformTypeForMethodReference()
1678 return use->IsIdentifier() ? use->Start() : use->AsMemberExpression()->Property()->Start(); in TransformTypeForMethodReference()
1682 …while (expr->Parent()->IsMemberExpression() && expr->Parent()->AsMemberExpression()->Property() ==… in TransformTypeForMethodReference()
1683 expr = expr->Parent()->AsMemberExpression(); in TransformTypeForMethodReference()
1685 … if (expr->Parent()->IsCallExpression() && expr->Parent()->AsCallExpression()->Callee() == expr) { in TransformTypeForMethodReference()
1689 auto *const functionType = type->AsETSFunctionType(); in TransformTypeForMethodReference()
1690 auto &signatures = functionType->CallSignatures(); in TransformTypeForMethodReference()
1692 if (signatures.at(0)->HasSignatureFlag(SignatureFlags::PRIVATE)) { in TransformTypeForMethodReference()
1693 checker->LogError(diagnostic::PRIVATE_METHOD_AS_VALUE, getUseSite()); in TransformTypeForMethodReference()
1694 return checker->GlobalTypeError(); in TransformTypeForMethodReference()
1699 if ((*it)->HasSignatureFlag(SignatureFlags::ABSTRACT) && in TransformTypeForMethodReference()
1700 !(*it)->Owner()->GetDeclNode()->IsTSInterfaceDeclaration()) { in TransformTypeForMethodReference()
1708 checker->LogError(diagnostic::OVERLOADED_METHOD_AS_VALUE, getUseSite()); in TransformTypeForMethodReference()
1709 return checker->GlobalTypeError(); in TransformTypeForMethodReference()
1711 return type->AsETSFunctionType()->MethodToArrow(checker); in TransformTypeForMethodReference()
1714 checker::Type *ETSAnalyzer::Check(ir::Identifier *expr) const in Check()
1716 if (expr->TsType() != nullptr) { in Check()
1717 return expr->TsType(); in Check()
1720 ETSChecker *checker = GetETSChecker(); in Check() local
1722 …auto *identType = TransformTypeForMethodReference(checker, expr, checker->ResolveIdentifier(expr)); in Check()
1724 if (expr->TsType() != nullptr && expr->TsType()->IsTypeError()) { in Check()
1725 return expr->TsType(); in Check()
1727 ES2PANDA_ASSERT(expr->Variable() != nullptr); in Check()
1728 if (expr->Parent() == nullptr || !expr->Parent()->IsAssignmentExpression() || in Check()
1729 expr != expr->Parent()->AsAssignmentExpression()->Left()) { in Check()
1730 auto *const smartType = checker->Context().GetSmartCast(expr->Variable()); in Check()
1737 expr->SetTsType(identType); in Check()
1738 if (!identType->IsTypeError()) { in Check()
1739 checker->Context().CheckIdentifierSmartCastCondition(expr); in Check()
1741 return expr->TsType(); in Check()
1744 std::pair<checker::Type *, util::StringView> SearchReExportsType(ETSObjectType *baseType, ir::Membe… in SearchReExportsType()
1745 … util::StringView &aliasName, ETSChecker *checker) in SearchReExportsType() argument
1749 for (auto *const item : baseType->ReExports()) { in SearchReExportsType()
1750 auto name = item->GetReExportAliasValue(aliasName); in SearchReExportsType()
1751 if (name == aliasName && item->IsReExportHaveAliasValue(name)) { in SearchReExportsType()
1755 if (item->GetProperty(name, PropertySearchFlags::SEARCH_ALL) != nullptr) { in SearchReExportsType()
1757 checker->LogError(diagnostic::AMBIGUOUS_REFERENCE, {aliasName}, expr->Start()); in SearchReExportsType()
1758 expr->SetTsType(checker->GlobalTypeError()); in SearchReExportsType()
1764 …if (auto reExportType = SearchReExportsType(item, expr, name, checker); reExportType.first != null… in SearchReExportsType()
1772 static void TypeErrorOnMissingProperty(ir::MemberExpression *expr, checker::Type *baseType, in TypeErrorOnMissingProperty()
1773 checker::ETSChecker *checker) in TypeErrorOnMissingProperty() argument
1775 std::ignore = checker->TypeError(expr, diagnostic::PROPERTY_NONEXISTENT, in TypeErrorOnMissingProperty()
1776 … {expr->Property()->AsIdentifier()->Name(), baseType}, expr->Object()->Start()); in TypeErrorOnMissingProperty()
1779 checker::Type *ETSAnalyzer::ResolveMemberExpressionByBaseType(ETSChecker *checker, checker::Type *b… in ResolveMemberExpressionByBaseType() argument
1782 if (baseType->IsTypeError()) { in ResolveMemberExpressionByBaseType()
1783 return checker->InvalidateType(expr); in ResolveMemberExpressionByBaseType()
1786 if (baseType->IsETSArrayType()) { in ResolveMemberExpressionByBaseType()
1787 if (expr->Property()->AsIdentifier()->Name().Is("length")) { in ResolveMemberExpressionByBaseType()
1788 return expr->AdjustType(checker, checker->GlobalIntType()); in ResolveMemberExpressionByBaseType()
1791 return expr->SetAndAdjustType(checker, checker->GlobalETSObjectType()); in ResolveMemberExpressionByBaseType()
1794 if (baseType->IsETSTupleType()) { in ResolveMemberExpressionByBaseType()
1795 return expr->SetAndAdjustType(checker, checker->GlobalETSObjectType()); in ResolveMemberExpressionByBaseType()
1798 if (baseType->IsETSFunctionType()) { in ResolveMemberExpressionByBaseType()
1799 return expr->SetAndAdjustType(checker, checker->GlobalBuiltinFunctionType()); in ResolveMemberExpressionByBaseType()
1802 if (baseType->IsETSObjectType()) { in ResolveMemberExpressionByBaseType()
1803 checker->ETSObjectTypeDeclNode(checker, baseType->AsETSObjectType()); in ResolveMemberExpressionByBaseType()
1804 return expr->SetTsType(TransformTypeForMethodReference( in ResolveMemberExpressionByBaseType()
1805 checker, expr, expr->SetAndAdjustType(checker, baseType->AsETSObjectType()))); in ResolveMemberExpressionByBaseType()
1808 if (baseType->IsETSUnionType()) { in ResolveMemberExpressionByBaseType()
1809 return expr->AdjustType(checker, expr->CheckUnionMember(checker, baseType)); in ResolveMemberExpressionByBaseType()
1814 if (baseType->IsETSPrimitiveType()) { in ResolveMemberExpressionByBaseType()
1824 auto method = expr->Property()->AsIdentifier()->Name().Utf8(); in ResolveMemberExpressionByBaseType()
1827 auto type = checker->MaybeBoxType(baseType); in ResolveMemberExpressionByBaseType()
1828 expr->SetAstNodeFlags(ir::AstNodeFlags::TMP_CONVERT_PRIMITIVE_CAST_METHOD_CALL); in ResolveMemberExpressionByBaseType()
1829 checker->ETSObjectTypeDeclNode(checker, type->AsETSObjectType()); in ResolveMemberExpressionByBaseType()
1830 return expr->SetTsType(TransformTypeForMethodReference( in ResolveMemberExpressionByBaseType()
1831 checker, expr, expr->SetAndAdjustType(checker, type->AsETSObjectType()))); in ResolveMemberExpressionByBaseType()
1835 TypeErrorOnMissingProperty(expr, baseType, checker); in ResolveMemberExpressionByBaseType()
1836 return expr->TsType(); in ResolveMemberExpressionByBaseType()
1839 checker::Type *ETSAnalyzer::Check(ir::MemberExpression *expr) const in Check()
1841 if (expr->TsType() != nullptr) { in Check()
1842 return expr->TsType(); in Check()
1844 ES2PANDA_ASSERT(!expr->IsOptional()); in Check()
1845 ETSChecker *checker = GetETSChecker(); in Check() local
1846 …auto *baseType = checker->GetNonConstantType(checker->GetApparentType(expr->Object()->Check(checke… in Check()
1847 // Note: don't use possible smart cast to null-like types. in Check()
1850 if (baseType->DefinitelyETSNullish() && expr->Object()->IsIdentifier()) { in Check()
1851 baseType = expr->Object()->AsIdentifier()->Variable()->TsType(); in Check()
1854 if (baseType->IsETSObjectType() && !baseType->AsETSObjectType()->ReExports().empty() && in Check()
1855 baseType->AsETSObjectType()->GetProperty(expr->Property()->AsIdentifier()->Name(), in Check()
1857 if (auto reExportType = SearchReExportsType(baseType->AsETSObjectType(), expr, in Check()
1858 … expr->Property()->AsIdentifier()->Name(), checker); in Check()
1861 expr->object_->AsIdentifier()->SetTsType(baseType); in Check()
1862 expr->property_->AsIdentifier()->SetName(reExportType.second); in Check()
1865 if (!checker->CheckNonNullish(expr->Object())) { in Check()
1866 auto *invalidType = checker->HasStatus(checker::CheckerStatus::IN_EXTENSION_ACCESSOR_CHECK) in Check()
1867 ? checker->GlobalETSUnionUndefinedNull() in Check()
1868 : checker->InvalidateType(expr); in Check()
1872 if (expr->IsComputed()) { in Check()
1873 return expr->AdjustType(checker, expr->CheckComputed(checker, baseType)); in Check()
1876 return ResolveMemberExpressionByBaseType(checker, baseType, expr); in Check()
1879 checker::Type *ETSAnalyzer::PreferredType(ir::ObjectExpression *expr) const in PreferredType()
1881 return expr->preferredType_; in PreferredType()
1884 checker::Type *ETSAnalyzer::CheckDynamic(ir::ObjectExpression *expr) const in CheckDynamic()
1886 ETSChecker *checker = GetETSChecker(); in CheckDynamic() local
1887 for (ir::Expression *propExpr : expr->Properties()) { in CheckDynamic()
1888 ES2PANDA_ASSERT(propExpr->IsProperty()); in CheckDynamic()
1889 ir::Property *prop = propExpr->AsProperty(); in CheckDynamic()
1890 ir::Expression *value = prop->Value(); in CheckDynamic()
1891 value->Check(checker); in CheckDynamic()
1892 ES2PANDA_ASSERT(value->TsType()); in CheckDynamic()
1895 expr->SetTsType(expr->PreferredType()); in CheckDynamic()
1896 return expr->PreferredType(); in CheckDynamic()
1899 static bool ValidatePreferredType(ETSChecker *checker, ir::ObjectExpression *expr) in ValidatePreferredType() argument
1901 auto preferredType = expr->PreferredType(); in ValidatePreferredType()
1903 checker->LogError(diagnostic::CLASS_COMPOSITE_UNKNOWN_TYPE, {}, expr->Start()); in ValidatePreferredType()
1907 if (preferredType->IsTypeError()) { in ValidatePreferredType()
1912 if (!preferredType->IsETSObjectType()) { in ValidatePreferredType()
1913 … checker->LogError(diagnostic::CLASS_COMPOSITE_INVALID_TARGET, {preferredType}, expr->Start()); in ValidatePreferredType()
1920 static void SetTypeforRecordProperties(const ir::ObjectExpression *expr, checker::ETSObjectType *ob… in SetTypeforRecordProperties()
1921 ETSChecker *checker) in SetTypeforRecordProperties() argument
1923 const auto &recordProperties = expr->Properties(); in SetTypeforRecordProperties()
1924 auto typeArguments = objType->TypeArguments(); in SetTypeforRecordProperties()
1929 if (recordProperty->IsProperty()) { in SetTypeforRecordProperties()
1930 recordPropertyExpr = recordProperty->AsProperty()->Value(); in SetTypeforRecordProperties()
1931 } else if (recordProperty->IsSpreadElement()) { in SetTypeforRecordProperties()
1932 recordPropertyExpr = recordProperty->AsSpreadElement()->Argument(); in SetTypeforRecordProperties()
1938 recordPropertyExpr->Check(checker); in SetTypeforRecordProperties()
1943 static bool HasParameterlessConstructor(checker::ETSObjectType *objType, ETSChecker *checker, in HasParameterlessConstructor() argument
1946 for (checker::Signature *sig : objType->ConstructSignatures()) { in HasParameterlessConstructor()
1947 if (sig->Params().empty()) { in HasParameterlessConstructor()
1948 checker->ValidateSignatureAccessibility(objType, sig, pos); in HasParameterlessConstructor()
1958 if (key->IsStringLiteral()) { in GetPropertyNameFromKey()
1959 return key->AsStringLiteral()->Str(); in GetPropertyNameFromKey()
1961 if (key->IsIdentifier()) { in GetPropertyNameFromKey()
1962 return key->AsIdentifier()->Name(); in GetPropertyNameFromKey()
1968 static checker::PropertySearchFlags DetermineSearchFlagsForLiteral(checker::ETSObjectType *potentia… in DetermineSearchFlagsForLiteral()
1970 if (potentialObjType->HasObjectFlag(checker::ETSObjectFlags::INTERFACE)) { in DetermineSearchFlagsForLiteral()
1971 return checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD | in DetermineSearchFlagsForLiteral()
1972 checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD | in DetermineSearchFlagsForLiteral()
1973 …checker::PropertySearchFlags::SEARCH_INSTANCE_DECL | checker::PropertySearchFlags::SEARCH_IN_INTER… in DetermineSearchFlagsForLiteral()
1975 …return checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD | checker::PropertySearchFlags::SEARCH_… in DetermineSearchFlagsForLiteral()
1976 checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD; in DetermineSearchFlagsForLiteral()
1979 static bool CheckSinglePropertyCompatibility(ir::Expression *propExpr, checker::ETSObjectType *pote… in CheckSinglePropertyCompatibility()
1981 if (!propExpr->IsProperty()) { in CheckSinglePropertyCompatibility()
1982 return false; // Not a key-value property in CheckSinglePropertyCompatibility()
1984 ir::Expression *key = propExpr->AsProperty()->Key(); in CheckSinglePropertyCompatibility()
1992 checker::PropertySearchFlags searchFlags = DetermineSearchFlagsForLiteral(potentialObjType); in CheckSinglePropertyCompatibility()
1994 return potentialObjType->GetProperty(pname, searchFlags) != nullptr; in CheckSinglePropertyCompatibility()
1997 static bool CheckObjectLiteralCompatibility(ir::ObjectExpression *expr, checker::ETSObjectType *pot… in CheckObjectLiteralCompatibility()
1999 for (ir::Expression *propExpr : expr->Properties()) { in CheckObjectLiteralCompatibility()
2008 static bool IsPropertyTypeOptional(checker::Type *propertyType) in IsPropertyTypeOptional()
2010 if (!propertyType->IsETSUnionType()) { in IsPropertyTypeOptional()
2014 auto *unionType = propertyType->AsETSUnionType(); in IsPropertyTypeOptional()
2015 for (auto *constituentType : unionType->ConstituentTypes()) { in IsPropertyTypeOptional()
2016 if (constituentType->IsETSUndefinedType()) { in IsPropertyTypeOptional()
2026 auto *decl = property->Declaration(); in HasPropertyDefaultValue()
2027 if (decl == nullptr || decl->Node() == nullptr || !decl->Node()->IsClassProperty()) { in HasPropertyDefaultValue()
2031 auto *classProp = decl->Node()->AsClassProperty(); in HasPropertyDefaultValue()
2032 return classProp->Value() != nullptr; in HasPropertyDefaultValue()
2036 static bool IsPropertyOptional(varbinder::LocalVariable *property, checker::Type *propertyType) in IsPropertyOptional()
2039 if (property->HasFlag(varbinder::VariableFlags::OPTIONAL)) { in IsPropertyOptional()
2049 auto *decl = property->Declaration(); in IsPropertyOptional()
2050 if (decl != nullptr && decl->Node() != nullptr && decl->Node()->IsClassProperty()) { in IsPropertyOptional()
2051 auto *classProp = decl->Node()->AsClassProperty(); in IsPropertyOptional()
2052 if (classProp->IsOptionalDeclaration()) { in IsPropertyOptional()
2061 static bool IsMethodOnlyAccessors(checker::Type *propertyType) in IsMethodOnlyAccessors()
2063 if (!propertyType->IsETSMethodType()) { in IsMethodOnlyAccessors()
2067 auto methodType = propertyType->AsETSFunctionType(); in IsMethodOnlyAccessors()
2068 for (auto *sig : methodType->CallSignatures()) { in IsMethodOnlyAccessors()
2069 if (!sig->HasSignatureFlag(checker::SignatureFlags::GETTER) && in IsMethodOnlyAccessors()
2070 !sig->HasSignatureFlag(checker::SignatureFlags::SETTER)) { in IsMethodOnlyAccessors()
2079 static bool IsInterfacePropertyCompatible(ir::Expression *propExpr, checker::ETSObjectType *interfa… in IsInterfacePropertyCompatible()
2080 ETSChecker *checker) in IsInterfacePropertyCompatible() argument
2082 if (!propExpr->IsProperty()) { in IsInterfacePropertyCompatible()
2086 ir::Expression *key = propExpr->AsProperty()->Key(); in IsInterfacePropertyCompatible()
2095 interfaceType->GetProperty(pname, checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD | in IsInterfacePropertyCompatible()
2096 checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD | in IsInterfacePropertyCompatible()
2097 checker::PropertySearchFlags::SEARCH_INSTANCE_DECL | in IsInterfacePropertyCompatible()
2098 checker::PropertySearchFlags::SEARCH_IN_INTERFACES); in IsInterfacePropertyCompatible()
2104 auto *propertyType = checker->GetTypeOfVariable(property); in IsInterfacePropertyCompatible()
2107 if (propertyType->IsETSMethodType()) { in IsInterfacePropertyCompatible()
2116 … checker::ETSObjectType *interfaceType, ETSChecker *checker) in AreAllRequiredInterfacePropertiesSatisfied() argument
2119 auto allProperties = interfaceType->GetAllProperties(); in AreAllRequiredInterfacePropertiesSatisfied()
2123 for (ir::Expression *propExpr : expr->Properties()) { in AreAllRequiredInterfacePropertiesSatisfied()
2124 if (propExpr->IsProperty()) { in AreAllRequiredInterfacePropertiesSatisfied()
2125 ir::Expression *key = propExpr->AsProperty()->Key(); in AreAllRequiredInterfacePropertiesSatisfied()
2136 if (property->Name().Utf8() == litPropName) { in AreAllRequiredInterfacePropertiesSatisfied()
2148 std::string propName(property->Name().Utf8()); in AreAllRequiredInterfacePropertiesSatisfied()
2149 auto *propertyType = checker->GetTypeOfVariable(property); in AreAllRequiredInterfacePropertiesSatisfied()
2152 if (propertyType->IsETSMethodType()) { in AreAllRequiredInterfacePropertiesSatisfied()
2161 // Property not in literal - check if it's optional or has default value in AreAllRequiredInterfacePropertiesSatisfied()
2173 static bool IsObjectTypeCompatibleWithLiteral(ETSChecker *checker, ir::ObjectExpression *expr, in IsObjectTypeCompatibleWithLiteral() argument
2174 checker::ETSObjectType *potentialObjType) in IsObjectTypeCompatibleWithLiteral()
2178 checker::ETSObjectType *originalBaseType = potentialObjType->GetOriginalBaseType(); in IsObjectTypeCompatibleWithLiteral()
2179 checker::GlobalTypesHolder *globalTypes = checker->GetGlobalTypesHolder(); in IsObjectTypeCompatibleWithLiteral()
2182 if (checker->IsTypeIdenticalTo(originalBaseType, globalTypes->GlobalMapBuiltinType()) || in IsObjectTypeCompatibleWithLiteral()
2183 checker->IsTypeIdenticalTo(originalBaseType, globalTypes->GlobalRecordBuiltinType())) { in IsObjectTypeCompatibleWithLiteral()
2189 if (potentialObjType->HasObjectFlag(checker::ETSObjectFlags::INTERFACE)) { in IsObjectTypeCompatibleWithLiteral()
2193 // For non-empty literals, check that all literal properties exist in interface in IsObjectTypeCompatibleWithLiteral()
2195 for (ir::Expression *propExpr : expr->Properties()) { in IsObjectTypeCompatibleWithLiteral()
2196 if (!IsInterfacePropertyCompatible(propExpr, potentialObjType, checker)) { in IsObjectTypeCompatibleWithLiteral()
2202 return AreAllRequiredInterfacePropertiesSatisfied(expr, potentialObjType, checker); in IsObjectTypeCompatibleWithLiteral()
2207 // - that there is a parameterless constructor, and in IsObjectTypeCompatibleWithLiteral()
2208 // - that all fields/properties set in the object literal are present in the class in IsObjectTypeCompatibleWithLiteral()
2210 if (!HasParameterlessConstructor(potentialObjType, checker, expr->Start())) { in IsObjectTypeCompatibleWithLiteral()
2218 checker::ETSObjectType *ResolveUnionObjectTypeForObjectLiteral(ETSChecker *checker, ir::ObjectExpre… in ResolveUnionObjectTypeForObjectLiteral() argument
2219 checker::ETSUnionType *unionType) in ResolveUnionObjectTypeForObjectLiteral()
2221 std::vector<checker::ETSObjectType *> candidateObjectTypes; in ResolveUnionObjectTypeForObjectLiteral()
2223 for (auto *constituentType : unionType->ConstituentTypes()) { in ResolveUnionObjectTypeForObjectLiteral()
2224 if (constituentType->IsETSObjectType()) { in ResolveUnionObjectTypeForObjectLiteral()
2225 candidateObjectTypes.push_back(constituentType->AsETSObjectType()); in ResolveUnionObjectTypeForObjectLiteral()
2231 …checker->LogError(diagnostic::CLASS_COMPOSITE_INVALID_TARGET, {expr->PreferredType()}, expr->Start… in ResolveUnionObjectTypeForObjectLiteral()
2235 std::vector<checker::ETSObjectType *> matchingObjectTypes; in ResolveUnionObjectTypeForObjectLiteral()
2238 if (IsObjectTypeCompatibleWithLiteral(checker, expr, potentialObjType)) { in ResolveUnionObjectTypeForObjectLiteral()
2249 …checker->LogError(diagnostic::CLASS_COMPOSITE_INVALID_TARGET, {expr->PreferredType()}, expr->Start… in ResolveUnionObjectTypeForObjectLiteral()
2253 …checker->LogError(diagnostic::AMBIGUOUS_REFERENCE, {expr->PreferredType()->ToString()}, expr->Star… in ResolveUnionObjectTypeForObjectLiteral()
2257 static checker::ETSObjectType *ResolveObjectTypeFromPreferredType(ETSChecker *checker, ir::ObjectEx… in ResolveObjectTypeFromPreferredType() argument
2260 checker::Type *preferredType = expr->PreferredType(); in ResolveObjectTypeFromPreferredType()
2262 if (preferredType->IsETSAsyncFuncReturnType()) { in ResolveObjectTypeFromPreferredType()
2263 preferredType = preferredType->AsETSAsyncFuncReturnType()->GetPromiseTypeArg(); in ResolveObjectTypeFromPreferredType()
2266 if (preferredType->IsETSUnionType()) { in ResolveObjectTypeFromPreferredType()
2267 … return ResolveUnionObjectTypeForObjectLiteral(checker, expr, preferredType->AsETSUnionType()); in ResolveObjectTypeFromPreferredType()
2270 if (preferredType->IsETSObjectType()) { in ResolveObjectTypeFromPreferredType()
2271 return preferredType->AsETSObjectType(); in ResolveObjectTypeFromPreferredType()
2278 static checker::Type *HandleInterfaceType(ETSChecker *checker, ir::ObjectExpression *expr, in HandleInterfaceType() argument
2279 checker::ETSObjectType *objType) in HandleInterfaceType()
2281 auto *analyzer = static_cast<checker::ETSAnalyzer *>(checker->GetAnalyzer()); in HandleInterfaceType()
2282 analyzer->CheckObjectExprProps( in HandleInterfaceType()
2284 …checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD | checker::PropertySearchFlags::SEARCH_INSTANC… in HandleInterfaceType()
2285 …checker::PropertySearchFlags::SEARCH_INSTANCE_DECL | checker::PropertySearchFlags::SEARCH_IN_INTER… in HandleInterfaceType()
2286 expr->SetTsType(objType); in HandleInterfaceType()
2291 static checker::Type *HandleRecordOrMapType(ETSChecker *checker, ir::ObjectExpression *expr, in HandleRecordOrMapType() argument
2292 checker::ETSObjectType *objType) in HandleRecordOrMapType()
2294 expr->SetTsType(objType); in HandleRecordOrMapType()
2295 SetTypeforRecordProperties(expr, objType, checker); in HandleRecordOrMapType()
2299 checker::Type *ETSAnalyzer::Check(ir::ObjectExpression *expr) const in Check()
2301 ETSChecker *checker = GetETSChecker(); in Check() local
2302 if (expr->TsType() != nullptr) { in Check()
2303 return expr->TsType(); in Check()
2306 if (expr->PreferredType() == nullptr) { in Check()
2307 checker->LogError(diagnostic::CLASS_COMPOSITE_UNKNOWN_TYPE, {}, expr->Start()); in Check()
2308 expr->SetTsType(checker->GlobalTypeError()); in Check()
2309 return expr->TsType(); in Check()
2312 if (!expr->PreferredType()->IsETSUnionType() && !expr->PreferredType()->IsETSDynamicType() && in Check()
2313 !ValidatePreferredType(checker, expr)) { in Check()
2314 expr->SetTsType(checker->GlobalTypeError()); in Check()
2315 return expr->TsType(); in Check()
2318 …if (expr->PreferredType()->IsETSDynamicType() && !expr->PreferredType()->AsETSDynamicType()->HasDe… in Check()
2322 checker::ETSObjectType *objType = ResolveObjectTypeFromPreferredType(checker, expr); in Check()
2325 if (!expr->PreferredType()->IsETSUnionType()) { in Check()
2326 …checker->LogError(diagnostic::CLASS_COMPOSITE_INVALID_TARGET, {expr->PreferredType()}, expr->Start… in Check()
2328 expr->SetTsType(checker->GlobalTypeError()); in Check()
2329 return expr->TsType(); in Check()
2332 if (objType->HasObjectFlag(checker::ETSObjectFlags::INTERFACE)) { in Check()
2333 return HandleInterfaceType(checker, expr, objType); in Check()
2336 checker::ETSObjectType *originalBaseObjType = objType->GetOriginalBaseType(); in Check()
2337 checker::GlobalTypesHolder *globalTypes = checker->GetGlobalTypesHolder(); in Check()
2338 if (checker->IsTypeIdenticalTo(originalBaseObjType, globalTypes->GlobalMapBuiltinType()) || in Check()
2339 checker->IsTypeIdenticalTo(originalBaseObjType, globalTypes->GlobalRecordBuiltinType())) { in Check()
2340 return HandleRecordOrMapType(checker, expr, objType); in Check()
2344 if (!HasParameterlessConstructor(objType, checker, expr->Start())) { in Check()
2345 …expr->SetTsType(checker->TypeError(expr, diagnostic::NO_PARAMLESS_CTOR, {objType->Name()}, expr->S… in Check()
2346 return expr->TsType(); in Check()
2350 checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD | in Check()
2351 checker::PropertySearchFlags::SEARCH_IN_BASE | in Check()
2352 checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD); in Check()
2354 expr->SetTsType(objType); in Check()
2359 checker::ETSObjectType *objectTypeForProperties, in CheckObjectExprProps()
2360 checker::PropertySearchFlags searchFlags) const in CheckObjectExprProps()
2362 ETSChecker *checker = GetETSChecker(); in CheckObjectExprProps() local
2363 checker::ETSObjectType *objType = objectTypeForProperties; in CheckObjectExprProps()
2365 for (ir::Expression *propExpr : expr->Properties()) { in CheckObjectExprProps()
2366 if (!propExpr->IsProperty()) { in CheckObjectExprProps()
2367 checker->LogError(diagnostic::OBJECT_LITERAL_NOT_KV, {}, expr->Start()); in CheckObjectExprProps()
2370 ir::Expression *key = propExpr->AsProperty()->Key(); in CheckObjectExprProps()
2371 ir::Expression *value = propExpr->AsProperty()->Value(); in CheckObjectExprProps()
2374 if (key->IsStringLiteral()) { in CheckObjectExprProps()
2375 pname = key->AsStringLiteral()->Str(); in CheckObjectExprProps()
2376 } else if (key->IsIdentifier()) { in CheckObjectExprProps()
2377 pname = key->AsIdentifier()->Name(); in CheckObjectExprProps()
2379 checker->LogError(diagnostic::CLASS_COMPOSITE_INVALID_KEY, {}, expr->Start()); in CheckObjectExprProps()
2382 varbinder::LocalVariable *lv = objType->GetProperty(pname, searchFlags); in CheckObjectExprProps()
2384 … checker->LogError(diagnostic::UNDEFINED_PROPERTY, {objType->Name(), pname}, propExpr->Start()); in CheckObjectExprProps()
2387 checker->ValidatePropertyAccess(lv, objType, propExpr->Start()); in CheckObjectExprProps()
2389 if (key->IsIdentifier()) { in CheckObjectExprProps()
2390 key->AsIdentifier()->SetVariable(lv); in CheckObjectExprProps()
2393 auto *propType = checker->GetTypeOfVariable(lv); in CheckObjectExprProps()
2394 if (propType->IsETSMethodType()) { in CheckObjectExprProps()
2395 checker->LogError(diagnostic::OBJECT_LITERAL_METHOD_KEY, {pname}, propExpr->Start()); in CheckObjectExprProps()
2400 propExpr->SetTsType(propType); in CheckObjectExprProps()
2401 key->SetTsType(propType); in CheckObjectExprProps()
2402 value->SetTsType(value->Check(checker)); in CheckObjectExprProps()
2404 … checker::AssignmentContext(checker->Relation(), value, value->TsType(), propType, value->Start(), in CheckObjectExprProps()
2405 … {{diagnostic::PROP_INCOMPAT, {value->TsType(), propType, pname}}}); in CheckObjectExprProps()
2408 if (objType->HasObjectFlag(ETSObjectFlags::REQUIRED)) { in CheckObjectExprProps()
2409 checker->ValidateObjectLiteralForRequiredType(objType, expr); in CheckObjectExprProps()
2413 checker::Type *ETSAnalyzer::Check(ir::OpaqueTypeNode *expr) const in Check()
2415 return expr->TsType(); in Check()
2418 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::BrokenTypeNode *expr) const in Check()
2420 return GetETSChecker()->GlobalTypeError(); in Check()
2423 checker::Type *ETSAnalyzer::Check(ir::SequenceExpression *expr) const in Check()
2425 ETSChecker *checker = GetETSChecker(); in Check() local
2426 if (expr->TsType() != nullptr) { in Check()
2427 return expr->TsType(); in Check()
2430 for (auto *it : expr->Sequence()) { in Check()
2431 it->Check(checker); in Check()
2433 ES2PANDA_ASSERT(!expr->Sequence().empty()); in Check()
2434 expr->SetTsType(expr->Sequence().back()->TsType()); in Check()
2435 return expr->TsType(); in Check()
2438 checker::Type *ETSAnalyzer::Check(ir::SuperExpression *expr) const in Check()
2440 ETSChecker *checker = GetETSChecker(); in Check() local
2441 if (expr->TsType() != nullptr) { in Check()
2442 return expr->TsType(); in Check()
2445 …expr->SetTsType(checker->CheckThisOrSuperAccess(expr, checker->Context().ContainingClass()->SuperT… in Check()
2446 return expr->TsType(); in Check()
2449 checker::Type *ETSAnalyzer::Check(ir::TemplateLiteral *expr) const in Check()
2451 ETSChecker *checker = GetETSChecker(); in Check() local
2453 for (auto *it : expr->Expressions()) { in Check()
2454 it->Check(checker); in Check()
2457 if (expr->TsType() != nullptr) { in Check()
2458 return expr->TsType(); in Check()
2461 if (expr->Quasis().size() != expr->Expressions().size() + 1U) { in Check()
2462 checker->LogError(diagnostic::TEMPLATE_COUNT_MISMATCH, {}, expr->Start()); in Check()
2463 expr->SetTsType(checker->GlobalTypeError()); in Check()
2464 return expr->TsType(); in Check()
2467 for (auto *it : expr->Quasis()) { in Check()
2468 it->Check(checker); in Check()
2471 expr->SetTsType(checker->CreateETSStringLiteralType(expr->GetMultilineString())); in Check()
2472 return expr->TsType(); in Check()
2475 checker::Type *ETSAnalyzer::Check(ir::ThisExpression *expr) const in Check()
2477 ETSChecker *checker = GetETSChecker(); in Check() local
2478 if (expr->TsType() != nullptr) { in Check()
2479 return expr->TsType(); in Check()
2503 …auto *variable = checker->AsETSChecker()->Scope()->Find(varbinder::VarBinder::MANDATORY_PARAM_THIS… in Check()
2504 if (checker->HasStatus(checker::CheckerStatus::IN_EXTENSION_METHOD)) { in Check()
2506 expr->SetTsType(variable->TsType()); in Check()
2508 …expr->SetTsType(checker->CheckThisOrSuperAccess(expr, checker->Context().ContainingClass(), "this"… in Check()
2511 return expr->TsType(); in Check()
2515 static checker::Type *GetTypeOfStringType(checker::Type *argType, ETSChecker *checker) in GetTypeOfStringType() argument
2517 if (auto unboxed = checker->MaybeUnboxType(argType); unboxed->IsETSPrimitiveType()) { in GetTypeOfStringType()
2518 switch (checker->TypeKind(unboxed)) { in GetTypeOfStringType()
2520 return checker->CreateETSStringLiteralType("boolean"); in GetTypeOfStringType()
2528 return checker->CreateETSStringLiteralType("number"); in GetTypeOfStringType()
2533 if (argType->IsETSUndefinedType()) { in GetTypeOfStringType()
2534 return checker->CreateETSStringLiteralType("undefined"); in GetTypeOfStringType()
2536 … if (argType->IsETSArrayType() || argType->IsETSNullType() || argType->IsETSResizableArrayType()) { in GetTypeOfStringType()
2537 return checker->CreateETSStringLiteralType("object"); in GetTypeOfStringType()
2539 if (argType->IsETSStringType()) { in GetTypeOfStringType()
2540 return checker->CreateETSStringLiteralType("string"); in GetTypeOfStringType()
2542 if (argType->IsETSBigIntType()) { in GetTypeOfStringType()
2543 return checker->CreateETSStringLiteralType("bigint"); in GetTypeOfStringType()
2545 if (argType->IsETSFunctionType()) { in GetTypeOfStringType()
2546 return checker->CreateETSStringLiteralType("function"); in GetTypeOfStringType()
2548 if (argType->IsETSIntEnumType()) { in GetTypeOfStringType()
2549 return checker->CreateETSStringLiteralType("number"); in GetTypeOfStringType()
2551 if (argType->IsETSStringEnumType()) { in GetTypeOfStringType()
2552 return checker->CreateETSStringLiteralType("string"); in GetTypeOfStringType()
2554 return checker->GlobalBuiltinETSStringType(); in GetTypeOfStringType()
2557 static checker::Type *ComputeTypeOfType(ETSChecker *checker, checker::Type *argType) in ComputeTypeOfType() argument
2559 checker::Type *ret = nullptr; in ComputeTypeOfType()
2560 ArenaVector<checker::Type *> types(checker->ProgramAllocator()->Adapter()); in ComputeTypeOfType()
2561 if (argType->IsETSUnionType()) { in ComputeTypeOfType()
2562 for (auto *it : argType->AsETSUnionType()->ConstituentTypes()) { in ComputeTypeOfType()
2563 checker::Type *elType = ComputeTypeOfType(checker, it); in ComputeTypeOfType()
2566 ret = checker->CreateETSUnionType(std::move(types)); in ComputeTypeOfType()
2568 ret = GetTypeOfStringType(argType, checker); in ComputeTypeOfType()
2573 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TypeofExpression *expr) const in Check()
2575 ETSChecker *checker = GetETSChecker(); in Check() local
2576 if (expr->TsType() != nullptr) { in Check()
2577 return expr->TsType(); in Check()
2580 expr->Argument()->Check(checker); in Check()
2581 expr->SetTsType(ComputeTypeOfType(checker, expr->Argument()->TsType())); in Check()
2582 return expr->TsType(); in Check()
2585 checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const in Check()
2587 ETSChecker *checker = GetETSChecker(); in Check() local
2589 if (expr->TsType() != nullptr) { in Check()
2590 return expr->TsType(); in Check()
2593 auto argType = expr->argument_->Check(checker); in Check()
2594 const auto isCondExpr = expr->OperatorType() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK; in Check()
2595 …checker::Type *operandType = checker->ApplyUnaryOperatorPromotion(argType, true, true, isCondExpr); in Check()
2597 …isCondExpr ? checker->MaybeUnboxConditionalInRelation(argType) : checker->MaybeUnboxInRelation(arg… in Check()
2599 …if (argType != nullptr && argType->IsETSBigIntType() && argType->HasTypeFlag(checker::TypeFlag::BI… in Check()
2600 switch (expr->OperatorType()) { in Check()
2602 … checker::Type *type = checker->CreateETSBigIntLiteralType(argType->AsETSBigIntType()->GetValue()); in Check()
2605 type->RemoveTypeFlag(checker::TypeFlag::CONSTANT); in Check()
2606 expr->argument_->SetTsType(type); in Check()
2607 expr->SetTsType(type); in Check()
2608 return expr->TsType(); in Check()
2617 if (argType != nullptr && argType->IsETSBigIntType()) { in Check()
2618 switch (expr->OperatorType()) { in Check()
2622 expr->SetTsType(argType); in Check()
2623 return expr->TsType(); in Check()
2630 if ((argType != nullptr) && argType->IsETSObjectType() && (unboxedOperandType != nullptr) && in Check()
2631 unboxedOperandType->IsETSPrimitiveType()) { in Check()
2632 expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedOperandType)); in Check()
2635 SetTsTypeForUnaryExpression(checker, expr, operandType); in Check()
2637 checker->Context().CheckUnarySmartCastCondition(expr); in Check()
2639 return expr->TsType(); in Check()
2642 checker::Type *ETSAnalyzer::Check(ir::UpdateExpression *expr) const in Check()
2644 ETSChecker *checker = GetETSChecker(); in Check() local
2645 if (expr->TsType() != nullptr) { in Check()
2646 return expr->TsType(); in Check()
2649 checker::Type *operandType = expr->argument_->Check(checker); in Check()
2650 if (operandType->IsTypeError()) { in Check()
2651 return checker->InvalidateType(expr); in Check()
2654 if (expr->Argument()->IsIdentifier()) { in Check()
2655 checker->ValidateUnaryOperatorOperand(expr->Argument()->AsIdentifier()->Variable()); in Check()
2656 } else if (expr->Argument()->IsTSAsExpression()) { in Check()
2657 …if (auto *const asExprVar = expr->Argument()->AsTSAsExpression()->Variable(); asExprVar != nullptr… in Check()
2658 checker->ValidateUnaryOperatorOperand(asExprVar); in Check()
2660 } else if (expr->Argument()->IsTSNonNullExpression()) { in Check()
2661 if (auto *const nonNullExprVar = expr->Argument()->AsTSNonNullExpression()->Variable(); in Check()
2663 checker->ValidateUnaryOperatorOperand(nonNullExprVar); in Check()
2665 } else if (expr->Argument()->IsMemberExpression()) { in Check()
2666 varbinder::LocalVariable *propVar = expr->argument_->AsMemberExpression()->PropVar(); in Check()
2668 checker->ValidateUnaryOperatorOperand(propVar); in Check()
2671 ES2PANDA_ASSERT(checker->IsAnyError()); in Check()
2672 expr->Argument()->SetTsType(checker->GlobalTypeError()); in Check()
2673 return expr->SetTsType(checker->GlobalTypeError()); in Check()
2676 if (operandType->IsETSBigIntType()) { in Check()
2677 return expr->SetTsType(operandType); in Check()
2680 auto unboxedType = checker->MaybeUnboxInRelation(operandType); in Check()
2681 …if (unboxedType == nullptr || !unboxedType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUME… in Check()
2682 checker->LogError(diagnostic::OPERAND_NOT_NUMERIC, {}, expr->Argument()->Start()); in Check()
2683 return expr->SetTsType(checker->GlobalTypeError()); in Check()
2686 if (operandType->IsETSObjectType()) { in Check()
2687 expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedType) | in Check()
2688 checker->GetBoxingFlag(unboxedType)); in Check()
2691 return expr->SetTsType(operandType); in Check()
2695 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::BigIntLiteral *expr) const in Check()
2697 ETSChecker *checker = GetETSChecker(); in Check() local
2698 expr->SetTsType(checker->CreateETSBigIntLiteralType(expr->Str())); in Check()
2699 return expr->TsType(); in Check()
2702 checker::Type *ETSAnalyzer::Check(ir::BooleanLiteral *expr) const in Check()
2704 ETSChecker *checker = GetETSChecker(); in Check() local
2705 if (expr->TsType() == nullptr) { in Check()
2706 expr->SetTsType(checker->CreateETSBooleanType(expr->Value())); in Check()
2708 return expr->TsType(); in Check()
2711 checker::Type *ETSAnalyzer::Check(ir::CharLiteral *expr) const in Check()
2713 ETSChecker *checker = GetETSChecker(); in Check() local
2714 if (expr->TsType() == nullptr) { in Check()
2715 expr->SetTsType(checker->ProgramAllocator()->New<checker::CharType>(expr->Char())); in Check()
2717 return expr->TsType(); in Check()
2720 checker::Type *ETSAnalyzer::Check(ir::NullLiteral *expr) const in Check()
2722 ETSChecker *checker = GetETSChecker(); in Check() local
2723 if (expr->TsType() == nullptr) { in Check()
2724 expr->SetTsType(checker->GlobalETSNullType()); in Check()
2726 return expr->TsType(); in Check()
2729 checker::Type *ETSAnalyzer::Check(ir::NumberLiteral *expr) const in Check()
2731 ETSChecker *checker = GetETSChecker(); in Check() local
2732 if (expr->Number().IsInt()) { in Check()
2733 expr->SetTsType(checker->CreateIntType(expr->Number().GetInt())); in Check()
2734 return expr->TsType(); in Check()
2737 if (expr->Number().IsLong()) { in Check()
2738 expr->SetTsType(checker->CreateLongType(expr->Number().GetLong())); in Check()
2739 return expr->TsType(); in Check()
2742 if (expr->Number().IsFloat()) { in Check()
2743 expr->SetTsType(checker->CreateFloatType(expr->Number().GetFloat())); in Check()
2744 return expr->TsType(); in Check()
2747 expr->SetTsType(checker->CreateDoubleType(expr->Number().GetDouble())); in Check()
2748 return expr->TsType(); in Check()
2751 checker::Type *ETSAnalyzer::Check(ir::StringLiteral *expr) const in Check()
2753 ETSChecker *checker = GetETSChecker(); in Check() local
2754 if (expr->TsType() == nullptr) { in Check()
2755 expr->SetTsType(checker->CreateETSStringLiteralType(expr->Str())); in Check()
2757 return expr->TsType(); in Check()
2760 checker::Type *ETSAnalyzer::Check(ir::ImportDeclaration *st) const in Check()
2762 ETSChecker *checker = GetETSChecker(); in Check() local
2763 checker::Type *type = nullptr; in Check()
2764 for (auto *spec : st->Specifiers()) { in Check()
2765 if (spec->IsImportNamespaceSpecifier()) { in Check()
2766 type = spec->AsImportNamespaceSpecifier()->Check(checker); in Check()
2773 checker::Type *ETSAnalyzer::Check(ir::ImportNamespaceSpecifier *st) const in Check()
2775 ETSChecker *checker = GetETSChecker(); in Check() local
2776 if (st->Local()->Name().Empty()) { in Check()
2780 if (st->Local()->AsIdentifier()->TsType() != nullptr) { in Check()
2781 return st->Local()->TsType(); in Check()
2785 if (st->Parent()->IsETSImportDeclaration()) { in Check()
2786 importDecl = st->Parent()->AsETSImportDeclaration(); in Check()
2787 } else if (st->Parent()->IsETSReExportDeclaration()) { in Check()
2788 importDecl = st->Parent()->AsETSReExportDeclaration()->GetETSImportDeclarations(); in Check()
2793 if (importDecl->IsPureDynamic()) { in Check()
2794 auto *type = checker->GlobalBuiltinDynamicType(importDecl->Language()); in Check()
2795 checker->SetrModuleObjectTsType(st->Local(), type); in Check()
2799 return checker->GetImportSpecifierObjectType(importDecl, st->Local()->AsIdentifier()); in Check()
2803 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::AssertStatement *st) const in Check()
2808 checker::Type *ETSAnalyzer::Check(ir::BlockStatement *st) const in Check()
2810 ETSChecker *checker = GetETSChecker(); in Check() local
2811 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
2815 //---- Don't modify this to iterator, as it may break things during checking in Check()
2816 for (std::size_t idx = 0; idx < st->Statements().size(); ++idx) { in Check()
2817 auto *stmt = st->Statements()[idx]; in Check()
2818 stmt->Check(checker); in Check()
2821 if (auto const tb = st->trailingBlocks_.find(stmt); tb != st->trailingBlocks_.end()) { in Check()
2822 auto *const trailingBlock = tb->second; in Check()
2823 trailingBlock->Check(checker); in Check()
2824 st->Statements().emplace(std::next(st->Statements().begin() + idx), trailingBlock); in Check()
2828 if (UNLIKELY(checker->GetDebugInfoPlugin() != nullptr)) { in Check()
2829 // Compilation in eval-mode might require to create additional statements. in Check()
2831 checker->GetDebugInfoPlugin()->AddPrologueEpilogue(st); in Check()
2834 auto const *const scope = st->Scope(); in Check()
2840 if (scope->IsFunctionScope() && st->Parent()->Parent()->Parent()->IsMethodDefinition()) { in Check()
2842 checker->Context().ClearSmartCasts(); in Check()
2843 } else if (!scope->IsGlobalScope()) { in Check()
2845 for (auto const *const decl : scope->Decls()) { in Check()
2846 … if (decl->IsLetOrConstDecl() && decl->Node() != nullptr && decl->Node()->IsIdentifier()) { in Check()
2847 checker->Context().RemoveSmartCast(decl->Node()->AsIdentifier()->Variable()); in Check()
2853 if (st->IsETSModule() && st->AsETSModule()->Program()->IsPackage() && in Check()
2854 (checker->Context().Status() & checker::CheckerStatus::IN_EXTERNAL) == 0) { in Check()
2855 CheckAllConstPropertyInitialized(checker, st->AsETSModule()); in Check()
2860 checker::Type *ETSAnalyzer::Check(ir::BreakStatement *st) const in Check()
2862 ETSChecker *checker = GetETSChecker(); in Check() local
2864 if (!st->HasTarget()) { in Check()
2866 setJumpTarget.FindJumpTarget(checker->VarBinder()->GetContext(), st); in Check()
2869 if (st->Target() == nullptr) { in Check()
2870 return checker->GlobalTypeError(); in Check()
2873 checker->Context().OnBreakStatement(st); in Check()
2877 checker::Type *ETSAnalyzer::Check(ir::ClassDeclaration *st) const in Check()
2879 ETSChecker *checker = GetETSChecker(); in Check() local
2880 st->Definition()->Check(checker); in Check()
2884 checker::Type *ETSAnalyzer::Check(ir::AnnotationDeclaration *st) const in Check()
2886 if (st->Expr()->TsType() != nullptr) { in Check()
2889 ETSChecker *checker = GetETSChecker(); in Check() local
2890 st->Expr()->Check(checker); in Check()
2892 for (auto *anno : st->Annotations()) { in Check()
2893 checker->CheckStandardAnnotation(anno); in Check()
2894 anno->Check(checker); in Check()
2897 ScopeContext scopeCtx(checker, st->Scope()); in Check()
2898 for (auto *it : st->Properties()) { in Check()
2899 auto *property = it->AsClassProperty(); in Check()
2900 if (checker::Type *propertyType = property->Check(checker); !propertyType->IsTypeError()) { in Check()
2901 checker->CheckAnnotationPropertyType(property); in Check()
2905 auto baseName = st->GetBaseName(); in Check()
2906 if (!baseName->IsErrorPlaceHolder()) { in Check()
2907 if (baseName->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { in Check()
2908 auto *annoDecl = baseName->Variable()->Declaration()->Node()->AsAnnotationDeclaration(); in Check()
2909 if (annoDecl != st && annoDecl->IsDeclare()) { in Check()
2910 checker->CheckAmbientAnnotation(st, annoDecl); in Check()
2918 checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const in Check()
2920 if (st->Expr()->TsType() != nullptr) { in Check()
2923 ETSChecker *checker = GetETSChecker(); in Check() local
2924 st->Expr()->Check(checker); in Check()
2926 if (st->GetBaseName()->Variable() == nullptr || in Check()
2927 !st->GetBaseName()->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { in Check()
2928 …checker->LogError(diagnostic::NOT_AN_ANNOTATION, {st->GetBaseName()->Name()}, st->GetBaseName()->S… in Check()
2932 … auto *annoDecl = st->GetBaseName()->Variable()->Declaration()->Node()->AsAnnotationDeclaration(); in Check()
2933 annoDecl->Check(checker); in Check()
2935 …ArenaUnorderedMap<util::StringView, ir::ClassProperty *> fieldMap {checker->ProgramAllocator()->Ad… in Check()
2936 for (auto *it : annoDecl->Properties()) { in Check()
2937 auto *field = it->AsClassProperty(); in Check()
2939 auto *id = field->Id(); in Check()
2941 fieldMap.insert(std::make_pair(id->Name(), field)); in Check()
2944 if (annoDecl->Properties().size() < st->Properties().size()) { in Check()
2945 checker->LogError(diagnostic::ANNOTATION_ARG_COUNT_MISMATCH, {}, st->Start()); in Check()
2949 … if (st->Properties().size() == 1 && st->Properties().at(0)->AsClassProperty()->Id() != nullptr && in Check()
2950 …st->Properties().at(0)->AsClassProperty()->Id()->Name() == compiler::Signatures::ANNOTATION_KEY_VA… in Check()
2951 checker->CheckSinglePropertyAnnotation(st, annoDecl); in Check()
2954 checker->CheckMultiplePropertiesAnnotation(st, st->GetBaseName()->Name(), fieldMap); in Check()
2957 checker->ProcessRequiredFields(fieldMap, st, checker); in Check()
2961 checker::Type *ETSAnalyzer::Check(ir::ContinueStatement *st) const in Check()
2963 ETSChecker *checker = GetETSChecker(); in Check() local
2965 if (!st->HasTarget()) { in Check()
2967 setJumpTarget.FindJumpTarget(checker->VarBinder()->GetContext(), st); in Check()
2970 if (st->Target() == nullptr) { in Check()
2971 return checker->GlobalTypeError(); in Check()
2974 checker->AddStatus(CheckerStatus::MEET_CONTINUE); in Check()
2978 checker::Type *ETSAnalyzer::Check(ir::DoWhileStatement *st) const in Check()
2980 ETSChecker *checker = GetETSChecker(); in Check() local
2981 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
2984 auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st, std::nullopt); in Check()
2986 checker->CheckTruthinessOfType(st->Test()); in Check()
2987 st->Body()->Check(checker); in Check()
2989 checker->Context().ExitLoop(smartCasts, clearFlag, st); in Check()
2993 checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::EmptyStatement *st) const in Check()
2998 checker::Type *ETSAnalyzer::Check(ir::ExpressionStatement *st) const in Check()
3000 ETSChecker *checker = GetETSChecker(); in Check() local
3001 return st->GetExpression()->Check(checker); in Check()
3004 static bool ValidateAndProcessIteratorType(ETSChecker *checker, Type *elemType, ir::ForOfStatement … in ValidateAndProcessIteratorType() argument
3006 checker::Type *iterType = GetIteratorType(checker, elemType, st->Left()); in ValidateAndProcessIteratorType()
3007 if (iterType->IsTypeError()) { in ValidateAndProcessIteratorType()
3011 const auto ident = st->Left()->IsVariableDeclaration() in ValidateAndProcessIteratorType()
3012 … ? st->Left()->AsVariableDeclaration()->Declarators().front()->Id()->AsIdentifier() in ValidateAndProcessIteratorType()
3013 : st->Left()->AsIdentifier(); in ValidateAndProcessIteratorType()
3014 auto *const relation = checker->Relation(); in ValidateAndProcessIteratorType()
3015 relation->SetFlags(checker::TypeRelationFlag::ASSIGNMENT_CONTEXT); in ValidateAndProcessIteratorType()
3016 relation->SetNode(ident); in ValidateAndProcessIteratorType()
3017 …if (auto ctx = checker::AssignmentContext(checker->Relation(), ident, elemType, iterType, ident->S… in ValidateAndProcessIteratorType()
3020 … checker->LogError(diagnostic::ITERATOR_ELEMENT_TYPE_MISMATCH, {elemType, iterType}, st->Start()); in ValidateAndProcessIteratorType()
3024 relation->SetNode(nullptr); in ValidateAndProcessIteratorType()
3025 relation->SetFlags(checker::TypeRelationFlag::NONE); in ValidateAndProcessIteratorType()
3027 const auto variable = ident->Variable(); in ValidateAndProcessIteratorType()
3029 // Set smart type for variable of 'for-of' statement in ValidateAndProcessIteratorType()
3030 const auto smartType = checker->ResolveSmartType(elemType, variable->TsType()); in ValidateAndProcessIteratorType()
3031 checker->Context().SetSmartCast(variable, smartType); in ValidateAndProcessIteratorType()
3037 checker::Type *ETSAnalyzer::Check(ir::ForOfStatement *const st) const in Check()
3039 ETSChecker *checker = GetETSChecker(); in Check() local
3040 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
3043 auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st, std::nullopt); in Check()
3045 checker::Type *const exprType = st->Right()->Check(checker); in Check()
3047 checker->LogError(diagnostic::FOROF_CANT_INFER_SOURCE, {}, st->Right()->Start()); in Check()
3048 return checker->GlobalTypeError(); in Check()
3051 checker::Type *elemType = checker->GlobalTypeError(); in Check()
3053 if (exprType->IsETSStringType()) { in Check()
3054 elemType = checker->GlobalBuiltinETSStringType(); in Check()
3055 } else if (exprType->IsETSArrayType() || exprType->IsETSResizableArrayType()) { in Check()
3056 elemType = checker->GetElementTypeOfArray(exprType); in Check()
3057 …} else if (exprType->IsETSObjectType() || exprType->IsETSUnionType() || exprType->IsETSTypeParamet… in Check()
3058 elemType = st->CheckIteratorMethod(checker); in Check()
3061 if (elemType == checker->GlobalTypeError()) { in Check()
3062 checker->LogError(diagnostic::FOROF_SOURCE_NONITERABLE, {}, st->Right()->Start()); in Check()
3063 return checker->GlobalTypeError(); in Check()
3066 st->Left()->Check(checker); in Check()
3068 if (!ValidateAndProcessIteratorType(checker, elemType, st)) { in Check()
3069 return checker->GlobalTypeError(); in Check()
3072 st->Body()->Check(checker); in Check()
3074 checker->Context().ExitLoop(smartCasts, clearFlag, st); in Check()
3078 checker::Type *ETSAnalyzer::Check(ir::ForUpdateStatement *st) const in Check()
3080 ETSChecker *checker = GetETSChecker(); in Check() local
3081 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
3084 auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st, std::nullopt); in Check()
3086 if (st->Init() != nullptr) { in Check()
3087 st->Init()->Check(checker); in Check()
3090 if (st->Test() != nullptr) { in Check()
3091 checker->CheckTruthinessOfType(st->Test()); in Check()
3094 if (st->Update() != nullptr) { in Check()
3095 st->Update()->Check(checker); in Check()
3098 st->Body()->Check(checker); in Check()
3100 checker->Context().ExitLoop(smartCasts, clearFlag, st); in Check()
3104 checker::Type *ETSAnalyzer::Check(ir::IfStatement *st) const in Check()
3106 ETSChecker *const checker = GetETSChecker(); in Check() local
3108 SmartCastArray smartCasts = checker->Context().EnterTestExpression(); in Check()
3109 checker->CheckTruthinessOfType(st->Test()); in Check()
3110 SmartCastTypes testedTypes = checker->Context().ExitTestExpression(); in Check()
3113 checker->ApplySmartCast(variable, consequentType); in Check()
3117 checker->Context().EnterPath(); in Check()
3118 st->Consequent()->Check(checker); in Check()
3119 bool const consequentTerminated = checker->Context().ExitPath(); in Check()
3120 SmartCastArray consequentSmartCasts = checker->Context().CloneSmartCasts(); in Check()
3123 checker->Context().RestoreSmartCasts(smartCasts); in Check()
3127 checker->ApplySmartCast(variable, alternateType); in Check()
3131 if (st->Alternate() != nullptr) { in Check()
3132 checker->Context().EnterPath(); in Check()
3133 st->Alternate()->Check(checker); in Check()
3134 bool const alternateTerminated = checker->Context().ExitPath(); in Check()
3138 checker->Context().RestoreSmartCasts(consequentSmartCasts); in Check()
3141 checker->Context().RestoreSmartCasts(smartCasts); in Check()
3145 checker->Context().CombineSmartCasts(consequentSmartCasts); in Check()
3150 checker->Context().CombineSmartCasts(consequentSmartCasts); in Check()
3157 checker::Type *ETSAnalyzer::Check(ir::LabelledStatement *st) const in Check()
3159 ETSChecker *checker = GetETSChecker(); in Check() local
3160 st->body_->Check(checker); in Check()
3165 … ir::TypeNode *returnTypeAnnotation, ETSChecker *checker) in CheckIsValidReturnTypeAnnotation() argument
3168 …if (containingFunc->GetPreferredReturnType() != nullptr || !returnTypeAnnotation->IsTSThisType()) { in CheckIsValidReturnTypeAnnotation()
3173 …bool inValidNormalFuncReturnThisType = st->Argument() == nullptr || !st->Argument()->IsThisExpress… in CheckIsValidReturnTypeAnnotation()
3175 !containingFunc->HasReceiver() || in CheckIsValidReturnTypeAnnotation()
3176 … (containingFunc->HasReceiver() && (st->Argument() == nullptr || !st->Argument()->IsIdentifier() || in CheckIsValidReturnTypeAnnotation()
3177 !st->Argument()->AsIdentifier()->IsReceiver())); in CheckIsValidReturnTypeAnnotation()
3179 checker->LogError(diagnostic::RETURN_THIS_OUTSIDE_METHOD, {}, st->Start()); in CheckIsValidReturnTypeAnnotation()
3186 // CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic
3188 … checker::Type *&funcReturnType, ir::TypeNode *returnTypeAnnotation, in CheckInferredFunctionReturnType()
3189 ETSChecker *checker) const in CheckInferredFunctionReturnType()
3191 if (!CheckIsValidReturnTypeAnnotation(st, containingFunc, returnTypeAnnotation, checker)) { in CheckInferredFunctionReturnType()
3195 if (containingFunc->ReturnTypeAnnotation() != nullptr) { in CheckInferredFunctionReturnType()
3196 if (containingFunc->IsAsyncFunc()) { in CheckInferredFunctionReturnType()
3197 auto *promiseType = containingFunc->ReturnTypeAnnotation()->GetType(checker); in CheckInferredFunctionReturnType()
3199 …if (!promiseType->IsETSObjectType() || promiseType->AsETSObjectType()->TypeArguments().size() != 1… in CheckInferredFunctionReturnType()
3202 …funcReturnType = checker->CreateETSAsyncFuncReturnTypeFromPromiseType(promiseType->AsETSObjectType… in CheckInferredFunctionReturnType()
3204 funcReturnType = containingFunc->ReturnTypeAnnotation()->GetType(checker); in CheckInferredFunctionReturnType()
3207 funcReturnType = containingFunc->GetPreferredReturnType(); in CheckInferredFunctionReturnType()
3211 if (st->argument_ == nullptr) { in CheckInferredFunctionReturnType()
3213 if (!funcReturnType->IsETSVoidType() && funcReturnType != checker->GlobalVoidType() && in CheckInferredFunctionReturnType()
3214 !funcReturnType->IsETSAsyncFuncReturnType()) { in CheckInferredFunctionReturnType()
3215 checker->LogError(diagnostic::RETURN_WITHOUT_VALUE, {}, st->Start()); in CheckInferredFunctionReturnType()
3218 funcReturnType = checker->GlobalVoidType(); in CheckInferredFunctionReturnType()
3220 const auto name = containingFunc->Scope()->InternalName().Mutf8(); in CheckInferredFunctionReturnType()
3221 if (!CheckArgumentVoidType(funcReturnType, checker, name, st)) { in CheckInferredFunctionReturnType()
3225 if (st->argument_->IsObjectExpression()) { in CheckInferredFunctionReturnType()
3226 st->argument_->AsObjectExpression()->SetPreferredType(funcReturnType); in CheckInferredFunctionReturnType()
3228 if (st->argument_->IsMemberExpression()) { in CheckInferredFunctionReturnType()
3229 … checker->SetArrayPreferredTypeForNestedMemberExpressions(st->argument_->AsMemberExpression(), in CheckInferredFunctionReturnType()
3233 if (st->argument_->IsArrayExpression()) { in CheckInferredFunctionReturnType()
3234 st->argument_->AsArrayExpression()->SetPreferredType(funcReturnType); in CheckInferredFunctionReturnType()
3237 if (st->argument_->IsETSNewArrayInstanceExpression()) { in CheckInferredFunctionReturnType()
3238 st->argument_->AsETSNewArrayInstanceExpression()->SetPreferredType(funcReturnType); in CheckInferredFunctionReturnType()
3241 if (st->argument_->IsETSNewMultiDimArrayInstanceExpression()) { in CheckInferredFunctionReturnType()
3242 … st->argument_->AsETSNewMultiDimArrayInstanceExpression()->SetPreferredType(funcReturnType); in CheckInferredFunctionReturnType()
3245 checker::Type *argumentType = st->argument_->Check(checker); in CheckInferredFunctionReturnType()
3246 … return CheckReturnType(checker, funcReturnType, argumentType, st->argument_, containingFunc); in CheckInferredFunctionReturnType()
3251 checker::Type *ETSAnalyzer::GetFunctionReturnType(ir::ReturnStatement *st, ir::ScriptFunction *cont… in GetFunctionReturnType()
3253 ES2PANDA_ASSERT(containingFunc->ReturnTypeAnnotation() != nullptr || in GetFunctionReturnType()
3254 containingFunc->Signature()->ReturnType() != nullptr || in GetFunctionReturnType()
3255 containingFunc->GetPreferredReturnType() != nullptr); in GetFunctionReturnType()
3257 ETSChecker *checker = GetETSChecker(); in GetFunctionReturnType() local
3258 checker::Type *funcReturnType = nullptr; in GetFunctionReturnType()
3260 if (auto *const returnTypeAnnotation = containingFunc->ReturnTypeAnnotation(); in GetFunctionReturnType()
3261 returnTypeAnnotation != nullptr || containingFunc->GetPreferredReturnType() != nullptr) { in GetFunctionReturnType()
3262 …eckInferredFunctionReturnType(st, containingFunc, funcReturnType, returnTypeAnnotation, checker)) { in GetFunctionReturnType()
3263 return checker->GlobalTypeError(); in GetFunctionReturnType()
3267 … if (containingFunc->Signature()->HasSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE)) { in GetFunctionReturnType()
3268 InferReturnType(checker, containingFunc, funcReturnType, in GetFunctionReturnType()
3269 … st->argument_); // This removes the NEED_RETURN_TYPE flag, so only the first return in GetFunctionReturnType()
3273 ProcessReturnStatements(checker, containingFunc, funcReturnType, st, in GetFunctionReturnType()
3274 … st->argument_); // and the remaining return statements will get processed here. in GetFunctionReturnType()
3278 …if ((st->argument_ != nullptr) && st->argument_->IsArrayExpression() && funcReturnType->IsArrayTyp… in GetFunctionReturnType()
3279 checker->ModifyPreferredType(st->argument_->AsArrayExpression(), funcReturnType); in GetFunctionReturnType()
3280 st->argument_->Check(checker); in GetFunctionReturnType()
3286 checker::Type *ETSAnalyzer::Check(ir::ReturnStatement *st) const in Check()
3288 ETSChecker *checker = GetETSChecker(); in Check() local
3291 ES2PANDA_ASSERT(ancestor && ancestor->IsScriptFunction()); in Check()
3294 auto *containingFunc = ancestor->AsScriptFunction(); in Check()
3295 containingFunc->AddFlag(ir::ScriptFunctionFlags::HAS_RETURN); in Check()
3297 if (containingFunc->Signature() == nullptr) { in Check()
3298 ES2PANDA_ASSERT(checker->IsAnyError()); in Check()
3302 checker->AddStatus(CheckerStatus::MEET_RETURN); in Check()
3304 if (containingFunc->IsConstructor()) { in Check()
3305 if (st->argument_ != nullptr) { in Check()
3306 checker->LogError(diagnostic::NON_VOID_RETURN_IN_CONSTRUCTOR, {}, st->Start()); in Check()
3307 return checker->GlobalTypeError(); in Check()
3312 st->returnType_ = GetFunctionReturnType(st, containingFunc); in Check()
3314 if (containingFunc->ReturnTypeAnnotation() == nullptr) { in Check()
3315 containingFunc->AddReturnStatement(st); in Check()
3321 checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const in Check()
3323 ETSChecker *checker = GetETSChecker(); in Check() local
3324 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
3325 checker::SavedTypeRelationFlagsContext savedTypeRelationFlagCtx(checker->Relation(), in Check()
3326 … checker::TypeRelationFlag::NONE); in Check()
3328 auto *comparedExprType = checker->CheckSwitchDiscriminant(st->Discriminant()); in Check()
3329 …auto unboxedDiscType = (st->Discriminant()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UN… in Check()
3330 ? checker->MaybeUnboxInRelation(comparedExprType) in Check()
3333 SmartCastArray smartCasts = checker->Context().CloneSmartCasts(); in Check()
3336 for (auto &it : st->Cases()) { in Check()
3337 checker->Context().EnterPath(); in Check()
3338 …it->CheckAndTestCase(checker, comparedExprType, unboxedDiscType, st->Discriminant(), hasDefaultCas… in Check()
3339 bool const caseTerminated = checker->Context().ExitPath(); in Check()
3341 if (it != st->Cases().back()) { in Check()
3343 checker->Context().CombineSmartCasts(smartCasts); in Check()
3345 checker->Context().RestoreSmartCasts(smartCasts); in Check()
3351 checker->Context().AddBreakSmartCasts(st, checker->Context().CloneSmartCasts()); in Check()
3353 checker->Context().ClearSmartCasts(); in Check()
3359 checker->Context().AddBreakSmartCasts(st, std::move(smartCasts)); in Check()
3362 // Combine smart casts from all [non-terminated] case blocks with 'break' in Check()
3363 checker->Context().CombineBreakSmartCasts(st); in Check()
3365 checker->CheckForSameSwitchCases(st->Cases()); in Check()
3369 checker::Type *ETSAnalyzer::Check(ir::ThrowStatement *st) const in Check()
3371 ETSChecker *checker = GetETSChecker(); in Check() local
3372 const auto *arg = st->argument_; in Check()
3373 checker::Type *argType = st->argument_->Check(checker); in Check()
3376 if (arg->IsIdentifier() && !catchParamStack_.empty()) { in Check()
3377 const varbinder::Variable *sym = arg->AsIdentifier()->Variable(); in Check()
3383 if (!isRethrow && !argType->IsTypeError()) { in Check()
3384 checker->CheckExceptionOrErrorType(argType, st->Start()); in Check()
3387 checker->AddStatus(CheckerStatus::MEET_THROW); in Check()
3391 checker::Type *ETSAnalyzer::Check(ir::TryStatement *st) const in Check()
3393 ETSChecker *checker = GetETSChecker(); in Check() local
3394 std::vector<checker::ETSObjectType *> exceptions {}; in Check()
3397 auto smartCasts = checker->Context().CheckTryBlock(*st->Block()); in Check()
3398 st->Block()->Check(checker); in Check()
3401 for (auto *catchClause : st->CatchClauses()) { in Check()
3403 checker->LogError(diagnostic::CATCH_DEFAULT_NOT_LAST, {}, catchClause->Start()); in Check()
3404 return checker->GlobalTypeError(); in Check()
3407 checker->Context().RestoreSmartCasts(smartCasts); in Check()
3409 if (auto const exceptionType = catchClause->Check(checker); !exceptionType->IsTypeError()) { in Check()
3410 auto *clauseType = exceptionType->AsETSObjectType(); in Check()
3411 checker->CheckExceptionClauseType(exceptions, catchClause, clauseType); in Check()
3415 defaultCatchFound = catchClause->IsDefaultCatchClause(); in Check()
3417 casts.emplace_back(checker->Context().CloneSmartCasts()); in Check()
3420 checker->Context().RestoreSmartCasts(smartCasts); in Check()
3423 checker->Context().CombineSmartCasts(cast); in Check()
3427 if (st->HasFinalizer()) { in Check()
3428 st->FinallyBlock()->Check(checker); in Check()
3434 checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const in Check()
3436 if (st->TsType() != nullptr) { in Check()
3437 return st->TsType(); in Check()
3440 ETSChecker *checker = GetETSChecker(); in Check() local
3441 ES2PANDA_ASSERT(st->Id()->IsIdentifier()); in Check()
3442 auto *const ident = st->Id()->AsIdentifier(); in Check()
3445 if (ident->Parent()->Parent()->AsVariableDeclaration()->Kind() == in Check()
3450 if (ident->IsOptionalDeclaration()) { in Check()
3455 if (ident->Variable() == nullptr) { in Check()
3456 ident->Check(checker); in Check()
3458 …auto *const variableType = checker->CheckVariableDeclaration(ident, ident->TypeAnnotation(), st->I… in Check()
3460 …o define the actual type of Identifier so that smart cast can be used in further checker processing in Check()
3461 // NOTE: T_S and K_o_t_l_i_n don't act in such way, but we can try - why not? :) in Check()
3463 …if (auto *const initType = st->Init() != nullptr ? st->Init()->TsType() : nullptr; initType != nul… in Check()
3464 smartType = checker->ResolveSmartType(initType, variableType); in Check()
3466 // Top-level and captured variables are not processed here! in Check()
3467 if (!checker->Relation()->IsIdenticalTo(variableType, smartType)) { in Check()
3468 ident->SetTsType(smartType); in Check()
3469 checker->Context().SetSmartCast(ident->Variable(), smartType); in Check()
3473 return st->SetTsType(smartType); in Check()
3476 checker::Type *ETSAnalyzer::Check(ir::VariableDeclaration *st) const in Check()
3478 ETSChecker *checker = GetETSChecker(); in Check() local
3480 checker->CheckAnnotations(st->Annotations()); in Check()
3482 for (auto *it : st->Declarators()) { in Check()
3483 it->Check(checker); in Check()
3489 checker::Type *ETSAnalyzer::Check(ir::WhileStatement *st) const in Check()
3491 ETSChecker *checker = GetETSChecker(); in Check() local
3492 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
3495 const auto reassignedVars = checker->Context().GetReassignedVariablesInNode(st->Body()); in Check()
3497 checker->Context().RemoveSmartCast(var); in Check()
3500 SmartCastArray savedSmartCasts = checker->Context().EnterTestExpression(); in Check()
3501 checker->CheckTruthinessOfType(st->Test()); in Check()
3502 SmartCastTypes testedTypes = checker->Context().ExitTestExpression(); in Check()
3505 checker->ApplySmartCast(variable, consequentType); in Check()
3509 auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st, testedTypes); in Check()
3510 st->Body()->Check(checker); in Check()
3511 checker->Context().ExitLoop(savedSmartCasts, clearFlag, st); in Check()
3515 checker::Type *ETSAnalyzer::Check(ir::TSArrayType *node) const in Check()
3517 ETSChecker *checker = GetETSChecker(); in Check() local
3518 checker->CheckAnnotations(node->Annotations()); in Check()
3519 node->elementType_->Check(checker); in Check()
3520 node->SetTsType(node->GetType(checker)); in Check()
3522 const auto *arrayType = node->TsType()->AsETSArrayType(); in Check()
3523 checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); in Check()
3524 return node->TsType(); in Check()
3527 checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const in Check()
3529 ETSChecker *checker = GetETSChecker(); in Check() local
3531 if (expr->TsType() != nullptr) { in Check()
3532 return expr->TsType(); in Check()
3535 checker->CheckAnnotations(expr->TypeAnnotation()->Annotations()); in Check()
3536 auto *const targetType = expr->TypeAnnotation()->AsTypeNode()->GetType(checker); in Check()
3538 if (targetType->IsTypeError()) { in Check()
3539 return checker->InvalidateType(expr); in Check()
3542 ETSChecker::SetPreferredTypeIfPossible(expr->Expr(), targetType); in Check()
3544 auto const sourceType = expr->Expr()->Check(checker); in Check()
3545 if (sourceType->IsTypeError()) { in Check()
3546 return checker->InvalidateType(expr); in Check()
3550 if (targetType->IsETSPrimitiveType() && sourceType->IsETSReferenceType()) { in Check()
3551 auto *const boxedTargetType = checker->MaybeBoxInRelation(targetType); in Check()
3552 if (!checker->Relation()->IsIdenticalTo(sourceType, boxedTargetType)) { in Check()
3553 expr->Expr()->AddAstNodeFlags(ir::AstNodeFlags::CHECKCAST); in Check()
3557 if (sourceType->DefinitelyETSNullish() && !targetType->PossiblyETSNullish()) { in Check()
3558 return checker->TypeError(expr, diagnostic::NULLISH_CAST_TO_NONNULLISH, expr->Start()); in Check()
3561 const checker::CastingContext ctx( in Check()
3562 checker->Relation(), diagnostic::INVALID_CAST, {sourceType, targetType}, in Check()
3563 …checker::CastingContext::ConstructorData {expr->Expr(), sourceType, targetType, expr->Expr()->Star… in Check()
3565 if (sourceType->IsETSDynamicType() && targetType->IsLambdaObject()) { in Check()
3568 checker->BuildLambdaObjectClass(targetType->AsETSObjectType(), in Check()
3569 expr->TypeAnnotation()->AsETSFunctionType()->ReturnType()); in Check()
3571 expr->isUncheckedCast_ = ctx.UncheckedCast(); in Check()
3575 if (!expr->isUncheckedCast_ && targetType->IsETSArrayType()) { in Check()
3576 const auto *const targetArrayType = targetType->AsETSArrayType(); in Check()
3577 checker->CreateBuiltinArraySignature(targetArrayType, targetArrayType->Rank()); in Check()
3580 if (targetType == checker->GetGlobalTypesHolder()->GlobalETSNeverType()) { in Check()
3581 return checker->TypeError(expr, diagnostic::CAST_TO_NEVER, expr->Start()); in Check()
3584 checker->ComputeApparentType(targetType); in Check()
3585 expr->SetTsType(targetType); in Check()
3586 return expr->TsType(); in Check()
3589 checker::Type *ETSAnalyzer::Check(ir::TSEnumDeclaration *st) const in Check()
3595 checker::Type *ETSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const in Check()
3597 if (st->TsType() != nullptr) { in Check()
3598 return st->TsType(); in Check()
3601 ETSChecker *checker = GetETSChecker(); in Check() local
3602 auto *stmtType = checker->BuildBasicInterfaceProperties(st); in Check()
3605 if (stmtType->IsTypeError()) { in Check()
3606 return st->SetTsType(stmtType); in Check()
3609 auto *interfaceType = stmtType->AsETSObjectType(); in Check()
3610 checker->CheckInterfaceAnnotations(st); in Check()
3612 interfaceType->SetSuperType(checker->GlobalETSObjectType()); in Check()
3613 checker->CheckInvokeMethodsLegitimacy(interfaceType); in Check()
3615 st->SetTsType(interfaceType); in Check()
3617 checker::ScopeContext scopeCtx(checker, st->Scope()); in Check()
3618 …auto savedContext = checker::SavedCheckerContext(checker, checker::CheckerStatus::IN_INTERFACE, in… in Check()
3620 for (auto *it : st->Body()->Body()) { in Check()
3621 it->Check(checker); in Check()
3623 return st->TsType(); in Check()
3626 checker::Type *ETSAnalyzer::Check(ir::TSNonNullExpression *expr) const in Check()
3628 if (expr->TsType() != nullptr) { in Check()
3629 return expr->TsType(); in Check()
3631 ETSChecker *checker = GetETSChecker(); in Check() local
3632 auto exprType = expr->expr_->Check(checker); in Check()
3635 if (exprType->DefinitelyETSNullish()) { in Check()
3636 checker->LogDiagnostic(diagnostic::NULLISH_OPERAND, expr->Expr()->Start()); in Check()
3638 if (expr->expr_->IsIdentifier()) { in Check()
3639 ES2PANDA_ASSERT(expr->expr_->AsIdentifier()->Variable() != nullptr); in Check()
3640 auto originalType = expr->expr_->AsIdentifier()->Variable()->TsType(); in Check()
3642 expr->SetTsType(checker->GetNonNullishType(originalType)); in Check()
3647 if (expr->TsType() == nullptr) { in Check()
3648 expr->SetTsType(checker->GetNonNullishType(exprType)); in Check()
3650 expr->SetOriginalType(expr->TsType()); in Check()
3651 return expr->TsType(); in Check()
3654 checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const in Check()
3656 ETSChecker *checker = GetETSChecker(); in Check() local
3657 checker::Type *baseType = expr->Left()->Check(checker); in Check()
3658 if (baseType->IsETSObjectType()) { in Check()
3659 // clang-format off in Check()
3660 auto searchName = expr->Right()->Name(); in Check()
3661 // clang-format on in Check()
3662 // NOTE (oeotvos) This should be done differently in the follow-up patch. in Check()
3664 searchName = expr->Right()->Name(); in Check()
3667 … baseType->AsETSObjectType()->GetProperty(searchName, checker::PropertySearchFlags::SEARCH_DECL); in Check()
3670 … checker->LogError(diagnostic::NONEXISTENT_TYPE, {expr->Right()->Name()}, expr->Right()->Start()); in Check()
3671 return checker->GlobalTypeError(); in Check()
3674 checker->ValidateNamespaceProperty(prop, baseType->AsETSObjectType(), expr->Right()); in Check()
3675 expr->Right()->SetVariable(prop); in Check()
3676 return checker->GetTypeOfVariable(prop); in Check()
3679 … checker->LogError(diagnostic::NONEXISTENT_TYPE, {expr->Right()->Name()}, expr->Right()->Start()); in Check()
3680 return checker->GlobalTypeError(); in Check()
3683 checker::Type *ETSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const in Check()
3685 ETSChecker *checker = GetETSChecker(); in Check() local
3686 …auto checkerContext = SavedCheckerContext(checker, CheckerStatus::NO_OPTS, checker->Context().Cont… in Check()
3688 checker->CheckAnnotations(st->Annotations()); in Check()
3690 if (st->TypeParams() == nullptr) { in Check()
3691 const checker::SavedTypeRelationFlagsContext savedFlagsCtx( in Check()
3692 checker->Relation(), checker::TypeRelationFlag::NO_THROW_GENERIC_TYPEALIAS); in Check()
3694 if (st->TypeAnnotation()->TsType() == nullptr) { in Check()
3695 st->TypeAnnotation()->Check(checker); in Check()
3701 if (st->TypeParameterTypes().empty()) { in Check()
3702 auto [typeParamTypes, ok] = checker->CreateUnconstrainedTypeParameters(st->TypeParams()); in Check()
3703 st->SetTypeParameterTypes(std::move(typeParamTypes)); in Check()
3705 checker->AssignTypeParameterConstraints(st->TypeParams()); in Check()
3709 const checker::SavedTypeRelationFlagsContext savedFlagsCtx(checker->Relation(), in Check()
3710 … checker::TypeRelationFlag::NO_THROW_GENERIC_TYPEALIAS); in Check()
3712 if (st->TypeAnnotation()->TsType() == nullptr) { in Check()
3713 st->TypeAnnotation()->Check(checker); in Check()
3719 checker::Type *ETSAnalyzer::ReturnTypeForStatement([[maybe_unused]] const ir::Statement *const st) … in ReturnTypeForStatement()
3721 ES2PANDA_ASSERT(st->IsStatement()); in ReturnTypeForStatement()
3725 } // namespace ark::es2panda::checker