From c326e448cd127771f0643095fb746c2be6f94f17 Mon Sep 17 00:00:00 2001 From: Shimenkov Mikhail Date: Wed, 30 Apr 2025 18:29:22 +0300 Subject: [PATCH] Fix opAssignment lowering and koala build Signed-off-by: Shimenkov Mikhail Change-Id: Id843da63c6900a0e870012e8324c96f86ca9204b --- ets2panda/checker/types/ets/etsObjectType.cpp | 30 +++++++------ ets2panda/checker/types/ets/etsObjectType.h | 2 +- .../ets/interfacePropertyDeclarations.cpp | 1 + .../compiler/lowering/ets/opAssignment.cpp | 43 ++++++++++++------- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index ce7115139..e1564d8e3 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -171,7 +171,7 @@ static void UpdateDeclarationForGetterSetter(varbinder::LocalVariable *res, cons varbinder::LocalVariable *ETSObjectType::CreateSyntheticVarFromEverySignature(const util::StringView &name, PropertySearchFlags flags) const { - std::unordered_multimap signatureSet; + std::multimap signatureSet; CollectSignaturesForSyntheticType(signatureSet, name, flags); if (signatureSet.empty()) { @@ -200,7 +200,7 @@ ETSFunctionType *ETSObjectType::CreateMethodTypeForProp(const util::StringView & return GetRelation()->GetChecker()->AsETSChecker()->CreateETSMethodType(name, {{}, Allocator()->Adapter()}); } -static void AddSignatureToSignatureSet(std::unordered_multimap &signatureSet, +static void AddSignatureToSignatureSet(std::multimap &signatureSet, varbinder::LocalVariable *found, TypeRelation *relation, PropertySearchFlags flags) { @@ -210,26 +210,30 @@ static void AddSignatureToSignatureSet(std::unordered_multimapToString()) != 0U) { - auto range = signatureSet.equal_range(sigToInsert->ToString()); + 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) { - if (relation->IsSupertypeOf(sigToInsert->Owner(), it->second->Owner())) { - continue; - } - if (relation->IsSupertypeOf(it->second->Owner(), sigToInsert->Owner())) { + auto sigToReplace = it->second; + + if (relation->IsSupertypeOf(sigToReplace->Owner(), sigToInsert->Owner()) && + relation->SignatureIsSupertypeOf(sigToReplace, sigToInsert)) { signatureSet.erase(it); - signatureSet.insert({sigToInsert->ToString(), sigToInsert}); - } else { - signatureSet.insert({sigToInsert->ToString(), sigToInsert}); + signatureSet.insert({sigToInsert->ArgCount(), sigToInsert}); + replaced = true; + break; } } + if (!replaced) { + signatureSet.insert({sigToInsert->ArgCount(), sigToInsert}); + } } else { - signatureSet.insert({sigToInsert->ToString(), sigToInsert}); + signatureSet.insert({sigToInsert->ArgCount(), sigToInsert}); } } } -void ETSObjectType::CollectSignaturesForSyntheticType(std::unordered_multimap &signatureSet, +void ETSObjectType::CollectSignaturesForSyntheticType(std::multimap &signatureSet, const util::StringView &name, PropertySearchFlags flags) const { if ((flags & PropertySearchFlags::SEARCH_STATIC_METHOD) != 0) { diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index db607a133..3894142c7 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -405,7 +405,7 @@ protected: virtual ETSFunctionType *CreateMethodTypeForProp(const util::StringView &name) const; private: - void CollectSignaturesForSyntheticType(std::unordered_multimap &signatures, + void CollectSignaturesForSyntheticType(std::multimap &signatures, const util::StringView &name, PropertySearchFlags flags) const; template diff --git a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp index 01327be62..72bd64d07 100644 --- a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp +++ b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp @@ -60,6 +60,7 @@ void InterfacePropertyDeclarationsPhase::TransformOptionalFieldTypeAnnotation(ch types.push_back(checker->AllocNode(checker->Allocator())); auto *const unionType = checker->AllocNode(std::move(types), checker->Allocator()); field->SetTypeAnnotation(unionType); + unionType->SetParent(field); } field->ClearModifier(ir::ModifierFlags::OPTIONAL); diff --git a/ets2panda/compiler/lowering/ets/opAssignment.cpp b/ets2panda/compiler/lowering/ets/opAssignment.cpp index f73820990..8f9c6584b 100644 --- a/ets2panda/compiler/lowering/ets/opAssignment.cpp +++ b/ets2panda/compiler/lowering/ets/opAssignment.cpp @@ -176,15 +176,28 @@ static std::tuple> GenerateStringForA auto result = GenerateNestedMemberAccess(expr, allocator, counter); counter += std::get<1>(result).size(); retStr += " = ( " + std::get<0>(result) + ' ' + std::string {lexer::TokenToString(CombinedOpToOp(opEqual))} + - " (@@E" + std::to_string(counter) + ")) as @@T" + std::to_string(counter + 1); + " (@@E" + std::to_string(counter) + "))"; retVec.insert(retVec.end(), std::get<1>(result).begin(), std::get<1>(result).end()); return {retStr, retVec}; } +static std::string GetCastString(checker::ETSChecker *checker, ir::Expression *expr, ArenaVector &vec) +{ + auto type = expr->TsType(); + if (type->IsETSObjectType() && type->AsETSObjectType()->IsBoxedPrimitive()) { + return ".to" + type->ToString() + "()"; + } + + vec.push_back(CreateProxyTypeNode(checker, expr)); + + return " as @@T" + std::to_string(vec.size()); +} + static ir::Expression *GenerateLoweredResultForLoweredAssignment( - const lexer::TokenType opEqual, ir::MemberExpression *expr, ArenaAllocator *const allocator, - parser::ETSParser *parser, const std::array additionalAssignmentExpressions) + const lexer::TokenType opEqual, ir::MemberExpression *expr, checker::ETSChecker *const checker, + parser::ETSParser *parser, ir::Expression * additionalAssignmentExpression) { + auto *allocator = checker->Allocator(); // Generated a formatString for the new lowered assignment expression // The formatString will look like this: "A = (A `operation` B) as T" // Where A is a member access @@ -206,16 +219,16 @@ static ir::Expression *GenerateLoweredResultForLoweredAssignment( expr->SetProperty(dummyIndex->Clone(allocator, expr)); auto [retStr, retVec] = GenerateStringForAssignment(opEqual, expr, allocator, dummyIndexDeclExpression.size() + 1); - retVec.push_back(additionalAssignmentExpressions[0]); - retVec.push_back(additionalAssignmentExpressions[1]); + retVec.push_back(additionalAssignmentExpression); + retStr += GetCastString(checker, expr, retVec); retVec.insert(retVec.begin(), dummyIndexDeclExpression.begin(), dummyIndexDeclExpression.end()); retStr = dummyIndexDeclStr + retStr; return parser->CreateFormattedExpression(retStr, retVec); } auto [retStr, retVec] = GenerateStringForAssignment(opEqual, expr, allocator, 1); - retVec.push_back(additionalAssignmentExpressions[0]); - retVec.push_back(additionalAssignmentExpressions[1]); + retVec.push_back(additionalAssignmentExpression); + retStr += GetCastString(checker, expr, retVec); return parser->CreateFormattedExpression(retStr, retVec); } @@ -231,22 +244,22 @@ static ir::Expression *ConstructOpAssignmentResult(public_lib::Context *ctx, ir: auto *const left = assignment->Left(); auto *const right = assignment->Right(); - auto *exprType = CreateProxyTypeNode(checker, left); ir::Expression *retVal = nullptr; // Create temporary variable(s) if left hand of assignment is not defined by simple identifier[s] if (left->IsIdentifier()) { std::string formatString = "@@I1 = (@@I2 " + std::string(lexer::TokenToString(CombinedOpToOp(opEqual))) + " (@@E3))"; - if (!left->TsType()->IsETSStringType()) { - formatString += ".to" + left->TsType()->ToString() + "()"; - } - retVal = parser->CreateFormattedExpression(formatString, GetClone(allocator, left->AsIdentifier()), - GetClone(allocator, left->AsIdentifier()), right, exprType); + ArenaVector retVec (allocator->Adapter()); + retVec.push_back(GetClone(allocator, left->AsIdentifier())); + retVec.push_back(GetClone(allocator, left->AsIdentifier())); + retVec.push_back(right); + formatString += GetCastString(checker, left, retVec); + retVal = parser->CreateFormattedExpression(formatString, retVec); } else if (left->IsMemberExpression()) { // Generate ArkTS code string for new lowered assignment expression: - retVal = GenerateLoweredResultForLoweredAssignment(opEqual, left->AsMemberExpression(), allocator, parser, - {right, exprType}); + retVal = GenerateLoweredResultForLoweredAssignment(opEqual, left->AsMemberExpression(), checker, parser, + right); } else { ES2PANDA_UNREACHABLE(); } -- Gitee