From c51c6b6bc4a607185806495be4477ef23d3a0209 Mon Sep 17 00:00:00 2001 From: Georgy Bronnikov Date: Thu, 5 Jun 2025 16:27:24 +0300 Subject: [PATCH] Overridden signatures should not be considered in overload resolution Signed-off-by: Georgy Bronnikov --- .../checker/types/ets/etsDynamicType.cpp | 2 +- ets2panda/checker/types/ets/etsDynamicType.h | 2 +- ets2panda/checker/types/ets/etsObjectType.cpp | 76 +++++++++++-------- ets2panda/checker/types/ets/etsObjectType.h | 19 ++--- 4 files changed, 54 insertions(+), 45 deletions(-) diff --git a/ets2panda/checker/types/ets/etsDynamicType.cpp b/ets2panda/checker/types/ets/etsDynamicType.cpp index 3fb4c1392d..cd6be095d6 100644 --- a/ets2panda/checker/types/ets/etsDynamicType.cpp +++ b/ets2panda/checker/types/ets/etsDynamicType.cpp @@ -105,7 +105,7 @@ bool ETSDynamicType::IsConvertible(Type const *target) target->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC | checker::TypeFlag::ETS_BOOLEAN); } -ETSFunctionType *ETSDynamicType::CreateMethodTypeForProp(const util::StringView &name) const +ETSFunctionType *ETSDynamicType::CreateMethodTypeForProp(util::StringView name) const { auto checker = GetRelation()->GetChecker()->AsETSChecker(); return checker->CreateETSDynamicMethodType(name, {{}, Allocator()->Adapter()}, lang_); diff --git a/ets2panda/checker/types/ets/etsDynamicType.h b/ets2panda/checker/types/ets/etsDynamicType.h index 9506417407..47b99e3102 100644 --- a/ets2panda/checker/types/ets/etsDynamicType.h +++ b/ets2panda/checker/types/ets/etsDynamicType.h @@ -57,7 +57,7 @@ public: return hasDecl_; } - ETSFunctionType *CreateMethodTypeForProp(const util::StringView &name) const override; + ETSFunctionType *CreateMethodTypeForProp(util::StringView name) const override; void ToAssemblerType(std::stringstream &ss) const override; diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index ae153c0668..6d519a9904 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -20,12 +20,15 @@ #include "checker/types/globalTypesHolder.h" #include "checker/types/ets/etsAsyncFuncReturnType.h" #include "checker/types/ets/etsEnumType.h" -#include "checker/types/ets/etsDynamicFunctionType.h" #include "compiler/lowering/phase.h" #include "ir/statements/annotationDeclaration.h" namespace ark::es2panda::checker { +static std::multimap GetSignaturesForSyntheticType(ETSObjectType const *owner, + util::StringView name, + PropertySearchFlags flags); + void ETSObjectType::Iterate(const PropertyTraverser &cb) const { for (const auto *prop : GetAllProperties()) { @@ -41,8 +44,7 @@ void ETSObjectType::Iterate(const PropertyTraverser &cb) const } } -varbinder::LocalVariable *ETSObjectType::SearchFieldsDecls(const util::StringView &name, - PropertySearchFlags flags) const +varbinder::LocalVariable *ETSObjectType::SearchFieldsDecls(util::StringView name, PropertySearchFlags flags) const { varbinder::LocalVariable *res {}; if ((flags & PropertySearchFlags::SEARCH_INSTANCE_FIELD) != 0) { @@ -63,7 +65,7 @@ varbinder::LocalVariable *ETSObjectType::SearchFieldsDecls(const util::StringVie return res; } -varbinder::LocalVariable *ETSObjectType::GetProperty(const util::StringView &name, PropertySearchFlags flags) const +varbinder::LocalVariable *ETSObjectType::GetProperty(util::StringView name, PropertySearchFlags flags) const { varbinder::LocalVariable *res = SearchFieldsDecls(name, flags); if (res == nullptr && (flags & PropertySearchFlags::SEARCH_METHOD) != 0) { @@ -173,11 +175,10 @@ static void UpdateDeclarationForGetterSetter(varbinder::LocalVariable *res, cons res->Reset(decl, var->Flags()); } -varbinder::LocalVariable *ETSObjectType::CreateSyntheticVarFromEverySignature(const util::StringView &name, +varbinder::LocalVariable *ETSObjectType::CreateSyntheticVarFromEverySignature(util::StringView name, PropertySearchFlags flags) const { - std::multimap signatureSet; - CollectSignaturesForSyntheticType(signatureSet, name, flags); + auto signatureSet = GetSignaturesForSyntheticType(this, name, flags); if (signatureSet.empty()) { return nullptr; @@ -199,35 +200,36 @@ varbinder::LocalVariable *ETSObjectType::CreateSyntheticVarFromEverySignature(co return res; } -ETSFunctionType *ETSObjectType::CreateMethodTypeForProp(const util::StringView &name) const +ETSFunctionType *ETSObjectType::CreateMethodTypeForProp(util::StringView name) const { ES2PANDA_ASSERT(GetRelation() != nullptr); return GetRelation()->GetChecker()->AsETSChecker()->CreateETSMethodType(name, {{}, Allocator()->Adapter()}); } -static void ReplaceArgInSig(std::multimap &signatureSet, Signature *sigToInsert, +static void ReplaceArgInSig(std::multimap *signatureSet, Signature *sigToInsert, TypeRelation *relation) { - auto range = signatureSet.equal_range(sigToInsert->ArgCount()); - bool replaced = false; + auto range = signatureSet->equal_range(sigToInsert->ArgCount()); for (auto it = range.first; it != range.second; ++it) { auto sigToReplace = it->second; + if (relation->IsSupertypeOf(sigToInsert->Owner(), sigToReplace->Owner()) && + relation->SignatureIsSupertypeOf(sigToInsert, sigToReplace)) { + // Already overridden by a subtype's signature + return; + } if (relation->IsSupertypeOf(sigToReplace->Owner(), sigToInsert->Owner()) && relation->SignatureIsSupertypeOf(sigToReplace, sigToInsert)) { - signatureSet.erase(it); - signatureSet.insert({sigToInsert->ArgCount(), sigToInsert}); - replaced = true; - break; + signatureSet->erase(it); + signatureSet->insert({sigToInsert->ArgCount(), sigToInsert}); + return; } } - if (!replaced) { - signatureSet.insert({sigToInsert->ArgCount(), sigToInsert}); - } + signatureSet->insert({sigToInsert->ArgCount(), sigToInsert}); } // CC-OFFNXT(huge_depth) solid logic -static void AddSignatureToSignatureSet(std::multimap &signatureSet, +static void AddSignatureToSignatureSet(std::multimap *signatureSet, varbinder::LocalVariable *found, TypeRelation *relation, PropertySearchFlags flags) { @@ -237,44 +239,54 @@ static void AddSignatureToSignatureSet(std::multimap &signa continue; } - if (signatureSet.count(sigToInsert->ArgCount()) != 0U) { + if (signatureSet->count(sigToInsert->ArgCount()) != 0U) { ReplaceArgInSig(signatureSet, sigToInsert, relation); } else { - signatureSet.insert({sigToInsert->ArgCount(), sigToInsert}); + signatureSet->insert({sigToInsert->ArgCount(), sigToInsert}); } } } -void ETSObjectType::CollectSignaturesForSyntheticType(std::multimap &signatureSet, - const util::StringView &name, PropertySearchFlags flags) const +static void CollectSignaturesForSyntheticType(ETSObjectType const *owner, + std::multimap *signatureSet, util::StringView name, + PropertySearchFlags flags) { if ((flags & PropertySearchFlags::SEARCH_STATIC_METHOD) != 0) { - if (auto *found = GetOwnProperty(name); + if (auto *found = owner->GetOwnProperty(name); found != nullptr && !found->TsType()->IsTypeError()) { ES2PANDA_ASSERT(found->TsType()->IsETSFunctionType()); - AddSignatureToSignatureSet(signatureSet, found, GetRelation(), flags); + AddSignatureToSignatureSet(signatureSet, found, owner->GetRelation(), flags); } } if ((flags & PropertySearchFlags::SEARCH_INSTANCE_METHOD) != 0) { - if (auto *found = GetOwnProperty(name); + if (auto *found = owner->GetOwnProperty(name); found != nullptr && !found->TsType()->IsTypeError()) { ES2PANDA_ASSERT(found->TsType()->IsETSFunctionType()); - AddSignatureToSignatureSet(signatureSet, found, GetRelation(), flags); + AddSignatureToSignatureSet(signatureSet, found, owner->GetRelation(), flags); } } - if (superType_ != nullptr && ((flags & PropertySearchFlags::SEARCH_IN_BASE) != 0)) { - superType_->CollectSignaturesForSyntheticType(signatureSet, name, flags); + if (owner->SuperType() != nullptr && ((flags & PropertySearchFlags::SEARCH_IN_BASE) != 0)) { + CollectSignaturesForSyntheticType(owner->SuperType(), signatureSet, name, flags); } if ((flags & PropertySearchFlags::SEARCH_IN_INTERFACES) != 0) { - for (auto *interface : interfaces_) { - interface->CollectSignaturesForSyntheticType(signatureSet, name, flags); + for (auto *interface : owner->Interfaces()) { + CollectSignaturesForSyntheticType(interface, signatureSet, name, flags); } } } +static std::multimap GetSignaturesForSyntheticType(ETSObjectType const *owner, + util::StringView name, + PropertySearchFlags flags) +{ + std::multimap signatureSet; + CollectSignaturesForSyntheticType(owner, &signatureSet, name, flags); + return signatureSet; +} + std::vector ETSObjectType::GetAllProperties() const { std::vector allProperties; @@ -1477,7 +1489,7 @@ ETSObjectType *ETSObjectType::GetInstantiatedType(util::StringView hash) return found2->second; } -void ETSObjectType::InsertInstantiationMap(const util::StringView &key, ETSObjectType *value) +void ETSObjectType::InsertInstantiationMap(util::StringView key, ETSObjectType *value) { auto &instantiationMap = compiler::GetPhaseManager()->Context()->GetChecker()->AsETSChecker()->GetObjectInstantiationMap(); diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 804fb6556c..1a5f0c13b3 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -241,12 +241,12 @@ public: bool IsDescendantOf(const ETSObjectType *ascendant) const; - const util::StringView &Name() const + const util::StringView Name() const { return name_; } - const util::StringView &AssemblerName() const + const util::StringView AssemblerName() const { return internalName_; } @@ -294,10 +294,10 @@ public: return typeParams->Scope(); } - void InsertInstantiationMap(const util::StringView &key, ETSObjectType *value); + void InsertInstantiationMap(const util::StringView key, ETSObjectType *value); template - varbinder::LocalVariable *GetOwnProperty(const util::StringView &name) const + varbinder::LocalVariable *GetOwnProperty(const util::StringView name) const { EnsurePropertiesInstantiated(); auto found = properties_[static_cast(TYPE)].find(name); @@ -345,13 +345,13 @@ public: } std::vector ForeignProperties() const; - varbinder::LocalVariable *GetProperty(const util::StringView &name, PropertySearchFlags flags) const; + varbinder::LocalVariable *GetProperty(util::StringView name, PropertySearchFlags flags) const; std::vector GetAllProperties() const; varbinder::LocalVariable *CopyProperty(varbinder::LocalVariable *prop, ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes); std::vector Methods() const; std::vector Fields() const; - varbinder::LocalVariable *CreateSyntheticVarFromEverySignature(const util::StringView &name, + varbinder::LocalVariable *CreateSyntheticVarFromEverySignature(util::StringView name, PropertySearchFlags flags) const; bool CheckIdenticalFlags(ETSObjectType *other) const; ETSObjectType *CreateETSObjectType(ir::AstNode *declNode, ETSObjectFlags flags); @@ -398,12 +398,9 @@ public: } protected: - virtual ETSFunctionType *CreateMethodTypeForProp(const util::StringView &name) const; + virtual ETSFunctionType *CreateMethodTypeForProp(util::StringView name) const; private: - void CollectSignaturesForSyntheticType(std::multimap &signatures, const util::StringView &name, - PropertySearchFlags flags) const; - template explicit ETSObjectType(ThreadSafeArenaAllocator *allocator, util::StringView name, util::StringView assemblerName, std::tuple info, @@ -440,7 +437,7 @@ private: void UpdateTypeProperty(varbinder::LocalVariable *const prop, PropertyType fieldType, PropertyProcesser const &func); - varbinder::LocalVariable *SearchFieldsDecls(const util::StringView &name, PropertySearchFlags flags) const; + varbinder::LocalVariable *SearchFieldsDecls(util::StringView name, PropertySearchFlags flags) const; void SetCopiedTypeProperties(TypeRelation *relation, ETSObjectType *copiedType, ArenaVector &&newTypeArgs, ETSObjectType *base); -- Gitee