diff --git a/ets2panda/compiler/core/ETSemitter.cpp b/ets2panda/compiler/core/ETSemitter.cpp index 4da7d669bffc01517c9a77c6411698abc5df42e5..aeacda2c127b742ad960426ab9d35d91eb0dc851 100644 --- a/ets2panda/compiler/core/ETSemitter.cpp +++ b/ets2panda/compiler/core/ETSemitter.cpp @@ -223,13 +223,9 @@ static pandasm::Function GenExternalFunction(checker::Signature *signature, bool void FilterForSimultaneous(varbinder::ETSBinder *varbinder) { - ArenaSet &classDefinitions = varbinder->GetGlobalRecordTable()->ClassDefinitions(); - for (auto it = classDefinitions.begin(); it != classDefinitions.end(); ++it) { - if ((*it)->InternalName().Is(Signatures::ETS_GLOBAL)) { - classDefinitions.erase(it); - break; - } - } + varbinder->GetGlobalRecordTable()->Erase( + [](ir::ClassDefinition *classDef) { return classDef->InternalName().Is(Signatures::ETS_GLOBAL); }); + std::vector filterFunctions = { Signatures::UNUSED_ETSGLOBAL_CTOR, Signatures::UNUSED_ETSGLOBAL_INIT, Signatures::UNUSED_ETSGLOBAL_MAIN}; auto &functions = varbinder->Functions(); @@ -253,21 +249,21 @@ void ETSEmitter::GenAnnotation() auto *globalRecordTable = varbinder->GetGlobalRecordTable(); auto baseName = varbinder->GetRecordTable()->RecordName().Mutf8(); - for (auto *annoDecl : globalRecordTable->AnnotationDeclarations()) { + + globalRecordTable->Iterate([this, &baseName](ir::AnnotationDeclaration *annoDecl) { std::string newBaseName = util::NameMangler::GetInstance()->CreateMangledNameForAnnotation( baseName, annoDecl->GetBaseName()->Name().Mutf8()); GenCustomAnnotationRecord(annoDecl, newBaseName, annoDecl->IsDeclare()); - } + }); - for (auto *classDecl : globalRecordTable->ClassDefinitions()) { - GenClassRecord(classDecl, classDecl->IsDeclare()); - } + globalRecordTable->Iterate( + [this](ir::ClassDefinition *classDecl) { GenClassRecord(classDecl, classDecl->IsDeclare()); }); - for (auto *interfaceDecl : globalRecordTable->InterfaceDeclarations()) { + globalRecordTable->Iterate([this](ir::TSInterfaceDeclaration *interfaceDecl) { GenInterfaceRecord(interfaceDecl, interfaceDecl->IsDeclare()); - } + }); - for (auto *signature : globalRecordTable->Signatures()) { + globalRecordTable->Iterate([this](varbinder::FunctionScope *signature) { auto *scriptFunc = signature->Node()->AsScriptFunction(); auto func = GenScriptFunction(scriptFunc, this); if (scriptFunc->IsDeclare()) { @@ -279,7 +275,7 @@ void ETSEmitter::GenAnnotation() func.metadata->AddAnnotations(annotations); } Program()->AddToFunctionTable(std::move(func)); - } + }); for (auto [extProg, recordTable] : varbinder->GetExternalRecordTable()) { if (recordTable == varbinder->GetRecordTable()) { @@ -314,21 +310,22 @@ void ETSEmitter::GenExternalRecord(varbinder::RecordTable *recordTable, const pa !recordTable->Program()->VarBinder()->IsGenStdLib() && !recordTable->Program()->IsGenAbcForExternal(); const auto *varbinder = static_cast(Context()->parserProgram->VarBinder()); auto baseName = varbinder->GetRecordTable()->RecordName().Mutf8(); - for (auto *annoDecl : recordTable->AnnotationDeclarations()) { + + recordTable->Iterate([this, &baseName, isExternalFromCompile](ir::AnnotationDeclaration *annoDecl) { std::string newBaseName = util::NameMangler::GetInstance()->CreateMangledNameForAnnotation( baseName, annoDecl->GetBaseName()->Name().Mutf8()); GenCustomAnnotationRecord(annoDecl, newBaseName, isExternalFromCompile || annoDecl->IsDeclare()); - } + }); - for (auto *classDecl : recordTable->ClassDefinitions()) { + recordTable->Iterate([this, isExternalFromCompile](ir::ClassDefinition *classDecl) { GenClassRecord(classDecl, isExternalFromCompile || classDecl->IsDeclare()); - } + }); - for (auto *interfaceDecl : recordTable->InterfaceDeclarations()) { + recordTable->Iterate([this, isExternalFromCompile](ir::TSInterfaceDeclaration *interfaceDecl) { GenInterfaceRecord(interfaceDecl, isExternalFromCompile || interfaceDecl->IsDeclare()); - } + }); - for (auto *signature : recordTable->Signatures()) { + recordTable->Iterate([this, extProg, isExternalFromCompile](varbinder::FunctionScope *signature) { auto scriptFunc = signature->Node()->AsScriptFunction(); auto func = GenScriptFunction(scriptFunc, this); @@ -343,13 +340,13 @@ void ETSEmitter::GenExternalRecord(varbinder::RecordTable *recordTable, const pa } if (func.metadata->IsForeign() && IsFromSelfHeadFile(func.name, Context()->parserProgram, extProg)) { - continue; + return; } if (Program()->functionStaticTable.find(func.name) == Program()->functionStaticTable.cend()) { Program()->AddToFunctionTable(std::move(func)); } - } + }); } // Helper function to reduce EmitDefaultFieldValue size and pass code check diff --git a/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_i.cpp b/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_i.cpp index 585921f05c96daec124a912fbeadc42a24f846ab..a8fa83255ff66b5fbd0459fb6319acecb5cf3941 100644 --- a/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_i.cpp +++ b/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_i.cpp @@ -258,31 +258,6 @@ es2panda_Type *classInstance, [[maybe_unused]] char *hash/*return_args:*/) EXPECT_TRUE(HasMatched(targetAPIWithNoSpace)); } -/* const ArenaSet &ClassDefinitions() const */ -TEST_F(PluginConversionRuleUnitTest, ArenaSetPtrReturnValue) -{ - std::string targetCAPI {R"( - extern "C" es2panda_AstNode **RecordTableClassDefinitionsConst([[maybe_unused]] es2panda_Context *context, -es2panda_RecordTable *classInstance/*return_args:*/, size_t *returnTypeLen) - { - auto *ctx = reinterpret_cast(context); - auto *ctxAllocator = ctx->allocator; - auto resultSet = ((reinterpret_cast(classInstance))->ClassDefinitions()); - *returnTypeLen = resultSet.size(); - auto apiRes = ctxAllocator->New< es2panda_AstNode *[]>(*returnTypeLen); - size_t i = 0; - for (auto elem : resultSet) { - auto toPush = reinterpret_cast< es2panda_AstNode *>(elem); - apiRes[i++] = reinterpret_cast< es2panda_AstNode *>(toPush); - }; - return apiRes; - } - )"}; - - std::string targetAPIWithNoSpace = RemoveWhitespace(targetCAPI); - EXPECT_TRUE(HasMatched(targetAPIWithNoSpace)); -} - /* virtual void MergeBindings(VariableMap const &bindings) */ TEST_F(PluginConversionRuleUnitTest, ArenaUnorderedMapPtrInputParameter) { diff --git a/ets2panda/test/unit/union_normalisation_test.h b/ets2panda/test/unit/union_normalisation_test.h index 36b345f6c3940552772d8cb0cc84326e2ec7ed83..3e5eebcbcb60b6214a8d6a7487e474d612e65dde 100644 --- a/ets2panda/test/unit/union_normalisation_test.h +++ b/ets2panda/test/unit/union_normalisation_test.h @@ -131,14 +131,16 @@ public: static checker::Type *FindClassType(varbinder::ETSBinder *varbinder, std::string_view className) { - auto classDefs = varbinder->AsETSBinder()->GetRecordTable()->ClassDefinitions(); - auto baseClass = std::find_if(classDefs.begin(), classDefs.end(), [className](ir::ClassDefinition *cdef) { - return cdef->Ident()->Name().Is(className); + ir::ClassDefinition *baseClass = nullptr; + varbinder->AsETSBinder()->GetRecordTable()->Iterate([className, &baseClass](ir::ClassDefinition *cdef) { + if (cdef->Ident()->Name().Is(className)) { + baseClass = cdef; + } }); - if (baseClass == classDefs.end()) { + if (baseClass == nullptr) { return nullptr; } - return (*baseClass)->TsType(); + return baseClass->TsType(); } static checker::Type *FindTypeAlias(checker::ETSChecker *checker, std::string_view aliasName) diff --git a/ets2panda/test/utils/checker_test.cpp b/ets2panda/test/utils/checker_test.cpp index d4a23dd699e6d3af12ae6cdba2def90ee19670f4..591fef7066827a407304babdff038f636332838d 100644 --- a/ets2panda/test/utils/checker_test.cpp +++ b/ets2panda/test/utils/checker_test.cpp @@ -20,14 +20,16 @@ namespace test::utils { checker_alias::Type *CheckerTest::FindClassType(varbinder_alias::ETSBinder *varbinder, std::string_view className) { - auto classDefs = varbinder->AsETSBinder()->GetRecordTable()->ClassDefinitions(); - auto baseClass = std::find_if(classDefs.begin(), classDefs.end(), [className](ir_alias::ClassDefinition *cdef) { - return cdef->Ident()->Name().Is(className); + ir_alias::ClassDefinition *baseClass = nullptr; + varbinder->AsETSBinder()->GetRecordTable()->Iterate([className, &baseClass](ir_alias::ClassDefinition *cdef) { + if (cdef->Ident()->Name().Is(className)) { + baseClass = cdef; + } }); - if (baseClass == classDefs.end()) { + if (baseClass == nullptr) { return nullptr; } - return (*baseClass)->TsType(); + return baseClass->TsType(); } checker_alias::Type *CheckerTest::FindTypeAlias(checker_alias::ETSChecker *checker, std::string_view aliasName) diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index ab009bdb00f2ade86b07a61d0bfd40e2cebd756b..be967ec3a766d4aa6d3736d11451b55faaa7eb4b 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -1382,7 +1382,7 @@ void ETSBinder::BuildExternalProgram(parser::Program *extProgram) if (!extProgram->IsASTLowered()) { BuildProgram(); } else { - extRecordTable->Merge(extProgram->VarBinder()->AsETSBinder()->GetExternalRecordTable().at(extProgram)); + extRecordTable->Link(extProgram->VarBinder()->AsETSBinder()->GetExternalRecordTable().at(extProgram)); } SetProgram(savedProgram); diff --git a/ets2panda/varbinder/recordTable.h b/ets2panda/varbinder/recordTable.h index 437a2ffb79dd259f21257e6901141194fc991930..06c4af152d12d8f884cf102d07dc90addcc8f46f 100644 --- a/ets2panda/varbinder/recordTable.h +++ b/ets2panda/varbinder/recordTable.h @@ -65,7 +65,8 @@ public: annotationDeclarations_(allocator->Adapter()), signatures_(allocator->Adapter()), program_(program), - flags_(flags) + flags_(flags), + linkedRecordTables_(allocator->Adapter()) { } @@ -74,23 +75,9 @@ public: ~RecordTable() = default; - void Merge(RecordTable *other) + void Link(RecordTable *other) { - for (auto classDef : other->classDefinitions_) { - classDefinitions_.insert(classDef); - } - - for (auto interfaceDecl : other->InterfaceDeclarations()) { - interfaceDeclarations_.insert(interfaceDecl); - } - - for (auto annoDecl : other->AnnotationDeclarations()) { - annotationDeclarations_.insert(annoDecl); - } - - for (auto sig : other->signatures_) { - signatures_.insert(sig); - } + linkedRecordTables_.insert(other); } bool IsExternal() const @@ -98,44 +85,59 @@ public: return (flags_ & RecordTableFlags::EXTERNAL) != 0; } - ArenaSet &ClassDefinitions() - { - return classDefinitions_; - } - - const ArenaSet &ClassDefinitions() const - { - return classDefinitions_; - } - - ArenaSet &InterfaceDeclarations() + using ClassDefinitionTraverser = std::function; + void Iterate(const ClassDefinitionTraverser &cb) const { - return interfaceDeclarations_; - } - - const ArenaSet &InterfaceDeclarations() const - { - return interfaceDeclarations_; + for (auto classDefinition : classDefinitions_) { + cb(classDefinition); + } + for (auto linkedRecordTable : linkedRecordTables_) { + linkedRecordTable->Iterate(cb); + } } - ArenaSet &AnnotationDeclarations() + using ClassDefinitionPredicate = std::function; + void Erase(const ClassDefinitionPredicate &predicate) { - return annotationDeclarations_; + for (auto it = classDefinitions_.begin(); it != classDefinitions_.end(); ++it) { + if (predicate(*it)) { + classDefinitions_.erase(it); + break; + } + } } - const ArenaSet &AnnotationDeclarations() const + using InterfaceDeclarationTraverser = std::function; + void Iterate(const InterfaceDeclarationTraverser &cb) const { - return annotationDeclarations_; + for (auto interfaceDeclaration : interfaceDeclarations_) { + cb(interfaceDeclaration); + } + for (auto linkedRecordTable : linkedRecordTables_) { + linkedRecordTable->Iterate(cb); + } } - ArenaSet &Signatures() + using AnnotationDeclarationTraverser = std::function; + void Iterate(const AnnotationDeclarationTraverser &cb) const { - return signatures_; + for (auto annotationDeclaration : annotationDeclarations_) { + cb(annotationDeclaration); + } + for (auto linkedRecordTable : linkedRecordTables_) { + linkedRecordTable->Iterate(cb); + } } - const ArenaSet &Signatures() const + using FunctionScopeTraverser = std::function; + void Iterate(const FunctionScopeTraverser &cb) const { - return signatures_; + for (auto signature : signatures_) { + cb(signature); + } + for (auto linkedRecordTable : linkedRecordTables_) { + linkedRecordTable->Iterate(cb); + } } void EmplaceSignatures(varbinder::FunctionScope *signature, ir::ScriptFunction *func) @@ -240,6 +242,7 @@ private: parser::Program *program_ {}; BoundContext *boundCtx_ {}; RecordTableFlags flags_ {}; + ArenaSet linkedRecordTables_; }; class BoundContext {