diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 187aa0f3d252e03187a123abe428f1e526966b8f..e0fa5e46af2728d33286536bb5643e09b1aa566d 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -171,13 +171,10 @@ static void UpdateDeclarationForGetterSetter(varbinder::LocalVariable *res, cons varbinder::LocalVariable *ETSObjectType::CreateSyntheticVarFromEverySignature(const util::StringView &name, PropertySearchFlags flags) const { - std::vector signatures; - varbinder::LocalVariable *functionalInterface = CollectSignaturesForSyntheticType(signatures, name, flags); - // #22952: the called function *always* returns nullptr - ES2PANDA_ASSERT(functionalInterface == nullptr); - (void)functionalInterface; + std::unordered_multimap signatureSet; + CollectSignaturesForSyntheticType(signatureSet, name, flags); - if (signatures.empty()) { + if (signatureSet.empty()) { return nullptr; } @@ -185,8 +182,8 @@ varbinder::LocalVariable *ETSObjectType::CreateSyntheticVarFromEverySignature(co varbinder::VariableFlags::METHOD); ETSFunctionType *funcType = CreateMethodTypeForProp(name); - for (auto &s : signatures) { - funcType->AddCallSignature(s); + for (auto &s : signatureSet) { + funcType->AddCallSignature(s.second); } res->SetTsType(funcType); @@ -203,27 +200,41 @@ ETSFunctionType *ETSObjectType::CreateMethodTypeForProp(const util::StringView & return GetRelation()->GetChecker()->AsETSChecker()->CreateETSMethodType(name, {{}, Allocator()->Adapter()}); } -varbinder::LocalVariable *ETSObjectType::CollectSignaturesForSyntheticType(std::vector &signatures, - const util::StringView &name, - PropertySearchFlags flags) const +static void AddSignatureToSignatureSet(std::unordered_multimap &signatureSet, varbinder::LocalVariable *found, TypeRelation *relation, PropertySearchFlags flags) { - auto const addSignature = [&signatures, flags](varbinder::LocalVariable *found) -> void { - for (auto *it : found->TsType()->AsETSFunctionType()->CallSignatures()) { - if (((flags & PropertySearchFlags::IGNORE_ABSTRACT) != 0) && - it->HasSignatureFlag(SignatureFlags::ABSTRACT)) { - continue; + for (auto *sigToInsert : found->TsType()->AsETSFunctionType()->CallSignatures()) { + if (((flags & PropertySearchFlags::IGNORE_ABSTRACT) != 0) && + sigToInsert->HasSignatureFlag(SignatureFlags::ABSTRACT)) { + continue; + } + + if (signatureSet.count(sigToInsert->ToString())) { + auto range = signatureSet.equal_range(sigToInsert->ToString()); + for (auto it = range.first; it != range.second; ++it) { + if (relation->IsSupertypeOf(sigToInsert->Owner(), it->second->Owner())) { + continue; + } else if (relation->IsSupertypeOf(it->second->Owner(), sigToInsert->Owner())) { + signatureSet.erase(it); + signatureSet.insert({sigToInsert->ToString(), sigToInsert}); + } else { + signatureSet.insert({sigToInsert->ToString(), sigToInsert}); + } } - // Issue: #18720 - // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) - signatures.push_back(&*it); + } else { + signatureSet.insert({sigToInsert->ToString(), sigToInsert}); } - }; + } +} +void ETSObjectType::CollectSignaturesForSyntheticType(std::unordered_multimap &signatureSet, + const util::StringView &name, + PropertySearchFlags flags) const +{ if ((flags & PropertySearchFlags::SEARCH_STATIC_METHOD) != 0) { if (auto *found = GetOwnProperty(name); found != nullptr && !found->TsType()->IsTypeError()) { ES2PANDA_ASSERT(found->TsType()->IsETSFunctionType()); - addSignature(found); + AddSignatureToSignatureSet(signatureSet, found, GetRelation(), flags); } } @@ -231,15 +242,13 @@ varbinder::LocalVariable *ETSObjectType::CollectSignaturesForSyntheticType(std:: if (auto *found = GetOwnProperty(name); found != nullptr && !found->TsType()->IsTypeError()) { ES2PANDA_ASSERT(found->TsType()->IsETSFunctionType()); - addSignature(found); + AddSignatureToSignatureSet(signatureSet, found, GetRelation(), flags); } } if (superType_ != nullptr && ((flags & PropertySearchFlags::SEARCH_IN_BASE) != 0)) { - return superType_->CollectSignaturesForSyntheticType(signatures, name, flags); + return superType_->CollectSignaturesForSyntheticType(signatureSet, name, flags); } - - return nullptr; } std::vector ETSObjectType::GetAllProperties() const diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 77089fe8eed76595c57970e34af41566be63cb95..1b7802c533af4c6333617b1717ca3ef2d90d852b 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -357,9 +357,6 @@ public: std::vector Fields() const; varbinder::LocalVariable *CreateSyntheticVarFromEverySignature(const util::StringView &name, PropertySearchFlags flags) const; - varbinder::LocalVariable *CollectSignaturesForSyntheticType(std::vector &signatures, - const util::StringView &name, - PropertySearchFlags flags) const; bool CheckIdenticalFlags(ETSObjectType *other) const; void Iterate(const PropertyTraverser &cb) const; @@ -408,6 +405,10 @@ protected: virtual ETSFunctionType *CreateMethodTypeForProp(const util::StringView &name) const; private: + void CollectSignaturesForSyntheticType(std::unordered_multimap &signatures, + const util::StringView &name, + PropertySearchFlags flags) const; + template explicit ETSObjectType(ArenaAllocator *allocator, util::StringView name, util::StringView assemblerName, std::tuple info,