From 1d69f9bb3174572e134762c1c78e34de85d71291 Mon Sep 17 00:00:00 2001 From: Yuwei Chen <3220103689@zju.edu.cn> Date: Mon, 21 Jul 2025 16:58:26 +0800 Subject: [PATCH] Generate declarations of indirect dependencies Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICN7W7 Signed-off-by: Yuwei Chen <3220103689@zju.edu.cn> Change-Id: I2c86a848a11781c3dd799d72e0d2c317ea8575e1 --- ets2panda/declgen_ets2ts/declgenEts2Ts.cpp | 98 ++++++++++++++----- ets2panda/declgen_ets2ts/declgenEts2Ts.h | 5 + .../declgen-ets2ts-runtime-ignored.txt | 3 +- 3 files changed, 82 insertions(+), 24 deletions(-) diff --git a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp index bb3dcc37c3..715dffe4a8 100644 --- a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp +++ b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp @@ -32,6 +32,7 @@ #include "ir/ts/tsInterfaceBody.h" #include "ir/ts/tsTypeAliasDeclaration.h" #include "ir/ts/tsTypeParameter.h" +#include "compiler/lowering/util.h" #define DEBUG_PRINT 0 @@ -143,6 +144,8 @@ void TSDeclGen::CollectIndirectExportDependencies() ProcessTypeAliasDependencies(stmt->AsTSTypeAliasDeclaration()); } else if (stmt->IsClassDeclaration()) { ProcessClassDependencies(stmt->AsClassDeclaration()); + } else if (stmt->IsTSInterfaceDeclaration()) { + ProcessInterfaceDependencies(stmt->AsTSInterfaceDeclaration()); } } } @@ -211,11 +214,12 @@ void TSDeclGen::ProcessClassDependencies(const ir::ClassDeclaration *classDecl) if (!classDef->IsExported() && !classDef->IsDefaultExported()) { return; } - state_.super = classDef->Super(); + state_.super = classDef->Super(); if (state_.super != nullptr) { AddSuperType(state_.super); } + if (classDef->TsType() != nullptr && classDef->TsType()->IsETSObjectType()) { ProcessInterfacesDependencies(classDef->TsType()->AsETSObjectType()->Interfaces()); } @@ -275,16 +279,63 @@ void TSDeclGen::ProcessClassMethodDependencies(const ir::MethodDefinition *metho AddSuperType(sig->ReturnType()); } +void TSDeclGen::ProcessInterfaceDependencies(const ir::TSInterfaceDeclaration *interfaceDecl) +{ + if (interfaceDecl->Id()->Name().Mutf8().find('#') != std::string::npos) { + return; + } + + if (!interfaceDecl->IsExported() && !interfaceDecl->IsExportedType()) { + return; + } + + if (interfaceDecl->TsType() != nullptr && interfaceDecl->TsType()->IsETSObjectType()) { + ProcessInterfacesDependencies(interfaceDecl->TsType()->AsETSObjectType()->Interfaces()); + } + + if (interfaceDecl->TypeParams() != nullptr) { + GenSeparated( + interfaceDecl->TypeParams()->Params(), + [this](ir::TSTypeParameter *param) { + if (param->Constraint() == nullptr) { + return; + } + AddSuperType(param->Constraint()); + }, + ""); + } + + ProcessInterfacePropDependencies(interfaceDecl); +} + +void TSDeclGen::ProcessInterfacePropDependencies(const ir::TSInterfaceDeclaration *interfaceDecl) +{ + for (const auto *prop : interfaceDecl->Body()->Body()) { + if (prop->IsMethodDefinition()) { + ProcessInterfaceMethodDependencies(prop->AsMethodDefinition()); + } + } +} + +void TSDeclGen::ProcessInterfaceMethodDependencies(const ir::MethodDefinition *methodDef) +{ + auto methDefFunc = methodDef->Function(); + if (methDefFunc == nullptr) { + return; + } + auto sig = methDefFunc->Signature(); + GenSeparated( + sig->Params(), [this](varbinder::LocalVariable *param) { AddSuperType(param->TsType()); }, ""); + + AddSuperType(sig->ReturnType()); +} + void TSDeclGen::AddSuperType(const ir::Expression *super) { if (super->TsType() == nullptr) { return; } - const auto superType = checker::ETSChecker::ETSType(super->TsType()); - if (superType == checker::TypeFlag::ETS_OBJECT) { - auto objectType = super->TsType()->AsETSObjectType(); - AddObjectDependencies(objectType->Name()); - } + AddSuperType(super->TsType()); } void TSDeclGen::AddSuperType(const checker::Type *tsType) @@ -293,6 +344,11 @@ void TSDeclGen::AddSuperType(const checker::Type *tsType) if (superType == checker::TypeFlag::ETS_OBJECT) { auto objectType = tsType->AsETSObjectType(); AddObjectDependencies(objectType->Name()); + } else if (superType == checker::TypeFlag::ETS_UNION) { + auto unionType = tsType->AsETSUnionType(); + std::vector filteredTypes = FilterUnionTypes(unionType->ConstituentTypes()); + GenSeparated( + filteredTypes, [this](checker::Type *type) { AddSuperType(type); }, ""); } } @@ -325,7 +381,10 @@ void TSDeclGen::GenDeclarations() for (auto *globalStatement : program_->Ast()->Statements()) { ResetState(); ResetClassNode(); - if (globalStatement->IsClassDeclaration()) { + const auto jsdoc = compiler::JsdocStringFromDeclaration(globalStatement); + if (jsdoc.Utf8().find(NON_INTEROP_FLAG) != std::string_view::npos) { + continue; + } else if (globalStatement->IsClassDeclaration()) { GenClassDeclaration(globalStatement->AsClassDeclaration()); } else if (globalStatement->IsTSInterfaceDeclaration()) { GenInterfaceDeclaration(globalStatement->AsTSInterfaceDeclaration()); @@ -436,14 +495,6 @@ void TSDeclGen::GenType(const checker::Type *checkerType) if (HandleBasicTypes(checkerType)) { return; } - if (checkerType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { - OutDts("number"); - return; - } - if (checkerType->IsETSStringEnumType()) { - OutDts("string"); - return; - } if (checkerType->IsETSFunctionType()) { HandleFunctionType(checkerType); @@ -1804,8 +1855,6 @@ void TSDeclGen::ProcessInterfaceBody(const ir::TSInterfaceBody *body) for (auto *prop : body->Body()) { if (prop->IsMethodDefinition()) { ProcessInterfaceMethodDefinition(prop->AsMethodDefinition()); - } else if (prop->IsClassProperty()) { - GenPropDeclaration(prop->AsClassProperty()); } } } @@ -2012,14 +2061,14 @@ void TSDeclGen::HandleClassDeclarationTypeInfo(const ir::ClassDefinition *classD HandleClassInherit(super); } - if (classDef->TsType() != nullptr && classDef->TsType()->IsETSObjectType() && - !classDef->TsType()->AsETSObjectType()->Interfaces().empty()) { + if (!classDef->Implements().empty()) { + OutDts(" implements "); + GenSeparated(classDef->Implements(), [this](ir::TSClassImplements *impl) { HandleClassInherit(impl->Expr()); }); + } else if (classDef->TsType() != nullptr && classDef->TsType()->IsETSObjectType() && + !classDef->TsType()->AsETSObjectType()->Interfaces().empty()) { OutDts(" implements "); const auto &interfaces = classDef->TsType()->AsETSObjectType()->Interfaces(); GenSeparated(interfaces, [this](checker::ETSObjectType *interface) { GenType(interface); }); - } else if (!classDef->Implements().empty()) { - OutDts(" implements "); - GenSeparated(classDef->Implements(), [this](ir::TSClassImplements *impl) { HandleClassInherit(impl->Expr()); }); } OutDts(" {"); @@ -2077,7 +2126,10 @@ void TSDeclGen::ProcessClassBody(const ir::ClassDefinition *classDef) state_.inClass = true; std::unordered_set processedMethods; for (const auto *prop : classDef->Body()) { - if (classDef->IsEnumTransformed()) { + const auto jsdoc = compiler::JsdocStringFromDeclaration(prop); + if (jsdoc.Utf8().find(NON_INTEROP_FLAG) != std::string_view::npos) { + continue; + } else if (classDef->IsEnumTransformed()) { if (prop->IsClassProperty()) { state_.inEnum = true; GenPropDeclaration(prop->AsClassProperty()); diff --git a/ets2panda/declgen_ets2ts/declgenEts2Ts.h b/ets2panda/declgen_ets2ts/declgenEts2Ts.h index fbe26acd05..d46a4c7661 100644 --- a/ets2panda/declgen_ets2ts/declgenEts2Ts.h +++ b/ets2panda/declgen_ets2ts/declgenEts2Ts.h @@ -27,6 +27,8 @@ namespace ark::es2panda::declgen_ets2ts { +constexpr const char *NON_INTEROP_FLAG = "@noninterop"; + struct DeclgenOptions { bool exportAll = false; bool isolated = false; @@ -219,6 +221,9 @@ private: void ProcessClassDependencies(const ir::ClassDeclaration *classDecl); void ProcessClassPropDependencies(const ir::ClassDefinition *classDef); void ProcessClassMethodDependencies(const ir::MethodDefinition *methodDef); + void ProcessInterfaceDependencies(const ir::TSInterfaceDeclaration *interfaceDecl); + void ProcessInterfacePropDependencies(const ir::TSInterfaceDeclaration *interfaceDecl); + void ProcessInterfaceMethodDependencies(const ir::MethodDefinition *methodDef); void ProcessETSTypeReferenceDependencies(const ir::ETSTypeReference *typeReference); void AddSuperType(const ir::Expression *super); void AddSuperType(const checker::Type *tsType); diff --git a/ets2panda/test/test-lists/declgenets2ts/ets-runtime/declgen-ets2ts-runtime-ignored.txt b/ets2panda/test/test-lists/declgenets2ts/ets-runtime/declgen-ets2ts-runtime-ignored.txt index 0bbbfcb47a..e708505448 100644 --- a/ets2panda/test/test-lists/declgenets2ts/ets-runtime/declgen-ets2ts-runtime-ignored.txt +++ b/ets2panda/test/test-lists/declgenets2ts/ets-runtime/declgen-ets2ts-runtime-ignored.txt @@ -2,8 +2,9 @@ lambda_with_receiver/lambda_with_receiver_generics_return_this.ets first_match/ctor_need_fix_bytecode.ets overload_declaration/constructor_overload_sig_with_ref_type.ets -#FailKind.ABORT_FAIL - 1 tests: +#FailKind.ABORT_FAIL - 2 tests: type_param_in_union.ets +mypackage/implicit_package_import_2.ets #FailKind.TSC_FAIL - 21 tests: ClassNewInstance.ets Enum7.ets -- Gitee