Lines Matching +full:checker +full:-
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
7 * http://www.apache.org/licenses/LICENSE-2.0
17 #include "checker/types/ets/etsAsyncFuncReturnType.h"
19 namespace ark::es2panda::checker { namespace
20 void CheckExtensionIsShadowedInCurrentClassOrInterface(checker::ETSChecker *checker, checker::ETSOb… in CheckExtensionIsShadowedInCurrentClassOrInterface() argument
21 … ir::ScriptFunction *extensionFunc, checker::Signature *signature) in CheckExtensionIsShadowedInCurrentClassOrInterface()
23 const auto methodName = extensionFunc->Id()->Name(); in CheckExtensionIsShadowedInCurrentClassOrInterface()
25 …auto *const variable = objType->GetOwnProperty<checker::PropertyType::INSTANCE_METHOD>(methodName); in CheckExtensionIsShadowedInCurrentClassOrInterface()
30 const auto *const funcType = variable->TsType()->AsETSFunctionType(); in CheckExtensionIsShadowedInCurrentClassOrInterface()
31 for (auto *funcSignature : funcType->CallSignatures()) { in CheckExtensionIsShadowedInCurrentClassOrInterface()
32 signature->SetReturnType(funcSignature->ReturnType()); in CheckExtensionIsShadowedInCurrentClassOrInterface()
33 if (!checker->Relation()->IsCompatibleTo(signature, funcSignature)) { in CheckExtensionIsShadowedInCurrentClassOrInterface()
37 … checker->ReportWarning({"extension is shadowed by a instance member function '", funcType->Name(), in CheckExtensionIsShadowedInCurrentClassOrInterface()
38 funcSignature, "' in class ", objType->Name()}, in CheckExtensionIsShadowedInCurrentClassOrInterface()
39 extensionFunc->Body()->Start()); in CheckExtensionIsShadowedInCurrentClassOrInterface()
44 void CheckExtensionIsShadowedByMethod(checker::ETSChecker *checker, checker::ETSObjectType *objType, in CheckExtensionIsShadowedByMethod() argument
45 … ir::ScriptFunction *extensionFunc, checker::Signature *signature) in CheckExtensionIsShadowedByMethod()
51 CheckExtensionIsShadowedInCurrentClassOrInterface(checker, objType, extensionFunc, signature); in CheckExtensionIsShadowedByMethod()
53 for (auto *interface : objType->Interfaces()) { in CheckExtensionIsShadowedByMethod()
54 CheckExtensionIsShadowedByMethod(checker, interface, extensionFunc, signature); in CheckExtensionIsShadowedByMethod()
57 CheckExtensionIsShadowedByMethod(checker, objType->SuperType(), extensionFunc, signature); in CheckExtensionIsShadowedByMethod()
60 static void ReplaceThisInExtensionMethod(checker::ETSChecker *checker, ir::ScriptFunction *extensio… in ReplaceThisInExtensionMethod() argument
62 ASSERT(!extensionFunc->Params().empty()); in ReplaceThisInExtensionMethod()
63 ASSERT(extensionFunc->Params()[0]->AsETSParameterExpression()->Ident()->Name() == in ReplaceThisInExtensionMethod()
65 auto thisVariable = extensionFunc->Params()[0]->Variable(); in ReplaceThisInExtensionMethod()
66 extensionFunc->Body()->TransformChildrenRecursively( in ReplaceThisInExtensionMethod()
68 if (ast->IsThisExpression()) { in ReplaceThisInExtensionMethod()
69 auto *thisParam = checker->Allocator()->New<ir::Identifier>( in ReplaceThisInExtensionMethod()
70 varbinder::TypedBinder::MANDATORY_PARAM_THIS, checker->Allocator()); in ReplaceThisInExtensionMethod()
71 thisParam->SetParent(ast->Parent()); in ReplaceThisInExtensionMethod()
72 thisParam->SetVariable(thisVariable); in ReplaceThisInExtensionMethod()
77 "replace-this-in-extension-method"); in ReplaceThisInExtensionMethod()
80 void CheckExtensionMethod(checker::ETSChecker *checker, ir::ScriptFunction *extensionFunc, ir::Meth… in CheckExtensionMethod() argument
82 auto *const thisType = extensionFunc->Signature()->Params()[0]->TsType(); in CheckExtensionMethod()
85 if (thisType->IsETSArrayType() || in CheckExtensionMethod()
86 (thisType->IsETSObjectType() && in CheckExtensionMethod()
87 (thisType->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::CLASS) || in CheckExtensionMethod()
88 thisType->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::INTERFACE)))) { in CheckExtensionMethod()
90 …if (!thisType->IsETSArrayType() && thisType->Variable()->Declaration()->Node()->IsClassDefinition(… in CheckExtensionMethod()
91 … !thisType->Variable()->Declaration()->Node()->AsClassDefinition()->IsClassDefinitionChecked()) { in CheckExtensionMethod()
92 thisType->Variable()->Declaration()->Node()->Check(checker); in CheckExtensionMethod()
96 ReplaceThisInExtensionMethod(checker, extensionFunc); in CheckExtensionMethod()
98 …checker::SignatureInfo *originalExtensionSigInfo = checker->Allocator()->New<checker::SignatureInf… in CheckExtensionMethod()
99 extensionFunc->Signature()->GetSignatureInfo(), checker->Allocator()); in CheckExtensionMethod()
100 originalExtensionSigInfo->minArgCount -= 1; in CheckExtensionMethod()
101 originalExtensionSigInfo->params.erase(originalExtensionSigInfo->params.begin()); in CheckExtensionMethod()
102 checker::Signature *originalExtensionSigature = in CheckExtensionMethod()
103 …checker->CreateSignature(originalExtensionSigInfo, extensionFunc->Signature()->ReturnType(), exten… in CheckExtensionMethod()
107 if (thisType->IsETSObjectType()) { in CheckExtensionMethod()
108 CheckExtensionIsShadowedByMethod(checker, thisType->AsETSObjectType(), extensionFunc, in CheckExtensionMethod()
112 …checker->LogTypeError("Extension function can only defined for class, interface or array.", node->… in CheckExtensionMethod()
116 void DoBodyTypeChecking(ETSChecker *checker, ir::MethodDefinition *node, ir::ScriptFunction *script… in DoBodyTypeChecking() argument
118 if (scriptFunc->HasBody() && (node->IsNative() || node->IsAbstract() || node->IsDeclare())) { in DoBodyTypeChecking()
119 …checker->LogTypeError("Native, Abstract and Declare methods cannot have body.", scriptFunc->Body()… in DoBodyTypeChecking()
122 if (!scriptFunc->IsAsyncFunc() && scriptFunc->HasBody() && in DoBodyTypeChecking()
123 (!scriptFunc->IsExternal() || scriptFunc->IsExternalOverload())) { in DoBodyTypeChecking()
124 checker::ScopeContext scopeCtx(checker, scriptFunc->Scope()); in DoBodyTypeChecking()
125 checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), in DoBodyTypeChecking()
126 checker->Context().ContainingClass()); in DoBodyTypeChecking()
127 checker->Context().SetContainingSignature(checker->GetSignatureFromMethodDefinition(node)); in DoBodyTypeChecking()
129 if (node->IsStatic() && !node->IsConstructor() && in DoBodyTypeChecking()
130 !checker->Context().ContainingClass()->HasObjectFlag(checker::ETSObjectFlags::GLOBAL)) { in DoBodyTypeChecking()
131 checker->AddStatus(checker::CheckerStatus::IN_STATIC_CONTEXT); in DoBodyTypeChecking()
134 if (node->IsConstructor()) { in DoBodyTypeChecking()
135 checker->AddStatus(checker::CheckerStatus::IN_CONSTRUCTOR); in DoBodyTypeChecking()
138 if (node->IsExtensionMethod()) { in DoBodyTypeChecking()
139 CheckExtensionMethod(checker, scriptFunc, node); in DoBodyTypeChecking()
142 scriptFunc->Body()->Check(checker); in DoBodyTypeChecking()
144 if (scriptFunc->ReturnTypeAnnotation() == nullptr) { in DoBodyTypeChecking()
145 if (scriptFunc->IsAsyncImplFunc()) { in DoBodyTypeChecking()
146 ComposeAsyncImplFuncReturnType(checker, scriptFunc); in DoBodyTypeChecking()
149 for (auto &returnStatement : scriptFunc->ReturnStatements()) { in DoBodyTypeChecking()
150 returnStatement->SetReturnType(checker, scriptFunc->Signature()->ReturnType()); in DoBodyTypeChecking()
154 checker->Context().SetContainingSignature(nullptr); in DoBodyTypeChecking()
158 void ComposeAsyncImplFuncReturnType(ETSChecker *checker, ir::ScriptFunction *scriptFunc) in ComposeAsyncImplFuncReturnType() argument
160 auto const promiseType = checker->CreatePromiseOf(scriptFunc->Signature()->ReturnType()); in ComposeAsyncImplFuncReturnType()
163 …checker->AllocNode<ir::Identifier>(compiler::Signatures::BUILTIN_OBJECT_CLASS, checker->Allocator(… in ComposeAsyncImplFuncReturnType()
164 checker->VarBinder()->AsETSBinder()->LookupTypeReference(objectId, false); in ComposeAsyncImplFuncReturnType()
165 auto *returnType = checker->AllocNode<ir::ETSTypeReference>( in ComposeAsyncImplFuncReturnType()
166 checker->AllocNode<ir::ETSTypeReferencePart>(objectId, nullptr, nullptr)); in ComposeAsyncImplFuncReturnType()
167 objectId->SetParent(returnType->Part()); in ComposeAsyncImplFuncReturnType()
168 returnType->Part()->SetParent(returnType); in ComposeAsyncImplFuncReturnType()
169 returnType->SetTsType( in ComposeAsyncImplFuncReturnType()
170 …checker->Allocator()->New<ETSAsyncFuncReturnType>(checker->Allocator(), checker->Relation(), promi… in ComposeAsyncImplFuncReturnType()
171 returnType->Check(checker); in ComposeAsyncImplFuncReturnType()
172 scriptFunc->Signature()->SetReturnType(returnType->TsType()); in ComposeAsyncImplFuncReturnType()
175 void ComposeAsyncImplMethod(ETSChecker *checker, ir::MethodDefinition *node) in ComposeAsyncImplMethod() argument
177 …auto *classDef = checker->FindAncestorGivenByType(node, ir::AstNodeType::CLASS_DEFINITION)->AsClas… in ComposeAsyncImplMethod()
178 auto *scriptFunc = node->Function(); in ComposeAsyncImplMethod()
179 ir::MethodDefinition *implMethod = checker->CreateAsyncProxy(node, classDef); in ComposeAsyncImplMethod()
181 implMethod->Check(checker); in ComposeAsyncImplMethod()
182 node->SetAsyncPairMethod(implMethod); in ComposeAsyncImplMethod()
184 if (scriptFunc->Signature()->HasSignatureFlag(SignatureFlags::NEED_RETURN_TYPE)) { in ComposeAsyncImplMethod()
185 node->Function()->Signature()->SetReturnType( in ComposeAsyncImplMethod()
186 … implMethod->Function()->Signature()->ReturnType()->AsETSAsyncFuncReturnType()->PromiseType()); in ComposeAsyncImplMethod()
187 scriptFunc->Signature()->RemoveSignatureFlag(SignatureFlags::NEED_RETURN_TYPE); in ComposeAsyncImplMethod()
190 if (node->Function()->IsOverload()) { in ComposeAsyncImplMethod()
191 auto *baseOverloadImplMethod = node->BaseOverloadMethod()->AsyncPairMethod(); in ComposeAsyncImplMethod()
192 … implMethod->Function()->Id()->SetVariable(baseOverloadImplMethod->Function()->Id()->Variable()); in ComposeAsyncImplMethod()
193 baseOverloadImplMethod->AddOverload(implMethod); in ComposeAsyncImplMethod()
195 classDef->Body().push_back(implMethod); in ComposeAsyncImplMethod()
199 void CheckPredefinedMethodReturnType(ETSChecker *checker, ir::ScriptFunction *scriptFunc) in CheckPredefinedMethodReturnType() argument
201 auto const &position = scriptFunc->Start(); in CheckPredefinedMethodReturnType()
203 …if (scriptFunc->IsSetter() && (scriptFunc->Signature()->ReturnType() != checker->GlobalVoidType())… in CheckPredefinedMethodReturnType()
204 checker->LogTypeError("Setter must have void return type", position); in CheckPredefinedMethodReturnType()
207 …if (scriptFunc->IsGetter() && (scriptFunc->Signature()->ReturnType() == checker->GlobalVoidType())… in CheckPredefinedMethodReturnType()
208 checker->LogTypeError("Getter must return a value", position); in CheckPredefinedMethodReturnType()
211 auto const name = scriptFunc->Id()->Name(); in CheckPredefinedMethodReturnType()
215 if (scriptFunc->Signature()->ReturnType() == checker->GlobalVoidType()) { in CheckPredefinedMethodReturnType()
216 checker->LogTypeError(methodName + "' shouldn't have void return type.", position); in CheckPredefinedMethodReturnType()
219 if (scriptFunc->Signature()->ReturnType() != checker->GlobalVoidType()) { in CheckPredefinedMethodReturnType()
220 checker->LogTypeError(methodName + "' should have void return type.", position); in CheckPredefinedMethodReturnType()
223 CheckIteratorMethodReturnType(checker, scriptFunc, position, methodName); in CheckPredefinedMethodReturnType()
230 auto &&iteratorInterfaceImpl) -> bool { in HasIteratorInterface()
231 if (checkType->Name().Is(ir::ITERATOR_INTERFACE_NAME)) { in HasIteratorInterface()
234 for (const auto *const interface : checkType->Interfaces()) { in HasIteratorInterface()
245 void CheckIteratorMethodReturnType(ETSChecker *checker, ir::ScriptFunction *scriptFunc, in CheckIteratorMethodReturnType() argument
248 const auto *returnType = scriptFunc->Signature()->ReturnType(); in CheckIteratorMethodReturnType()
251 checker->LogTypeError(methodName + "' doesn't have return type.", position); in CheckIteratorMethodReturnType()
254 if (returnType->IsETSTypeParameter()) { in CheckIteratorMethodReturnType()
255 … returnType = checker->GetApparentType(returnType->AsETSTypeParameter()->GetConstraintType()); in CheckIteratorMethodReturnType()
258 if (returnType->IsETSObjectType() && HasIteratorInterface(returnType->AsETSObjectType())) { in CheckIteratorMethodReturnType()
262 while (returnType->IsETSObjectType() && returnType->AsETSObjectType()->SuperType() != nullptr) { in CheckIteratorMethodReturnType()
263 returnType = returnType->AsETSObjectType()->SuperType(); in CheckIteratorMethodReturnType()
264 if (returnType->IsETSObjectType() && HasIteratorInterface(returnType->AsETSObjectType())) { in CheckIteratorMethodReturnType()
269 checker->LogTypeError( in CheckIteratorMethodReturnType()
270 …{"The return type of '", scriptFunc->Id()->Name(), "' must be a type that implements Iterator inte… in CheckIteratorMethodReturnType()
274 checker::Type *InitAnonymousLambdaCallee(checker::ETSChecker *checker, ir::Expression *callee, in InitAnonymousLambdaCallee() argument
275 checker::Type *calleeType) in InitAnonymousLambdaCallee()
277 auto *const arrowFunc = callee->AsArrowFunctionExpression()->Function(); in InitAnonymousLambdaCallee()
279 ArenaVector<ir::Expression *> params {checker->Allocator()->Adapter()}; in InitAnonymousLambdaCallee()
280 checker->CopyParams(arrowFunc->Params(), params); in InitAnonymousLambdaCallee()
281 checker::Type *funcReturnType = nullptr; in InitAnonymousLambdaCallee()
283 auto *typeAnnotation = arrowFunc->ReturnTypeAnnotation(); in InitAnonymousLambdaCallee()
285 typeAnnotation = typeAnnotation->Clone(checker->Allocator(), nullptr); in InitAnonymousLambdaCallee()
286 typeAnnotation->SetTsType(arrowFunc->ReturnTypeAnnotation()->TsType()); in InitAnonymousLambdaCallee()
287 } else if (arrowFunc->Signature()->ReturnType() != nullptr) { in InitAnonymousLambdaCallee()
288 auto newTypeAnnotation = callee->AsArrowFunctionExpression()->CreateTypeAnnotation(checker); in InitAnonymousLambdaCallee()
289 typeAnnotation = arrowFunc->ReturnTypeAnnotation(); in InitAnonymousLambdaCallee()
290 funcReturnType = newTypeAnnotation->GetType(checker); in InitAnonymousLambdaCallee()
294 …auto *funcType = checker->AllocNode<ir::ETSFunctionType>(std::move(signature), ir::ScriptFunctionF… in InitAnonymousLambdaCallee()
296 funcType->SetScope(arrowFunc->Scope()->AsFunctionScope()->ParamScope()); in InitAnonymousLambdaCallee()
297 auto *const funcIface = typeAnnotation != nullptr ? funcType->Check(checker) : funcReturnType; in InitAnonymousLambdaCallee()
298 checker->Relation()->SetNode(callee); in InitAnonymousLambdaCallee()
299 checker->Relation()->IsAssignableTo(calleeType, funcIface); in InitAnonymousLambdaCallee()
303 checker::Signature *ResolveCallExtensionFunction(checker::ETSFunctionType *functionType, checker::E… in ResolveCallExtensionFunction() argument
306 auto *memberExpr = expr->Callee()->AsMemberExpression(); in ResolveCallExtensionFunction()
307 expr->Arguments().insert(expr->Arguments().begin(), memberExpr->Object()); in ResolveCallExtensionFunction()
309 …checker->ResolveCallExpressionAndTrailingLambda(functionType->CallSignatures(), expr, expr->Start(… in ResolveCallExtensionFunction()
313 if (!signature->Function()->IsExtensionMethod()) { in ResolveCallExtensionFunction()
314 checker->LogTypeError({"Property '", memberExpr->Property()->AsIdentifier()->Name(), in ResolveCallExtensionFunction()
315 "' does not exist on type '", memberExpr->ObjType()->Name(), "'"}, in ResolveCallExtensionFunction()
316 memberExpr->Property()->Start()); in ResolveCallExtensionFunction()
318 expr->SetSignature(signature); in ResolveCallExtensionFunction()
319 expr->SetCallee(memberExpr->Property()); in ResolveCallExtensionFunction()
320 memberExpr->Property()->AsIdentifier()->SetParent(expr); in ResolveCallExtensionFunction()
321 expr->Arguments()[0]->SetParent(expr); in ResolveCallExtensionFunction()
322 checker->HandleUpdatedCallExpressionNode(expr); in ResolveCallExtensionFunction()
324 expr->Callee()->Check(checker); in ResolveCallExtensionFunction()
328 checker::Signature *ResolveCallForETSExtensionFuncHelperType(checker::ETSExtensionFuncHelperType *t… in ResolveCallForETSExtensionFuncHelperType()
329 … checker::ETSChecker *checker, ir::CallExpression *expr) in ResolveCallForETSExtensionFuncHelperType() argument
331 checker::Signature *signature = checker->ResolveCallExpressionAndTrailingLambda( in ResolveCallForETSExtensionFuncHelperType()
332 …type->ClassMethodType()->CallSignatures(), expr, expr->Start(), checker::TypeRelationFlag::NO_THRO… in ResolveCallForETSExtensionFuncHelperType()
335 if (expr->Callee()->IsMemberExpression()) { in ResolveCallForETSExtensionFuncHelperType()
336 auto memberExpr = expr->Callee()->AsMemberExpression(); in ResolveCallForETSExtensionFuncHelperType()
337 auto var = type->ClassMethodType()->Variable(); in ResolveCallForETSExtensionFuncHelperType()
338 memberExpr->Property()->AsIdentifier()->SetVariable(var); in ResolveCallForETSExtensionFuncHelperType()
344 return ResolveCallExtensionFunction(type->ExtensionMethodType(), checker, expr); in ResolveCallForETSExtensionFuncHelperType()
347 ArenaVector<checker::Signature *> GetUnionTypeSignatures(ETSChecker *checker, checker::ETSUnionType… in GetUnionTypeSignatures() argument
349 ArenaVector<checker::Signature *> callSignatures(checker->Allocator()->Adapter()); in GetUnionTypeSignatures()
351 for (auto *constituentType : etsUnionType->ConstituentTypes()) { in GetUnionTypeSignatures()
352 if (constituentType->IsETSObjectType() && in GetUnionTypeSignatures()
353 …constituentType->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::FUNCTIONAL_INTERFACE)) { in GetUnionTypeSignatures()
354 ArenaVector<checker::Signature *> tmpCallSignatures(checker->Allocator()->Adapter()); in GetUnionTypeSignatures()
356 constituentType->AsETSObjectType() in GetUnionTypeSignatures()
357 … ->GetOwnProperty<checker::PropertyType::INSTANCE_METHOD>(FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME) in GetUnionTypeSignatures()
358 ->TsType() in GetUnionTypeSignatures()
359 ->AsETSFunctionType() in GetUnionTypeSignatures()
360 ->CallSignatures(); in GetUnionTypeSignatures()
363 if (constituentType->IsETSFunctionType()) { in GetUnionTypeSignatures()
364 ArenaVector<checker::Signature *> tmpCallSignatures(checker->Allocator()->Adapter()); in GetUnionTypeSignatures()
365 tmpCallSignatures = constituentType->AsETSFunctionType()->CallSignatures(); in GetUnionTypeSignatures()
368 if (constituentType->IsETSUnionType()) { in GetUnionTypeSignatures()
369 ArenaVector<checker::Signature *> tmpCallSignatures(checker->Allocator()->Adapter()); in GetUnionTypeSignatures()
370 tmpCallSignatures = GetUnionTypeSignatures(checker, constituentType->AsETSUnionType()); in GetUnionTypeSignatures()
378 ArenaVector<checker::Signature *> &ChooseSignatures(ETSChecker *checker, checker::Type *calleeType, in ChooseSignatures() argument
382 static ArenaVector<checker::Signature *> unionSignatures(checker->Allocator()->Adapter()); in ChooseSignatures()
385 return calleeType->AsETSObjectType()->ConstructSignatures(); in ChooseSignatures()
388 return calleeType->AsETSObjectType() in ChooseSignatures()
389 … ->GetOwnProperty<checker::PropertyType::INSTANCE_METHOD>(FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME) in ChooseSignatures()
390 ->TsType() in ChooseSignatures()
391 ->AsETSFunctionType() in ChooseSignatures()
392 ->CallSignatures(); in ChooseSignatures()
395 unionSignatures = GetUnionTypeSignatures(checker, calleeType->AsETSUnionType()); in ChooseSignatures()
398 return calleeType->AsETSFunctionType()->CallSignatures(); in ChooseSignatures()
401 checker::ETSObjectType *ChooseCalleeObj(ETSChecker *checker, ir::CallExpression *expr, checker::Typ… in ChooseCalleeObj() argument
405 return calleeType->AsETSObjectType(); in ChooseCalleeObj()
407 if (expr->Callee()->IsIdentifier()) { in ChooseCalleeObj()
408 return checker->Context().ContainingClass(); in ChooseCalleeObj()
410 ASSERT(expr->Callee()->IsMemberExpression()); in ChooseCalleeObj()
411 return expr->Callee()->AsMemberExpression()->ObjType(); in ChooseCalleeObj()
414 void ProcessExclamationMark(ETSChecker *checker, ir::UnaryExpression *expr, checker::Type *operandT… in ProcessExclamationMark() argument
416 if (checker->IsNullLikeOrVoidExpression(expr->Argument())) { in ProcessExclamationMark()
417 auto tsType = checker->CreateETSBooleanType(true); in ProcessExclamationMark()
418 tsType->AddTypeFlag(checker::TypeFlag::CONSTANT); in ProcessExclamationMark()
419 expr->SetTsType(tsType); in ProcessExclamationMark()
423 if (operandType == nullptr || !operandType->IsConditionalExprType()) { in ProcessExclamationMark()
424 checker->LogTypeError("Bad operand type, the type of the operand must be boolean type.", in ProcessExclamationMark()
425 expr->Argument()->Start()); in ProcessExclamationMark()
426 expr->SetTsType(checker->GlobalTypeError()); in ProcessExclamationMark()
430 auto exprRes = operandType->ResolveConditionExpr(); in ProcessExclamationMark()
432 auto tsType = checker->CreateETSBooleanType(!std::get<1>(exprRes)); in ProcessExclamationMark()
433 tsType->AddTypeFlag(checker::TypeFlag::CONSTANT); in ProcessExclamationMark()
434 expr->SetTsType(tsType); in ProcessExclamationMark()
438 expr->SetTsType(checker->GlobalETSBooleanType()); in ProcessExclamationMark()
441 void SetTsTypeForUnaryExpression(ETSChecker *checker, ir::UnaryExpression *expr, checker::Type *ope… in SetTsTypeForUnaryExpression() argument
443 switch (expr->OperatorType()) { in SetTsTypeForUnaryExpression()
446 …if (operandType == nullptr || !operandType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUME… in SetTsTypeForUnaryExpression()
447 … checker->LogTypeError("Bad operand type, the type of the operand must be numeric type.", in SetTsTypeForUnaryExpression()
448 expr->Argument()->Start()); in SetTsTypeForUnaryExpression()
449 expr->SetTsType(checker->GlobalTypeError()); in SetTsTypeForUnaryExpression()
453 if (operandType->HasTypeFlag(checker::TypeFlag::CONSTANT) && in SetTsTypeForUnaryExpression()
454 expr->OperatorType() == lexer::TokenType::PUNCTUATOR_MINUS) { in SetTsTypeForUnaryExpression()
455 expr->SetTsType(checker->NegateNumericType(operandType, expr)); in SetTsTypeForUnaryExpression()
459 expr->SetTsType(operandType); in SetTsTypeForUnaryExpression()
463 …if (operandType == nullptr || !operandType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUME… in SetTsTypeForUnaryExpression()
464 … checker->LogTypeError("Bad operand type, the type of the operand must be numeric type.", in SetTsTypeForUnaryExpression()
465 expr->Argument()->Start()); in SetTsTypeForUnaryExpression()
466 expr->SetTsType(checker->GlobalTypeError()); in SetTsTypeForUnaryExpression()
470 if (operandType->HasTypeFlag(checker::TypeFlag::CONSTANT)) { in SetTsTypeForUnaryExpression()
471 expr->SetTsType(checker->BitwiseNegateNumericType(operandType, expr)); in SetTsTypeForUnaryExpression()
475 expr->SetTsType(checker->SelectGlobalIntegerTypeForNumeric(operandType)); in SetTsTypeForUnaryExpression()
479 ProcessExclamationMark(checker, expr, operandType); in SetTsTypeForUnaryExpression()
483 expr->SetTsType(expr->Argument()->TsType()); in SetTsTypeForUnaryExpression()
493 checker::ETSObjectType *CreateSyntheticType(ETSChecker *checker, util::StringView const &syntheticN… in CreateSyntheticType() argument
494 … checker::ETSObjectType *lastObjectType, ir::Identifier *id) in CreateSyntheticType()
496 auto *syntheticObjType = checker->Allocator()->New<checker::ETSObjectType>( in CreateSyntheticType()
497 checker->Allocator(), syntheticName, syntheticName, in CreateSyntheticType()
498 std::make_tuple(id, checker::ETSObjectFlags::NO_OPTS, checker->Relation())); in CreateSyntheticType()
500 auto *classDecl = checker->Allocator()->New<varbinder::ClassDecl>(syntheticName); in CreateSyntheticType()
502 … checker->Allocator()->New<varbinder::LocalVariable>(classDecl, varbinder::VariableFlags::CLASS); in CreateSyntheticType()
503 var->SetTsType(syntheticObjType); in CreateSyntheticType()
504 lastObjectType->AddProperty<checker::PropertyType::STATIC_FIELD>(var); in CreateSyntheticType()
505 syntheticObjType->SetEnclosingType(lastObjectType); in CreateSyntheticType()
509 // NOLINTBEGIN(modernize-avoid-c-arrays)
512 static constexpr char const ITERATOR_TYPE_ABSENT[] = "Cannot obtain iterator type in 'for-of' state…
513 // NOLINTEND(modernize-avoid-c-arrays)
515 checker::Type *GetIteratorType(ETSChecker *checker, checker::Type *elemType, ir::AstNode *left) in GetIteratorType() argument
518 // CC-OFFNXT(G.FMT.14-CPP) project code style in GetIteratorType()
519 …auto const getIterType = [checker, elemType](ir::VariableDeclarator *const declarator) -> checker:… in GetIteratorType()
520 if (declarator->TsType() == nullptr) { in GetIteratorType()
521 …if (auto *resolved = checker->FindVariableInFunctionScope(declarator->Id()->AsIdentifier()->Name(), in GetIteratorType()
524 resolved->SetTsType(elemType); in GetIteratorType()
528 return declarator->TsType(); in GetIteratorType()
530 return checker->GlobalTypeError(); in GetIteratorType()
533 checker::Type *iterType = nullptr; in GetIteratorType()
534 if (left->IsIdentifier()) { in GetIteratorType()
535 if (auto *const variable = left->AsIdentifier()->Variable(); variable != nullptr) { in GetIteratorType()
536 auto *decl = variable->Declaration(); in GetIteratorType()
537 if (decl->IsConstDecl() || decl->IsReadonlyDecl()) { in GetIteratorType()
539 decl->IsConstDecl() ? INVALID_CONST_ASSIGNMENT : INVALID_READONLY_ASSIGNMENT; in GetIteratorType()
540 checker->LogTypeError({errorMsg, variable->Name()}, decl->Node()->Start()); in GetIteratorType()
543 iterType = left->AsIdentifier()->TsType(); in GetIteratorType()
544 } else if (left->IsVariableDeclaration()) { in GetIteratorType()
545 …if (auto const &declarators = left->AsVariableDeclaration()->Declarators(); !declarators.empty()) { in GetIteratorType()
551 checker->LogTypeError(ITERATOR_TYPE_ABSENT, left->Start()); in GetIteratorType()
552 return checker->GlobalTypeError(); in GetIteratorType()
557 bool CheckArgumentVoidType(checker::Type *&funcReturnType, ETSChecker *checker, const std::string &… in CheckArgumentVoidType() argument
561 if (!funcReturnType->IsETSVoidType() && !funcReturnType->IsIntType()) { in CheckArgumentVoidType()
562 … checker->LogTypeError("Bad return type, main enable only void or int type.", st->Start()); in CheckArgumentVoidType()
568 bool CheckReturnType(ETSChecker *checker, checker::Type *funcReturnType, checker::Type *argumentTyp… in CheckReturnType() argument
571 if (funcReturnType->IsETSVoidType() || funcReturnType == checker->GlobalVoidType()) { in CheckReturnType()
572 if (argumentType != checker->GlobalVoidType()) { in CheckReturnType()
573 checker->LogTypeError("Unexpected return value, enclosing method return type is void.", in CheckReturnType()
574 stArgument->Start()); in CheckReturnType()
577 … if (!checker::AssignmentContext(checker->Relation(), stArgument, argumentType, funcReturnType, in CheckReturnType()
578 stArgument->Start(), {}, in CheckReturnType()
579 … checker::TypeRelationFlag::DIRECT_RETURN | checker::TypeRelationFlag::NO_THROW) in CheckReturnType()
580 // CC-OFFNXT(G.FMT.02) project code style in CheckReturnType()
582 …checker->LogTypeError({"Return statement type is not compatible with the enclosing method's return… in CheckReturnType()
583 stArgument->Start()); in CheckReturnType()
589 if (isAsync && funcReturnType->IsETSObjectType() && in CheckReturnType()
590 … funcReturnType->AsETSObjectType()->GetOriginalBaseType() == checker->GlobalBuiltinPromiseType()) { in CheckReturnType()
591 auto promiseArg = funcReturnType->AsETSObjectType()->TypeArguments()[0]; in CheckReturnType()
592 …checker::AssignmentContext(checker->Relation(), stArgument, argumentType, promiseArg, stArgument->… in CheckReturnType()
593 … checker::TypeRelationFlag::DIRECT_RETURN | checker::TypeRelationFlag::NO_THROW); in CheckReturnType()
594 if (checker->Relation()->IsTrue()) { in CheckReturnType()
599 const Type *targetType = checker->TryGettingFunctionTypeFromInvokeFunction(funcReturnType); in CheckReturnType()
600 const Type *sourceType = checker->TryGettingFunctionTypeFromInvokeFunction(argumentType); in CheckReturnType()
601 …if (!checker::AssignmentContext(checker->Relation(), stArgument, argumentType, funcReturnType, stA… in CheckReturnType()
602 … {}, checker::TypeRelationFlag::DIRECT_RETURN | checker::TypeRelationFlag::NO_THROW) in CheckReturnType()
603 // CC-OFFNXT(G.FMT.02) project code style in CheckReturnType()
605 checker->LogTypeError( in CheckReturnType()
607 stArgument->Start()); in CheckReturnType()
613 void InferReturnType(ETSChecker *checker, ir::ScriptFunction *containingFunc, checker::Type *&funcR… in InferReturnType() argument
618 …stArgument == nullptr ? checker->GlobalVoidType() : checker->GetNonConstantType(stArgument->Check(… in InferReturnType()
626 if (stArgument != nullptr && stArgument->IsArrowFunctionExpression()) { in InferReturnType()
627 auto arrowFunc = stArgument->AsArrowFunctionExpression(); in InferReturnType()
628 auto typeAnnotation = arrowFunc->CreateTypeAnnotation(checker); in InferReturnType()
630 auto *argumentType = arrowFunc->TsType(); in InferReturnType()
631 funcReturnType = typeAnnotation->GetType(checker); in InferReturnType()
633 const Type *sourceType = checker->TryGettingFunctionTypeFromInvokeFunction(argumentType); in InferReturnType()
634 const Type *targetType = checker->TryGettingFunctionTypeFromInvokeFunction(funcReturnType); in InferReturnType()
636 … if (!checker::AssignmentContext(checker->Relation(), arrowFunc, argumentType, funcReturnType, in InferReturnType()
637 stArgument->Start(), {}, in InferReturnType()
638 … checker::TypeRelationFlag::DIRECT_RETURN | checker::TypeRelationFlag::NO_THROW) in InferReturnType()
639 // CC-OFFNXT(G.FMT.02) project code style in InferReturnType()
641 checker->LogTypeError({"Type '", sourceType, in InferReturnType()
643 stArgument->Start()); in InferReturnType()
644 funcReturnType = checker->GlobalTypeError(); in InferReturnType()
649 containingFunc->Signature()->SetReturnType(funcReturnType); in InferReturnType()
650 containingFunc->Signature()->RemoveSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE); in InferReturnType()
651 containingFunc->Signature()->AddSignatureFlag(checker::SignatureFlags::INFERRED_RETURN_TYPE); in InferReturnType()
652 checker->VarBinder()->AsETSBinder()->BuildFunctionName(containingFunc); in InferReturnType()
654 if (stArgument != nullptr && stArgument->IsObjectExpression()) { in InferReturnType()
655 stArgument->AsObjectExpression()->SetPreferredType(funcReturnType); in InferReturnType()
659 void ProcessReturnStatements(ETSChecker *checker, ir::ScriptFunction *containingFunc, checker::Type… in ProcessReturnStatements() argument
662 funcReturnType = containingFunc->Signature()->ReturnType(); in ProcessReturnStatements()
666 if (!funcReturnType->IsETSVoidType() && funcReturnType != checker->GlobalVoidType()) { in ProcessReturnStatements()
667 … checker->LogTypeError("All return statements in the function should be empty or have a value.", in ProcessReturnStatements()
668 st->Start()); in ProcessReturnStatements()
672 if (stArgument->IsObjectExpression()) { in ProcessReturnStatements()
673 stArgument->AsObjectExpression()->SetPreferredType(funcReturnType); in ProcessReturnStatements()
676 if (stArgument->IsMemberExpression()) { in ProcessReturnStatements()
677 …checker->SetArrayPreferredTypeForNestedMemberExpressions(stArgument->AsMemberExpression(), funcRet… in ProcessReturnStatements()
680 checker::Type *argumentType = checker->GetNonConstantType(stArgument->Check(checker)); in ProcessReturnStatements()
683 if (funcReturnType->IsETSVoidType() && !argumentType->IsETSVoidType()) { in ProcessReturnStatements()
684 … checker->LogTypeError("All return statements in the function should be empty or have a value.", in ProcessReturnStatements()
685 stArgument->Start()); in ProcessReturnStatements()
689 const auto name = containingFunc->Scope()->InternalName().Mutf8(); in ProcessReturnStatements()
690 if (!CheckArgumentVoidType(funcReturnType, checker, name, st)) { in ProcessReturnStatements()
694 auto *const relation = checker->Relation(); in ProcessReturnStatements()
695 relation->SetNode(stArgument); in ProcessReturnStatements()
697 if (!relation->IsIdenticalTo(funcReturnType, argumentType)) { in ProcessReturnStatements()
698 checker->ResolveReturnStatement(funcReturnType, argumentType, containingFunc, st); in ProcessReturnStatements()
701 relation->SetNode(nullptr); in ProcessReturnStatements()
702 relation->SetFlags(checker::TypeRelationFlag::NONE); in ProcessReturnStatements()
706 ETSObjectType *CreateOptionalSignaturesForFunctionalType(ETSChecker *checker, ir::ETSFunctionType *… in CreateOptionalSignaturesForFunctionalType() argument
710 auto substitution = checker->NewSubstitution(); in CreateOptionalSignaturesForFunctionalType()
711 const auto ¶ms = node->Params(); in CreateOptionalSignaturesForFunctionalType()
712 auto returnType = node->ReturnType()->GetType(checker); in CreateOptionalSignaturesForFunctionalType()
715 checker::ETSChecker::EmplaceSubstituted( in CreateOptionalSignaturesForFunctionalType()
716 … substitution, genericInterfaceType->TypeArguments()[i]->AsETSTypeParameter()->GetOriginal(), in CreateOptionalSignaturesForFunctionalType()
717 InstantiateBoxedPrimitiveType(checker, params[i], in CreateOptionalSignaturesForFunctionalType()
718 … params[i]->AsETSParameterExpression()->TypeAnnotation()->GetType(checker))); in CreateOptionalSignaturesForFunctionalType()
722 checker::ETSChecker::EmplaceSubstituted( in CreateOptionalSignaturesForFunctionalType()
723 … substitution, genericInterfaceType->TypeArguments()[i]->AsETSTypeParameter()->GetOriginal(), in CreateOptionalSignaturesForFunctionalType()
724 CreateParamTypeWithDefaultParam(checker, params[i])); in CreateOptionalSignaturesForFunctionalType()
727 checker::ETSChecker::EmplaceSubstituted( in CreateOptionalSignaturesForFunctionalType()
729 genericInterfaceType->TypeArguments()[genericInterfaceType->TypeArguments().size() - 1] in CreateOptionalSignaturesForFunctionalType()
730 ->AsETSTypeParameter() in CreateOptionalSignaturesForFunctionalType()
731 ->GetOriginal(), in CreateOptionalSignaturesForFunctionalType()
732 InstantiateBoxedPrimitiveType(checker, node->ReturnType(), returnType)); in CreateOptionalSignaturesForFunctionalType()
734 return genericInterfaceType->Substitute(checker->Relation(), substitution)->AsETSObjectType(); in CreateOptionalSignaturesForFunctionalType()
737 ETSObjectType *CreateInterfaceTypeForETSFunctionType(ETSChecker *checker, ir::ETSFunctionType *node, in CreateInterfaceTypeForETSFunctionType() argument
740 auto substitution = checker->NewSubstitution(); in CreateInterfaceTypeForETSFunctionType()
742 …if (auto const ¶ms = node->Params(); params.size() < checker->GlobalBuiltinFunctionTypeVariadi… in CreateInterfaceTypeForETSFunctionType()
744 checker::ETSChecker::EmplaceSubstituted( in CreateInterfaceTypeForETSFunctionType()
745 … substitution, genericInterfaceType->TypeArguments()[i]->AsETSTypeParameter()->GetOriginal(), in CreateInterfaceTypeForETSFunctionType()
747 … checker, params[i], params[i]->AsETSParameterExpression()->TypeAnnotation()->GetType(checker))); in CreateInterfaceTypeForETSFunctionType()
751 checker::ETSChecker::EmplaceSubstituted( in CreateInterfaceTypeForETSFunctionType()
752 substitution, genericInterfaceType->TypeArguments()[i]->AsETSTypeParameter()->GetOriginal(), in CreateInterfaceTypeForETSFunctionType()
753 … InstantiateBoxedPrimitiveType(checker, node->ReturnType(), node->ReturnType()->GetType(checker))); in CreateInterfaceTypeForETSFunctionType()
754 return genericInterfaceType->Substitute(checker->Relation(), substitution)->AsETSObjectType(); in CreateInterfaceTypeForETSFunctionType()
757 Type *CreateParamTypeWithDefaultParam(ETSChecker *checker, ir::Expression *param) in CreateParamTypeWithDefaultParam() argument
759 if (!param->AsETSParameterExpression()->IsDefault()) { in CreateParamTypeWithDefaultParam()
760 …checker->LogTypeError({"Expected initializer for ", param->AsETSParameterExpression()->Ident()->Na… in CreateParamTypeWithDefaultParam()
761 param->Start()); in CreateParamTypeWithDefaultParam()
764 ArenaVector<Type *> types(checker->Allocator()->Adapter()); in CreateParamTypeWithDefaultParam()
766 checker, param, param->AsETSParameterExpression()->TypeAnnotation()->GetType(checker))); in CreateParamTypeWithDefaultParam()
768 if (param->AsETSParameterExpression()->Initializer()->IsUndefinedLiteral()) { in CreateParamTypeWithDefaultParam()
769 types.push_back(checker->GlobalETSUndefinedType()); in CreateParamTypeWithDefaultParam()
772 return checker->CreateETSUnionType(Span<Type *const>(types)); in CreateParamTypeWithDefaultParam()
775 Type *InstantiateBoxedPrimitiveType(ETSChecker *checker, ir::Expression *param, Type *paramType) in InstantiateBoxedPrimitiveType() argument
777 if (paramType->IsETSReferenceType()) { in InstantiateBoxedPrimitiveType()
781 auto node = checker->Relation()->GetNode(); in InstantiateBoxedPrimitiveType()
782 checker->Relation()->SetNode(param); in InstantiateBoxedPrimitiveType()
783 auto boxedTypeArg = checker->MaybeBoxInRelation(paramType); in InstantiateBoxedPrimitiveType()
784 …paramType = boxedTypeArg->Instantiate(checker->Allocator(), checker->Relation(), checker->GetGloba… in InstantiateBoxedPrimitiveType()
785 checker->Relation()->SetNode(node); in InstantiateBoxedPrimitiveType()
786 ASSERT(paramType->IsETSReferenceType()); in InstantiateBoxedPrimitiveType()
790 } // namespace ark::es2panda::checker