From 7a6ff291ab4a556b1050366a4aa261195420c07e Mon Sep 17 00:00:00 2001 From: dongchao Date: Mon, 7 Jul 2025 17:16:51 +0800 Subject: [PATCH] Achieve record scene in declgen_ets2ts Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICB1LU Signed-off-by: dongchao Change-Id: Ibf08d204b511bb4ec99206187b44a5e6b42c299e --- ets2panda/bindings/native/src/bridges.cpp | 7 ++-- .../src/common/Es2pandaNativeModule.ts | 3 +- .../bindings/src/common/driver_helper.ts | 4 +-- ets2panda/bindings/src/lsp/lsp_helper.ts | 4 +-- ets2panda/declgen_ets2ts/declgenEts2Ts.cpp | 29 ++++++++-------- ets2panda/declgen_ets2ts/declgenEts2Ts.h | 3 +- .../build_system/src/build/base_mode.ts | 23 +++++++++++-- .../build_system/src/build/declgen_worker.ts | 33 +++++++++++++++---- .../driver/build_system/src/pre_define.ts | 10 +++++- ets2panda/driver/build_system/src/utils.ts | 19 +++++++++++ ets2panda/public/es2panda_lib.cpp | 3 +- ets2panda/public/es2panda_lib.h | 3 +- ets2panda/scripts/arkui.properties | 2 +- .../declgen/test_ets2ts_isolated_declgen.cpp | 2 +- 14 files changed, 107 insertions(+), 38 deletions(-) diff --git a/ets2panda/bindings/native/src/bridges.cpp b/ets2panda/bindings/native/src/bridges.cpp index 1fd2af18dd..d318f98161 100644 --- a/ets2panda/bindings/native/src/bridges.cpp +++ b/ets2panda/bindings/native/src/bridges.cpp @@ -45,13 +45,14 @@ KNativePointer impl_CreateContextFromStringWithHistory(KNativePointer configPtr, TS_INTEROP_3(CreateContextFromStringWithHistory, KNativePointer, KNativePointer, KStringPtr, KStringPtr) KInt impl_GenerateTsDeclarationsFromContext(KNativePointer contextPtr, KStringPtr &outputDeclEts, KStringPtr &outputEts, - KBoolean exportAll, KBoolean isolated) + KBoolean exportAll, KBoolean isolated, KStringPtr &recordFile) { auto context = reinterpret_cast(contextPtr); return static_cast(GetPublicImpl()->GenerateTsDeclarationsFromContext( - context, outputDeclEts.data(), outputEts.data(), exportAll != 0, isolated != 0)); + context, outputDeclEts.data(), outputEts.data(), exportAll != 0, isolated != 0, recordFile.data())); } -TS_INTEROP_5(GenerateTsDeclarationsFromContext, KInt, KNativePointer, KStringPtr, KStringPtr, KBoolean, KBoolean) +TS_INTEROP_6(GenerateTsDeclarationsFromContext, KInt, KNativePointer, KStringPtr, KStringPtr, KBoolean, KBoolean, + KStringPtr) KNativePointer impl_CreateContextFromFile(KNativePointer configPtr, KStringPtr &filenamePtr) { diff --git a/ets2panda/bindings/src/common/Es2pandaNativeModule.ts b/ets2panda/bindings/src/common/Es2pandaNativeModule.ts index 823bb00b08..8d04990823 100644 --- a/ets2panda/bindings/src/common/Es2pandaNativeModule.ts +++ b/ets2panda/bindings/src/common/Es2pandaNativeModule.ts @@ -82,7 +82,8 @@ export class Es2pandaNativeModule { outputDeclEts: String, outputEts: String, exportAll: KBoolean, - isolated: KBoolean + isolated: KBoolean, + recordFile: String ): KPtr { throw new Error('Not implemented'); } diff --git a/ets2panda/bindings/src/common/driver_helper.ts b/ets2panda/bindings/src/common/driver_helper.ts index 4bd68da844..18809ce736 100644 --- a/ets2panda/bindings/src/common/driver_helper.ts +++ b/ets2panda/bindings/src/common/driver_helper.ts @@ -77,10 +77,10 @@ export class DriverHelper { global.destroyCfg(); } - public generateTsDecl(declOutPath: string, etsOutPath: string, exportAll: boolean, isolated: boolean): void { + public generateTsDecl(declOutPath: string, etsOutPath: string, exportAll: boolean, isolated: boolean, recordFile: string): void { let exportAll_: KBoolean = exportAll ? 1 : 0; let isolated_: KBoolean = isolated ? 1 : 0; - global.es2panda._GenerateTsDeclarationsFromContext(this._cfg.peer, declOutPath, etsOutPath, exportAll_, isolated_); + global.es2panda._GenerateTsDeclarationsFromContext(this._cfg.peer, declOutPath, etsOutPath, exportAll_, isolated_, recordFile); } } diff --git a/ets2panda/bindings/src/lsp/lsp_helper.ts b/ets2panda/bindings/src/lsp/lsp_helper.ts index 3b8999ce90..aa72ccb120 100644 --- a/ets2panda/bindings/src/lsp/lsp_helper.ts +++ b/ets2panda/bindings/src/lsp/lsp_helper.ts @@ -232,7 +232,7 @@ export class Lsp { ); ensurePathExists(declEtsOutputPath); ensurePathExists(etsOutputPath); - global.es2pandaPublic._GenerateTsDeclarationsFromContext(ctx, declEtsOutputPath, etsOutputPath, 1, 0); + global.es2pandaPublic._GenerateTsDeclarationsFromContext(ctx, declEtsOutputPath, etsOutputPath, 1, 0, ''); } finally { this.destroyContext(cfg, ctx); } @@ -297,7 +297,7 @@ export class Lsp { ); ensurePathExists(declEtsOutputPath); ensurePathExists(etsOutputPath); - global.es2pandaPublic._GenerateTsDeclarationsFromContext(ctx, declEtsOutputPath, etsOutputPath, 1, 0); + global.es2pandaPublic._GenerateTsDeclarationsFromContext(ctx, declEtsOutputPath, etsOutputPath, 1, 0, ''); } finally { this.destroyContext(cfg, ctx); } diff --git a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp index bb3dcc37c3..2de024be4c 100644 --- a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp +++ b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp @@ -52,7 +52,6 @@ bool TSDeclGen::Generate() CollectIndirectExportDependencies(); CollectGlueCodeImportSet(); GenDeclarations(); - GenOtherDeclarations(); return true; } @@ -337,20 +336,6 @@ void TSDeclGen::GenDeclarations() } } -void TSDeclGen::GenOtherDeclarations() -{ - const std::string recordKey = "Record"; - const std::string recordStr = R"( -// generated for static Record -type Record = { - [P in K]: T; -}; -)"; - if (indirectDependencyObjects_.find(recordKey) != indirectDependencyObjects_.end()) { - OutDts(recordStr); - } -} - void TSDeclGen::GenExportNamedDeclarations() { for (auto *globalStatement : program_->Ast()->Statements()) { @@ -369,6 +354,13 @@ void TSDeclGen::GenImportDeclarations() } } +void TSDeclGen::GenImportRecordDeclarations(const std::string &source) +{ + if (importSet_.find("Record") != importSet_.end()) { + OutDts("import type { Record } from \"", source, "\";\n"); + } +} + template void TSDeclGen::GenSeparated(const T &container, const CB &cb, const char *separator, bool isReExport, bool isDtsExport) { @@ -2526,6 +2518,13 @@ bool GenerateTsDeclarations(checker::ETSChecker *checker, const ark::es2panda::p std::string combineEts = importOutputEts + outputEts + exportOutputEts; std::string combinedDEts = importOutputDEts + outputDEts + exportOutputDEts; + if (!declBuilder.GetDeclgenOptions().recordFile.empty()) { + declBuilder.ResetDtsOutput(); + declBuilder.GenImportRecordDeclarations(declBuilder.GetDeclgenOptions().recordFile); + std::string recordImportOutputDEts = declBuilder.GetDtsOutput(); + combinedDEts = recordImportOutputDEts + combinedDEts; + } + return WriteOutputFiles(declBuilder.GetDeclgenOptions(), combineEts, combinedDEts, checker); } diff --git a/ets2panda/declgen_ets2ts/declgenEts2Ts.h b/ets2panda/declgen_ets2ts/declgenEts2Ts.h index fbe26acd05..f8b49dce99 100644 --- a/ets2panda/declgen_ets2ts/declgenEts2Ts.h +++ b/ets2panda/declgen_ets2ts/declgenEts2Ts.h @@ -32,6 +32,7 @@ struct DeclgenOptions { bool isolated = false; std::string outputDeclEts; std::string outputEts; + std::string recordFile; }; // Consume program after checker stage and generate out_path typescript file with declarations @@ -72,6 +73,7 @@ public: bool Generate(); void GenImportDeclarations(); void GenExportNamedDeclarations(); + void GenImportRecordDeclarations(const std::string &source); std::string GetDtsOutput() const { @@ -225,7 +227,6 @@ private: void ProcessInterfacesDependencies(const ArenaVector &interfaces); void AddObjectDependencies(const util::StringView &typeName, const std::string &alias = ""); void GenDeclarations(); - void GenOtherDeclarations(); void CloseClassBlock(const bool isDts); void EmitDeclarationPrefix(const ir::ClassDefinition *classDef, const std::string &typeName, diff --git a/ets2panda/driver/build_system/src/build/base_mode.ts b/ets2panda/driver/build_system/src/build/base_mode.ts index c208585be1..22f7b927ff 100644 --- a/ets2panda/driver/build_system/src/build/base_mode.ts +++ b/ets2panda/driver/build_system/src/build/base_mode.ts @@ -30,17 +30,21 @@ import { ARKTSCONFIG_JSON_FILE, DEFAULT_WOKER_NUMS, DECL_ETS_SUFFIX, + DECL_TS_SUFFIX, + DEPENDENCY_INPUT_FILE, DEPENDENCY_JSON_FILE, LANGUAGE_VERSION, LINKER_INPUT_FILE, MERGED_ABC_FILE, - TS_SUFFIX, - DEPENDENCY_INPUT_FILE, MERGED_INTERMEDIATE_FILE, + STATIC_RECORD_FILE, + STATIC_RECORD_FILE_CONTENT, + TS_SUFFIX } from '../pre_define'; import { changeDeclgenFileExtension, changeFileExtension, + createFileIfNotExists, ensurePathExists, getFileHash, isMac @@ -169,6 +173,18 @@ export abstract class BaseMode { const arkts: ArkTS = this.buildConfig.arkts; let errorStatus = false; try { + const staticRecordPath = path.join( + moduleInfo.declgenV1OutPath as string, + STATIC_RECORD_FILE + ) + const declEtsOutputDir = path.dirname(declEtsOutputPath); + const staticRecordRelativePath = changeFileExtension( + path.relative(declEtsOutputDir, staticRecordPath).replaceAll(/\\/g, '\/'), + "", + DECL_TS_SUFFIX + ); + createFileIfNotExists(staticRecordPath, STATIC_RECORD_FILE_CONTENT); + arktsGlobal.filePath = fileInfo.filePath; arktsGlobal.config = arkts.Config.create([ '_', @@ -197,7 +213,8 @@ export abstract class BaseMode { declEtsOutputPath, etsOutputPath, false, - false + false, + staticRecordRelativePath ); // Generate 1.0 declaration files & 1.0 glue code this.logger.printInfo('declaration files generated'); } catch (error) { diff --git a/ets2panda/driver/build_system/src/build/declgen_worker.ts b/ets2panda/driver/build_system/src/build/declgen_worker.ts index 6acecb94e3..e25cdff91d 100644 --- a/ets2panda/driver/build_system/src/build/declgen_worker.ts +++ b/ets2panda/driver/build_system/src/build/declgen_worker.ts @@ -18,11 +18,19 @@ import { BuildConfig } from '../types'; import { Logger } from '../logger'; import * as fs from 'fs'; import * as path from 'path'; -import { changeDeclgenFileExtension, ensurePathExists } from '../utils'; -import { - DECL_ETS_SUFFIX, - TS_SUFFIX, - KOALA_WRAPPER_PATH_FROM_SDK +import { + changeDeclgenFileExtension, + changeFileExtension, + createFileIfNotExists, + ensurePathExists +} from '../utils'; +import { + DECL_ETS_SUFFIX, + DECL_TS_SUFFIX, + KOALA_WRAPPER_PATH_FROM_SDK, + STATIC_RECORD_FILE, + STATIC_RECORD_FILE_CONTENT, + TS_SUFFIX } from '../pre_define'; import { PluginDriver, PluginHook } from '../plugins/plugins_driver'; @@ -67,6 +75,18 @@ process.on('message', (message: { ensurePathExists(declEtsOutputPath); ensurePathExists(etsOutputPath); + const staticRecordPath = path.join( + moduleInfo.declgenV1OutPath as string, + STATIC_RECORD_FILE + ) + const declEtsOutputDir = path.dirname(declEtsOutputPath); + const staticRecordRelativePath = changeFileExtension( + path.relative(declEtsOutputDir, staticRecordPath).replaceAll(/\\/g, '\/'), + "", + DECL_TS_SUFFIX + ); + createFileIfNotExists(staticRecordPath, STATIC_RECORD_FILE_CONTENT); + arktsGlobal.filePath = fileInfo.filePath; arktsGlobal.config = arkts.Config.create([ '_', @@ -96,7 +116,8 @@ process.on('message', (message: { declEtsOutputPath, etsOutputPath, false, - false + false, + staticRecordRelativePath ); // Generate 1.0 declaration files & 1.0 glue code logger.printInfo('declaration files generated'); diff --git a/ets2panda/driver/build_system/src/pre_define.ts b/ets2panda/driver/build_system/src/pre_define.ts index 4b071957de..bb0ef186ed 100644 --- a/ets2panda/driver/build_system/src/pre_define.ts +++ b/ets2panda/driver/build_system/src/pre_define.ts @@ -20,8 +20,10 @@ export const LINKER_INPUT_FILE: string = 'fileInfo.txt'; export const DEPENDENCY_INPUT_FILE: string = 'dependencyFileInfo.txt'; export const DEPENDENCY_JSON_FILE: string = 'dependency.json'; export const PROJECT_BUILD_CONFIG_FILE: string = 'projectionConfig.json'; +export const STATIC_RECORD_FILE: string = 'static.Record.d.ts'; export const DECL_ETS_SUFFIX: string = '.d.ets'; +export const DECL_TS_SUFFIX: string = '.d.ts'; export const ETS_SUFFIX: string = '.ets'; export const TS_SUFFIX: string = '.ts'; export const ABC_SUFFIX: string = '.abc'; @@ -53,4 +55,10 @@ export const API: string = 'api'; export const ARKTS:string = 'arkts'; export const COMPONENT:string = 'component'; -export const DYNAMIC_PREFIX:string = 'dynamic/'; \ No newline at end of file +export const DYNAMIC_PREFIX:string = 'dynamic/'; + +export const STATIC_RECORD_FILE_CONTENT: string = `// generated for static Record +export type Record = { + [P in K]: T; +}; +`; diff --git a/ets2panda/driver/build_system/src/utils.ts b/ets2panda/driver/build_system/src/utils.ts index 3ac40a0f81..e3a7a2bc37 100644 --- a/ets2panda/driver/build_system/src/utils.ts +++ b/ets2panda/driver/build_system/src/utils.ts @@ -182,3 +182,22 @@ export function hasEntry(moduleInfo: ModuleInfo): boolean { return false; } } + +export function createFileIfNotExists(filePath: string, content: string): boolean { + try { + const normalizedPath = path.normalize(filePath); + if (fs.existsSync(normalizedPath)) { + return false; + } + + const dir = path.dirname(normalizedPath); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + + fs.writeFileSync(normalizedPath, content, { encoding: 'utf-8' }); + return true; + } catch (error) { + return false; + } +} diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index dbefcc58ab..f9295c138b 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -1269,7 +1269,7 @@ extern "C" es2panda_AstNode **AllDeclarationsByNameFromProgram([[maybe_unused]] extern "C" __attribute__((unused)) int GenerateTsDeclarationsFromContext(es2panda_Context *ctx, const char *outputDeclEts, const char *outputEts, bool exportAll, - bool isolated) + bool isolated, const char *recordFile) { auto *ctxImpl = reinterpret_cast(ctx); auto *checker = reinterpret_cast(ctxImpl->GetChecker()); @@ -1279,6 +1279,7 @@ extern "C" __attribute__((unused)) int GenerateTsDeclarationsFromContext(es2pand declgenOptions.outputDeclEts = outputDeclEts ? outputDeclEts : ""; declgenOptions.outputEts = outputEts ? outputEts : ""; declgenOptions.isolated = isolated; + declgenOptions.recordFile = recordFile ? recordFile : ""; return ark::es2panda::declgen_ets2ts::GenerateTsDeclarations(checker, ctxImpl->parserProgram, declgenOptions) ? 0 : 1; diff --git a/ets2panda/public/es2panda_lib.h b/ets2panda/public/es2panda_lib.h index d2cb21858e..9455780678 100644 --- a/ets2panda/public/es2panda_lib.h +++ b/ets2panda/public/es2panda_lib.h @@ -272,7 +272,8 @@ struct CAPI_EXPORT es2panda_Impl { const char *name, size_t *declsLen); int (*GenerateTsDeclarationsFromContext)(es2panda_Context *context, const char *outputDeclEts, - const char *outputEts, bool exportAll, bool isolated); + const char *outputEts, bool exportAll, bool isolated, + const char *recordFile); void (*InsertETSImportDeclarationAndParse)(es2panda_Context *context, es2panda_Program *program, es2panda_AstNode *importDeclaration); int (*GenerateStaticDeclarationsFromContext)(es2panda_Context *context, const char *outputPath); diff --git a/ets2panda/scripts/arkui.properties b/ets2panda/scripts/arkui.properties index 6abfd539b7..0f1ace41c5 100644 --- a/ets2panda/scripts/arkui.properties +++ b/ets2panda/scripts/arkui.properties @@ -1,3 +1,3 @@ ARKUI_DEV_REPO=https://gitee.com/rri_opensource/koala_projects.git -ARKUI_DEV_BRANCH=panda_rev_9-ani-reorder-class-bind-static +ARKUI_DEV_BRANCH=panda_rev_9-decl_record_0702 ARKUI_DEST=koala-sig diff --git a/ets2panda/test/unit/declgen/test_ets2ts_isolated_declgen.cpp b/ets2panda/test/unit/declgen/test_ets2ts_isolated_declgen.cpp index 8cb169287b..a2049a3800 100644 --- a/ets2panda/test/unit/declgen/test_ets2ts_isolated_declgen.cpp +++ b/ets2panda/test/unit/declgen/test_ets2ts_isolated_declgen.cpp @@ -49,7 +49,7 @@ int main(int argc, char **argv) impl->ProceedToState(context, ES2PANDA_STATE_CHECKED); CheckForErrors("CHECKED", context); std::string declName = GetDeclPrefix(argv[argc - 1]) + ".d.ets"; - int result = impl->GenerateTsDeclarationsFromContext(context, declName.c_str(), "dump.ets", false, true); + int result = impl->GenerateTsDeclarationsFromContext(context, declName.c_str(), "dump.ets", false, true, ""); if (result != 0) { std::cerr << "FAILED TO GENERATE DECLARATIONS" << std::endl; return result; -- Gitee