diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index d929762e4ea114d4aa323ba4dda8f3aad47c3bfb..9ac333fc1503301f6ebf66cf4a0afebe1a1b3e28 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -407,6 +407,19 @@ static void ClearPreferredTypeForArray(checker::ETSChecker *checker, ir::Express } } +static bool CheckArrowFunctionParamIfNeeded(ETSChecker *checker, Signature *substitutedSig, + const ArenaVector &arguments, TypeRelationFlag flags) +{ + if ((flags & TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA) != 0 && arguments.back()->IsArrowFunctionExpression()) { + ir::ScriptFunction *const lambda = arguments.back()->AsArrowFunctionExpression()->Function(); + auto targetParm = substitutedSig->GetSignatureInfo()->params.back()->Declaration()->Node(); + if (!checker->CheckLambdaAssignable(targetParm->AsETSParameterExpression(), lambda)) { + return false; + } + } + return true; +} + // CC-OFFNXT(huge_method[C++], G.FUN.01-CPP, G.FUD.05) solid logic bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, const ArenaVector &arguments, TypeRelationFlag flags, @@ -467,14 +480,7 @@ bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, } } - if ((flags & TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA) != 0 && arguments.back()->IsArrowFunctionExpression()) { - ir::ScriptFunction *const lambda = arguments.back()->AsArrowFunctionExpression()->Function(); - auto targetParm = substitutedSig->GetSignatureInfo()->params.back()->Declaration()->Node(); - if (!CheckLambdaAssignable(targetParm->AsETSParameterExpression(), lambda)) { - return false; - } - } - return true; + return CheckArrowFunctionParamIfNeeded(this, substitutedSig, arguments, flags); } bool ETSChecker::ValidateSignatureInvocationContext(Signature *substitutedSig, ir::Expression *argument, diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 8a02358fb9b6d9d40abcf07dddb2d9ca6d4f2da7..d63f83880c7fdfca19d113cb269132d53084a8cc 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -201,6 +201,27 @@ ETSFunctionType *ETSObjectType::CreateMethodTypeForProp(const util::StringView & return checker->CreateETSMethodType(name, {{}, Allocator()->Adapter()}); } +static void ReplaceArgInSig(std::multimap &signatureSet, Signature *sigToInsert, + TypeRelation *relation) +{ + auto range = signatureSet.equal_range(sigToInsert->ArgCount()); + bool replaced = false; + for (auto it = range.first; it != range.second; ++it) { + auto sigToReplace = it->second; + + if (relation->IsSupertypeOf(sigToReplace->Owner(), sigToInsert->Owner()) && + relation->SignatureIsSupertypeOf(sigToReplace, sigToInsert)) { + signatureSet.erase(it); + signatureSet.insert({sigToInsert->ArgCount(), sigToInsert}); + replaced = true; + break; + } + } + if (!replaced) { + signatureSet.insert({sigToInsert->ArgCount(), sigToInsert}); + } +} + // CC-OFFNXT(huge_depth) solid logic static void AddSignatureToSignatureSet(std::multimap &signatureSet, varbinder::LocalVariable *found, TypeRelation *relation, @@ -213,22 +234,7 @@ static void AddSignatureToSignatureSet(std::multimap &signa } if (signatureSet.count(sigToInsert->ArgCount()) != 0U) { - auto range = signatureSet.equal_range(sigToInsert->ArgCount()); - bool replaced = false; - for (auto it = range.first; it != range.second; ++it) { - auto sigToReplace = it->second; - - if (relation->IsSupertypeOf(sigToReplace->Owner(), sigToInsert->Owner()) && - relation->SignatureIsSupertypeOf(sigToReplace, sigToInsert)) { - signatureSet.erase(it); - signatureSet.insert({sigToInsert->ArgCount(), sigToInsert}); - replaced = true; - break; - } - } - if (!replaced) { - signatureSet.insert({sigToInsert->ArgCount(), sigToInsert}); - } + ReplaceArgInSig(signatureSet, sigToInsert, relation); } else { signatureSet.insert({sigToInsert->ArgCount(), sigToInsert}); } diff --git a/ets2panda/compiler/core/compilerImpl.cpp b/ets2panda/compiler/core/compilerImpl.cpp index 6c78c3146b070a6dc2ea47946f2a5ba98bcb7501..f569b4f25896cd3b6d1723a1f282fd76dfa7a209 100644 --- a/ets2panda/compiler/core/compilerImpl.cpp +++ b/ets2panda/compiler/core/compilerImpl.cpp @@ -172,6 +172,12 @@ static bool DoIsolatedDeclgenCheck(const util::Options &options, const std::stri return true; } +static bool CheckIfPhaseToSkip(util::Options &options, const std::string &name) +{ + return options.GetSkipPhases().count(name) > 0 || + (options.IsGenerateDeclEnableIsolated() && name == compiler::InsertOptionalParametersAnnotation::NAME); +} + // CC-OFFNXT(huge_method[C++], G.FUN.01-CPP, G.FUD.05) solid logic static bool RunVerifierAndPhases(public_lib::Context &context, parser::Program &program) { @@ -184,7 +190,6 @@ static bool RunVerifierAndPhases(public_lib::Context &context, parser::Program & options.SetGenerateDeclEnabled(true); } - bool skipPhase = false; bool afterCheckerPhase = false; while (auto phase = context.phaseManager->NextPhase()) { const auto name = std::string {phase->Name()}; @@ -192,10 +197,7 @@ static bool RunVerifierAndPhases(public_lib::Context &context, parser::Program & afterCheckerPhase = true; } - skipPhase = - options.GetSkipPhases().count(name) > 0 || - (options.IsGenerateDeclEnableIsolated() && name == compiler::InsertOptionalParametersAnnotation::NAME); - if (skipPhase) { + if (CheckIfPhaseToSkip(options, name)) { continue; } @@ -215,6 +217,7 @@ static bool RunVerifierAndPhases(public_lib::Context &context, parser::Program & if (!options.IsGenerateDeclEnableIsolated()) { verifier.IntroduceNewInvariants(phase->Name()); } + if (verifierEachPhase || options.HasVerifierPhase(phase->Name())) { verifier.Verify(phase->Name()); } diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index 68ee229e51f3f7956e143fde4d6161f4ad7f1a61..dcb1c53a5e2a768a10b5884c5182304ee004003f 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -420,6 +420,26 @@ static ir::Expression *CreateToIntrinsicCallExpression(UnboxContext *uctx, check return call; } +static bool CheckIfOnTopOfUnboxing(UnboxContext *uctx, ir::Expression *expr, checker::Type *unboxedType, + checker::Type *boxedType) +{ + return expr->IsCallExpression() && expr->AsCallExpression()->Arguments().empty() && + expr->AsCallExpression()->Callee()->IsMemberExpression() && + expr->AsCallExpression()->Callee()->AsMemberExpression()->Property()->IsIdentifier() && + expr->AsCallExpression()->Callee()->AsMemberExpression()->Property()->AsIdentifier()->Name() == + // CC-OFFNXT(G.FMT.02) project code style + UnboxerMethodName(unboxedType) && + uctx->checker->Relation()->IsIdenticalTo( + expr->AsCallExpression()->Callee()->AsMemberExpression()->Object()->TsType(), boxedType); +} + +static ir::Expression *LinkUnboxingExpr(ir::Expression *expr, ir::AstNode *parent) +{ + auto *ret = expr->AsCallExpression()->Callee()->AsMemberExpression()->Object(); + ret->SetParent(parent); + return ret; +} + // CC-OFFNXT(huge_method[C++], G.FUN.01-CPP, G.FUD.05) solid logic static ir::Expression *InsertBoxing(UnboxContext *uctx, ir::Expression *expr) { @@ -428,17 +448,8 @@ static ir::Expression *InsertBoxing(UnboxContext *uctx, ir::Expression *expr) auto *parent = expr->Parent(); // Avoid boxing application right on top of unboxing. - if (expr->IsCallExpression() && expr->AsCallExpression()->Arguments().empty() && - expr->AsCallExpression()->Callee()->IsMemberExpression() && - expr->AsCallExpression()->Callee()->AsMemberExpression()->Property()->IsIdentifier() && - expr->AsCallExpression()->Callee()->AsMemberExpression()->Property()->AsIdentifier()->Name() == - // CC-OFFNXT(G.FMT.02) project code style - UnboxerMethodName(unboxedType) && - uctx->checker->Relation()->IsIdenticalTo( - expr->AsCallExpression()->Callee()->AsMemberExpression()->Object()->TsType(), boxedType)) { - auto *ret = expr->AsCallExpression()->Callee()->AsMemberExpression()->Object(); - ret->SetParent(parent); - return ret; + if (CheckIfOnTopOfUnboxing(uctx, expr, unboxedType, boxedType)) { + return LinkUnboxingExpr(expr, parent); } auto *allocator = uctx->allocator;