diff --git a/ets2panda/checker/ets/dynamic.cpp b/ets2panda/checker/ets/dynamic.cpp index f5d2544345b31dd7d9677a2248c32ca4b9186ba8..b24b3a9ffe7c555a88a28a87b768f206e4918cae 100644 --- a/ets2panda/checker/ets/dynamic.cpp +++ b/ets2panda/checker/ets/dynamic.cpp @@ -373,6 +373,9 @@ ir::ClassDeclaration *ETSChecker::BuildClass(util::StringView name, const ClassB auto recordTable = isExternal ? varBinder->GetExternalRecordTable().at(varBinder->Program()) : VarBinder()->AsETSBinder()->GetGlobalRecordTable(); varbinder::BoundContext boundCtx(recordTable, classDef); + if (!VarBinder()->Program()->IsExternal()) { + varbinder::BoundContext boundCtx(varBinder->GetUsedRecordTable(), classDef); + } ArenaVector classBody(ProgramAllocator()->Adapter()); diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index c267defa3c8f07b568c3720c739da8bc9d218139..640a1d4dec8380f2a3c28aa9d4b10dcfe2c86bcb 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -177,7 +177,9 @@ Type *ETSChecker::CreatePartialTypeClass(ETSObjectType *typeToBePartial, ir::Ast } const varbinder::BoundContext boundCtx(recordTable, partialClassDef); - + if (!VarBinder()->Program()->IsExternal()) { + varbinder::BoundContext boundCtx(VarBinder()->GetUsedRecordTable(), classDef); + } NamedTypeStackElement ntse(this, partialClassDef->TsType()); // If class is external, put partial of it in global scope for the varbinder diff --git a/ets2panda/compiler/core/ETSemitter.cpp b/ets2panda/compiler/core/ETSemitter.cpp index 8f0b822ef9a54cc8c5890d195f500e6a04a388b0..d13be887f1dea2e84bcd44674942aa7cc4bdd1b9 100644 --- a/ets2panda/compiler/core/ETSemitter.cpp +++ b/ets2panda/compiler/core/ETSemitter.cpp @@ -327,32 +327,44 @@ void ETSEmitter::GenExternalRecord(varbinder::RecordTable *recordTable, const pa bool isGenStdLib = recordTable->Program()->VarBinder()->IsGenStdLib(); const auto *varbinder = static_cast(Context()->parserProgram->VarBinder()); auto baseName = varbinder->GetRecordTable()->RecordName().Mutf8(); + auto usedAnnoDecl = varbinder->GetUsedRecordTable()->AnnotationDeclarations(); for (auto *annoDecl : recordTable->AnnotationDeclarations()) { - auto newBaseName = GenerateMangledName(baseName, annoDecl->GetBaseName()->Name().Mutf8()); - GenCustomAnnotationRecord(annoDecl, newBaseName, !isGenStdLib); + if (usedAnnoDecl.find(annoDecl) != usedAnnoDecl.end()) { + auto newBaseName = GenerateMangledName(baseName, annoDecl->GetBaseName()->Name().Mutf8()); + GenCustomAnnotationRecord(annoDecl, newBaseName, !isGenStdLib); + } } + auto usedClassDecl = varbinder->GetUsedRecordTable()->ClassDefinitions(); for (auto *classDecl : recordTable->ClassDefinitions()) { - GenClassRecord(classDecl, !isGenStdLib); + if (usedClassDecl.find(classDecl) != usedClassDecl.end()) { + GenClassRecord(classDecl, !isGenStdLib); + } } + auto usedInterfaceDecl = varbinder->GetUsedRecordTable()->InterfaceDeclarations(); for (auto *interfaceDecl : recordTable->InterfaceDeclarations()) { - GenInterfaceRecord(interfaceDecl, !isGenStdLib); + if (usedInterfaceDecl.find(interfaceDecl) != usedInterfaceDecl.end()) { + GenInterfaceRecord(interfaceDecl, !isGenStdLib); + } } + auto usedSignature = varbinder->GetUsedRecordTable()->Signatures(); for (auto const *signature : recordTable->Signatures()) { - auto func = GenScriptFunction(signature->Node()->AsScriptFunction(), this); + if (usedSignature.find(signature) != usedSignature.end()) { + auto func = GenScriptFunction(signature->Node()->AsScriptFunction(), this); - if (!isGenStdLib) { - func.metadata->SetAttribute(Signatures::EXTERNAL); - } + if (!isGenStdLib) { + func.metadata->SetAttribute(Signatures::EXTERNAL); + } - if (func.metadata->IsForeign() && IsFromSelfHeadFile(func.name, Context()->parserProgram, extProg)) { - continue; - } + if (func.metadata->IsForeign() && IsFromSelfHeadFile(func.name, Context()->parserProgram, extProg)) { + continue; + } - if (Program()->functionStaticTable.find(func.name) == Program()->functionStaticTable.cend()) { - Program()->AddToFunctionTable(std::move(func)); + if (Program()->functionStaticTable.find(func.name) == Program()->functionStaticTable.cend()) { + Program()->AddToFunctionTable(std::move(func)); + } } } } diff --git a/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp b/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp index 1aa0c072ea59241d4c8282e28f9abc226d28f72d..4c9298be450f48ecebd07e2949a01224db247d3c 100644 --- a/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp +++ b/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp @@ -98,6 +98,10 @@ void GenericBridgesPhase::AddGenericBridge(ir::ClassDefinition const *const clas varbinder::BoundContext boundCtx {varBinder->GetRecordTable(), const_cast(classDefinition), true}; + if (!varBinder->Program()->IsExternal()) { + varbinder::BoundContext boundCtx {varBinder->GetUsedRecordTable(), const_cast(classDefinition), + true}; + } varBinder->AsETSBinder()->ResolveReferencesForScopeWithContext(bridgeMethod, scope); auto *checker = context_->GetChecker()->AsETSChecker(); diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index d3ad50c52ab91206a19b5d2cc231200e6f2a965f..00ff1036fff2bc153015f33677e6fc8d0a6d2e89 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -301,6 +301,9 @@ static ir::MethodDefinition *SetUpCalleeMethod(public_lib::Context *ctx, LambdaI } varbinder::BoundContext bctx {varBinder->GetRecordTable(), calleeClass->Definition(), true}; + if (!varBinder->Program()->IsExternal()) { + varbinder::BoundContext bctx {varBinder->GetUsedRecordTable(), calleeClass->Definition(), true}; + } varBinder->ResolveReferencesForScopeWithContext(func, funcScope); auto checkerCtx = checker::SavedCheckerContext(ctx->GetChecker(), checker::CheckerStatus::IN_CLASS, diff --git a/ets2panda/compiler/lowering/ets/unionLowering.cpp b/ets2panda/compiler/lowering/ets/unionLowering.cpp index ecbedb0619bc957337ddc2ba387c27652a6d1911..ba30320f2542f0bc422b2f4518a127406b628854 100644 --- a/ets2panda/compiler/lowering/ets/unionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unionLowering.cpp @@ -120,6 +120,9 @@ static std::tuple CreateNamedA auto clsCtx = varbinder::LexicalScope::Enter(varbinder, accessClass->Scope()->AsClassScope()); auto boundCtx = varbinder::BoundContext(varbinder->AsETSBinder()->GetRecordTable(), accessClass, true); + if (!varbinder->Program()->IsExternal()) { + auto boundCtx = varbinder::BoundContext(varbinder->AsETSBinder()->GetRecordTable(), accessClass, true); + } CheckLoweredNode(varbinder->AsETSBinder(), checker, method); } diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 36001a7946a083e80444d63fcd2b0a9da50d1cb3..c48f83864be63280c6c36a468327d75e482f3ed4 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -223,6 +223,7 @@ void ETSParser::AddExternalSource(const std::vector &programs) } } if (!found) { + newProg->SetExternal(true); extSources.at(name).emplace_back(newProg); } } diff --git a/ets2panda/parser/program/program.cpp b/ets2panda/parser/program/program.cpp index 572ce976dc019b2b7e56d904c9303874ed1e8ce9..d0eb493068af4c882b4161e5921d3350418b7b60 100644 --- a/ets2panda/parser/program/program.cpp +++ b/ets2panda/parser/program/program.cpp @@ -221,6 +221,9 @@ bool Program::MergeExternalSource(const ExternalSource *externalSource) } for (const auto &[moduleName, extProgs] : *externalSource) { + for (auto &prog : extProgs) { + prog->SetExternal(true); + } externalSources_.emplace(moduleName, extProgs); } diff --git a/ets2panda/parser/program/program.h b/ets2panda/parser/program/program.h index c29543942cadcf88358a2ac9db0e08e8f34a4169..66ad71e884e68e2aa14582581ae39550f5beab9a 100644 --- a/ets2panda/parser/program/program.h +++ b/ets2panda/parser/program/program.h @@ -298,6 +298,14 @@ public: (FileName().Is("etsstdlib")); } + void SetExternal(bool flag) { + isExternal_ = true; + } + + bool IsExternal() { + return isExternal_; + } + varbinder::ClassScope *GlobalClassScope(); const varbinder::ClassScope *GlobalClassScope() const; @@ -391,6 +399,7 @@ private: std::vector> declGenExportNodes_; ArenaVector functionScopes_; std::unordered_map> fileDependencies_; + bool isExternal_ {false}; private: ArenaMap varbinders_; diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index f2983e06ca9e44054da91bbb320072f9c10867b8..d55f288b2c16631e2992399e6796c3e45ba82c55 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -343,6 +343,9 @@ void ETSBinder::ResolveEnumDeclaration(ir::TSEnumDeclaration *enumDecl) void ETSBinder::ResolveInterfaceDeclaration(ir::TSInterfaceDeclaration *decl) { auto boundCtx = BoundContext(recordTable_, decl); + if (!Program()->IsExternal()) { + auto boundCtx1 = BoundContext(&usedRecordTable_, decl); + } for (auto *extend : decl->Extends()) { ResolveReference(extend); @@ -399,6 +402,9 @@ void ETSBinder::BuildMethodDefinition(ir::MethodDefinition *methodDef) void ETSBinder::BuildAnnotationDeclaration(ir::AnnotationDeclaration *annoDecl) { auto boundCtx = BoundContext(recordTable_, annoDecl); + if (!Program()->IsExternal()) { + auto boundCtx1 = BoundContext(&usedRecordTable_, annoDecl); + } if (annoDecl->Expr()->IsIdentifier()) { LookupTypeReference(annoDecl->AsAnnotationDeclaration()->Expr()->AsIdentifier(), false); } else { @@ -461,6 +467,9 @@ void ETSBinder::BuildMemberExpression(ir::MemberExpression *memberExpr) void ETSBinder::BuildClassDefinition(ir::ClassDefinition *classDef) { auto boundCtx = BoundContext(recordTable_, classDef); + if (!Program()->IsExternal()) { + auto boundCtx1 = BoundContext(&usedRecordTable_, classDef); + } if (classDef->TypeParams() != nullptr) { auto scopeCtx = LexicalScope::Enter(this, classDef->TypeParams()->Scope()); diff --git a/ets2panda/varbinder/ETSBinder.h b/ets2panda/varbinder/ETSBinder.h index 140596eccdc48348626616e97dcf9b436d0b61b9..846df088e030446e37ab16ebb918fc6d52a29e4a 100644 --- a/ets2panda/varbinder/ETSBinder.h +++ b/ets2panda/varbinder/ETSBinder.h @@ -60,6 +60,7 @@ public: : TypedBinder(allocator), globalRecordTable_(allocator, Program(), RecordTableFlags::NONE), recordTable_(&globalRecordTable_), + usedRecordTable_(allocator, Program(), RecordTableFlags::NONE), externalRecordTable_(Allocator()->Adapter()), defaultImports_(Allocator()->Adapter()), dynamicImports_(Allocator()->Adapter()), @@ -111,6 +112,16 @@ public: return &globalRecordTable_; } + [[nodiscard]] RecordTable *GetUsedRecordTable() noexcept + { + return &usedRecordTable_; + } + + [[nodiscard]] const RecordTable *GetUsedRecordTable() const noexcept + { + return &usedRecordTable_; + } + [[nodiscard]] ArenaMap &GetExternalRecordTable() noexcept { return externalRecordTable_; @@ -276,6 +287,7 @@ public: dynamicImportVars_.clear(); defaultExport_ = nullptr; globalRecordTable_.CleanUp(); + usedRecordTable_.Clean(); } void CopyTo(VarBinder *target) override @@ -309,6 +321,7 @@ private: RecordTable globalRecordTable_; RecordTable *recordTable_; + usedRecordTable_; ArenaMap externalRecordTable_; ArenaVector defaultImports_; // 1 ArenaVector dynamicImports_;