From 3a81d2eea78fdf975024d67bb3b17fb19301d0bd Mon Sep 17 00:00:00 2001 From: varvara Date: Wed, 4 Jun 2025 16:14:08 +0300 Subject: [PATCH] another resize for codecheck --- .../compiler/lowering/ets/unboxLowering.cpp | 134 +++++++++++------- 1 file changed, 83 insertions(+), 51 deletions(-) diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index 2fc4d3c1a2..5f3e8e7c9f 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -116,11 +116,65 @@ static checker::Type *MaybeRecursivelyUnboxType(UnboxContext *uctx, checker::Typ return MaybeRecursivelyUnboxReferenceType(uctx, t); } -// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP, G.FUD.05) solid logic -static checker::Type *MaybeRecursivelyUnboxReferenceType(UnboxContext *uctx, checker::Type *t) +static checker::Type *MaybeRecursivelyUnboxTypeParameter(UnboxContext *uctx, checker::Type *t, std::uint64_t *typeId) +{ + auto typeParameter = t->AsETSTypeParameter(); + auto constraintType = typeParameter->GetConstraintType(); + // We need to avoid endless recursion in case of recursive generic types, say 'class A>' + if (typeId == 0U) { + *typeId = t->Id(); + typeParameter->SetConstraintType(MaybeRecursivelyUnboxReferenceType(uctx, constraintType)); + *typeId = 0U; + } else if (t->Id() != *typeId) { + typeParameter->SetConstraintType(MaybeRecursivelyUnboxReferenceType(uctx, constraintType)); + } + return t; +} + +static checker::Type *MaybeRecursivelyUnboxTupleType(UnboxContext *uctx, checker::Type *t) +{ + bool anyChange = false; + auto *srcTup = t->AsETSTupleType(); + + ArenaVector newTps {uctx->allocator->Adapter()}; + for (auto *e : srcTup->GetTupleTypesList()) { + auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, e); + newTps.push_back(newE); + anyChange |= (newE != e); + } + + return anyChange ? uctx->allocator->New(uctx->checker, newTps) : t; +} + +static checker::Type *MaybeRecursivelyUnboxUnionType(UnboxContext *uctx, checker::Type *t) +{ + bool anyChange = false; + auto *srcUnion = t->AsETSUnionType(); + ArenaVector newTps {uctx->allocator->Adapter()}; + for (auto *e : srcUnion->ConstituentTypes()) { + auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, e); + newTps.push_back(newE); + anyChange |= (newE != e); + } + return anyChange ? uctx->checker->CreateETSUnionType(std::move(newTps)) : t; +} + +static checker::Type *MaybeRecursivelyUnboxObjectType(UnboxContext *uctx, checker::Type *t) { - auto *allocator = uctx->allocator; bool anyChange = false; + + auto *objTp = t->AsETSObjectType(); + ArenaVector newTps {uctx->allocator->Adapter()}; + for (auto *e : objTp->TypeArguments()) { + auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, e); + newTps.push_back(newE); + anyChange |= (newE != e); + } + return anyChange ? objTp->GetOriginalBaseType()->SubstituteArguments(uctx->checker->Relation(), newTps) : t; +} + +static checker::Type *MaybeRecursivelyUnboxReferenceType(UnboxContext *uctx, checker::Type *t) +{ static std::uint64_t typeId = 0U; if (t == nullptr) { @@ -128,30 +182,11 @@ static checker::Type *MaybeRecursivelyUnboxReferenceType(UnboxContext *uctx, che } if (t->IsETSTypeParameter()) { - auto typeParameter = t->AsETSTypeParameter(); - auto constraintType = typeParameter->GetConstraintType(); - // We need to avoid endless recursion in case of recursive generic types, say 'class A>' - if (typeId == 0U) { - typeId = t->Id(); - typeParameter->SetConstraintType(MaybeRecursivelyUnboxReferenceType(uctx, constraintType)); - typeId = 0U; - } else if (t->Id() != typeId) { - typeParameter->SetConstraintType(MaybeRecursivelyUnboxReferenceType(uctx, constraintType)); - } - return t; + return MaybeRecursivelyUnboxTypeParameter(uctx, t, &typeId); } if (t->IsETSTupleType()) { - auto *srcTup = t->AsETSTupleType(); - - ArenaVector newTps {allocator->Adapter()}; - for (auto *e : srcTup->GetTupleTypesList()) { - auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, e); - newTps.push_back(newE); - anyChange |= (newE != e); - } - - return anyChange ? allocator->New(uctx->checker, newTps) : t; + return MaybeRecursivelyUnboxTupleType(uctx, t); } if (t->IsETSArrayType()) { @@ -167,25 +202,11 @@ static checker::Type *MaybeRecursivelyUnboxReferenceType(UnboxContext *uctx, che } if (t->IsETSUnionType()) { - auto *srcUnion = t->AsETSUnionType(); - ArenaVector newTps {allocator->Adapter()}; - for (auto *e : srcUnion->ConstituentTypes()) { - auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, e); - newTps.push_back(newE); - anyChange |= (newE != e); - } - return anyChange ? uctx->checker->CreateETSUnionType(std::move(newTps)) : t; + return MaybeRecursivelyUnboxUnionType(uctx, t); } if (t->IsETSObjectType()) { - auto *objTp = t->AsETSObjectType(); - ArenaVector newTps {allocator->Adapter()}; - for (auto *e : objTp->TypeArguments()) { - auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, e); - newTps.push_back(newE); - anyChange |= (newE != e); - } - return anyChange ? objTp->GetOriginalBaseType()->SubstituteArguments(uctx->checker->Relation(), newTps) : t; + return MaybeRecursivelyUnboxObjectType(uctx, t); } return t; @@ -1154,6 +1175,27 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor { ES2PANDA_UNREACHABLE(); } + checker::Type *GetHandledGetterSetterType(ir::MemberExpression *mexpr, checker::Type *propType) + { + if (propType->IsETSMethodType()) { + bool needSetter = + mexpr->Parent()->IsAssignmentExpression() && mexpr == mexpr->Parent()->AsAssignmentExpression()->Left(); + if (needSetter) { // CC-OFF(G.FUN.01-CPP, C_RULE_ID_FUNCTION_NESTING_LEVEL) solid logic + if (auto *setterSig = propType->AsETSFunctionType()->FindSetter(); setterSig != nullptr) { + HandleDeclarationNode(uctx_, setterSig->Function()); + propType = setterSig->Params()[0]->TsType(); + } + } else if (auto *getterSig = propType->AsETSFunctionType()->FindGetter(); getterSig != nullptr) { + HandleDeclarationNode(uctx_, getterSig->Function()); + propType = getterSig->ReturnType(); + } + } else if (mexpr->Property()->Variable() != nullptr) { + /* Adjustment needed for Readonly types and possibly some other cases */ + mexpr->Property()->Variable()->SetTsType(propType); + } + return propType; + } + // CC-OFFNXT(C_RULE_ID_FUNCTION_NESTING_LEVEL, huge_method[C++], huge_cca_cyclomatic_complexity[C++]) solid logic // CC-OFFNXT(huge_cyclomatic_complexity, huge_depth[C++], huge_depth, huge_method, G.FUN.01-CPP, G.FUN.05) solid void VisitMemberExpression(ir::MemberExpression *mexpr) override @@ -1182,17 +1224,7 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor { /* Special handling for getters/setters. */ if (propType->IsETSMethodType()) { - bool needSetter = mexpr->Parent()->IsAssignmentExpression() && - mexpr == mexpr->Parent()->AsAssignmentExpression()->Left(); - if (needSetter) { // CC-OFF(G.FUN.01-CPP, C_RULE_ID_FUNCTION_NESTING_LEVEL) solid logic - if (auto *setterSig = propType->AsETSFunctionType()->FindSetter(); setterSig != nullptr) { - HandleDeclarationNode(uctx_, setterSig->Function()); - propType = setterSig->Params()[0]->TsType(); - } - } else if (auto *getterSig = propType->AsETSFunctionType()->FindGetter(); getterSig != nullptr) { - HandleDeclarationNode(uctx_, getterSig->Function()); - propType = getterSig->ReturnType(); - } + propType = GetHandledGetterSetterType(mexpr, propType); } else if (mexpr->Property()->Variable() != nullptr) { /* Adjustment needed for Readonly types and possibly some other cases */ mexpr->Property()->Variable()->SetTsType(propType); -- Gitee