From 79695ddbf87c50968234414d84c1deb9af71c717 Mon Sep 17 00:00:00 2001 From: gou-jingjing Date: Wed, 25 Jun 2025 10:53:12 +0800 Subject: [PATCH] gencpp support callback,promise Signed-off-by: gou-jingjing --- src/vscode_plugin/src/gen/tools/gennapicpp.ts | 61 ++++++++++++++--- src/vscode_plugin/src/gen/tools/gennapih.ts | 8 ++- .../src/gen/tools/gennapiinit.ts | 4 ++ .../src/template/func_template.ts | 67 +++++++++++++++++-- 4 files changed, 122 insertions(+), 18 deletions(-) diff --git a/src/vscode_plugin/src/gen/tools/gennapicpp.ts b/src/vscode_plugin/src/gen/tools/gennapicpp.ts index 9dc09cf7..36d43c5d 100644 --- a/src/vscode_plugin/src/gen/tools/gennapicpp.ts +++ b/src/vscode_plugin/src/gen/tools/gennapicpp.ts @@ -16,7 +16,7 @@ import { FuncObj, GenInfo, ParamObj } from "../datatype"; import { classMethodGetParamTemplate, classMethodNoParamTemplate, classMethodTemplate, classPropertyGetTemplate, classPropertySetTemplate, classTemplate, funcGetParamTemplate, napiFuncCppTemplate, napiFuncRetTemplate, - paramGenTemplate } from "../../template/func_template"; + paramGenTemplate, napiFuncCallbackTemplate, napiAsyncFuncRet } from "../../template/func_template"; import { replaceAll } from "../../common/tool"; import * as path from 'path'; import * as fs from 'fs'; @@ -97,7 +97,7 @@ export function getCppParamGen(funcInfo: FuncObj): string { let getParamInTemplate = transCkey2NapiInkey(funcInfo.parameters[i].type); // 如果getParamInTemplate是空,则默认是对象输入,不做任何处理 if (getParamInTemplate === '') { - paramGenResult += '// Todo: handle object input.\n'; + paramGenResult += ' // Todo: handle object input.\n'; continue; } let getParam = replaceAll(getParamInTemplate, '[param_index_replace]', @@ -113,8 +113,6 @@ export function getCppParamGen(funcInfo: FuncObj): string { } let genParamReplace = replaceAll(funcGetParamTemplate, '[param_length]', 'PARAMS' + funcInfo.parameters.length); - genParamReplace = replaceAll(genParamReplace, '[func_name_replace]', - funcInfo.name); genParamReplace = replaceAll(genParamReplace, '[getAllParam_replace]', paramGenResult); return genParamReplace @@ -208,11 +206,7 @@ export function doGenNapiCppFile(rootInfo: GenInfo, fileContent: string) { rootInfo.parseObj.funcs.forEach(funcInfo => { // 替换每个方法主体 let hFileName = path.basename(rootInfo.rawFilePath); - let bodyReplace = replaceAll(napiFuncCppTemplate, '[func_name_replace]', - funcInfo.name); - bodyReplace = replaceAll(bodyReplace, '[get_error_msg_tag]', - funcInfo.name); - bodyReplace = replaceAll(bodyReplace, '[file_introduce_replace]', + let bodyReplace = replaceAll(napiFuncCppTemplate, '[file_introduce_replace]', hFileName); // 生成方法注释 let funcInfoParams = funcInfo.parameters.length > 0 ? '' : 'void'; @@ -232,12 +226,57 @@ export function doGenNapiCppFile(rootInfo: GenInfo, fileContent: string) { let paramGenResult = getCppParamGen(funcInfo); bodyReplace = replaceAll(bodyReplace, '[func_getParam_replace]', paramGenResult); + + // 同步方法生成 + let syncBodyReplace = replaceAll(bodyReplace, '[func_name_replace]', + funcInfo.name); // 方法返回值的处理,解析返回值类型,生成napi的返回值处理代码 let returnGenResult = genCppReturnGen(funcInfo); - bodyReplace = replaceAll(bodyReplace, '[func_return_replace]', + syncBodyReplace = replaceAll(syncBodyReplace, '[func_return_replace]', returnGenResult); // 组合一个个方法 - napiCppContent += bodyReplace; + napiCppContent += syncBodyReplace; + + // callback方法生成 + let asyncFuncName = funcInfo.name + 'Async'; + let callbackBodyReplace = replaceAll(bodyReplace, '[func_name_replace]', + asyncFuncName); + let asyncReturnReplace = replaceAll(napiFuncRetTemplate, '[return_replace]', + napiAsyncFuncRet); + asyncReturnReplace = replaceAll(asyncReturnReplace, '[func_name_replace]', + asyncFuncName); + asyncReturnReplace = replaceAll(asyncReturnReplace, '[return_name]', + asyncFuncName); + callbackBodyReplace = replaceAll(callbackBodyReplace, '[func_return_replace]', + asyncReturnReplace); + let asyncWorkContent = replaceAll(napiFuncCallbackTemplate, '[func_name_replace]', + asyncFuncName); + let funcParamDeclare = '[paramType_replace] [paramName_replace];' + let funcParamDeclareList = ''; + for (let i = 0; i < funcInfo.parameters.length; i++) { + let tempParamDeclare = replaceAll(funcParamDeclare, '[paramType_replace]', funcInfo.parameters[i].type); + tempParamDeclare = replaceAll(tempParamDeclare, '[paramName_replace]', funcInfo.parameters[i].name); + if (i !== funcInfo.parameters.length - 1) { + funcParamDeclareList += tempParamDeclare + '\n '; + } else { + funcParamDeclareList += tempParamDeclare; + } + } + asyncWorkContent = replaceAll(asyncWorkContent, '[func_param_declare]', funcParamDeclareList); + asyncWorkContent = replaceAll(asyncWorkContent, '[async_func_replace]', callbackBodyReplace); + napiCppContent += asyncWorkContent; + + // promise方法生成 + let promiseFuncName = funcInfo.name + 'Promise'; + let promiseBodyReplace = replaceAll(bodyReplace, '[func_name_replace]', + promiseFuncName); + promiseBodyReplace = replaceAll(promiseBodyReplace, '[func_name_replace]', + promiseFuncName); + promiseBodyReplace = replaceAll(promiseBodyReplace, '[return_name]', + promiseFuncName); + promiseBodyReplace = replaceAll(promiseBodyReplace, '[func_return_replace]', + asyncReturnReplace); + napiCppContent += promiseBodyReplace; }); } diff --git a/src/vscode_plugin/src/gen/tools/gennapih.ts b/src/vscode_plugin/src/gen/tools/gennapih.ts index 769143a4..ffce69a9 100644 --- a/src/vscode_plugin/src/gen/tools/gennapih.ts +++ b/src/vscode_plugin/src/gen/tools/gennapih.ts @@ -76,11 +76,15 @@ export function doGenNapiHFile(rootInfo: GenInfo, fileContent: string) { let rawFileName = path.basename(rootInfo.rawFilePath); let hContent = replaceAll(napiFuncHTemplate, '[file_introduce_replace]', rawFileName); hContent = replaceAll(hContent, '[input_introduce_replace]', funcParams === '' ? 'void' : funcParams); - hContent = replaceAll(hContent, '[func_name_replace]', func.name); hContent = replaceAll(hContent, '[func_param_replace]', funcParams); hContent = replaceAll(hContent, '[func_return_replace]', func.returns === '' ? 'void' : func.returns); - napiHContent += hContent; + let syncFunc = replaceAll(hContent, '[func_name_replace]', func.name); + let asyncCallbackFunc = replaceAll(hContent, '[func_name_replace]', func.name + 'Async'); + let asyncPromiseFunc = replaceAll(hContent, '[func_name_replace]', func.name + 'Promise'); + napiHContent += syncFunc; + napiHContent += asyncCallbackFunc; + napiHContent += asyncPromiseFunc; }); } let upperFileName = rootInfo.fileName.toLocaleUpperCase(); diff --git a/src/vscode_plugin/src/gen/tools/gennapiinit.ts b/src/vscode_plugin/src/gen/tools/gennapiinit.ts index 2e4581b3..3ac7314c 100644 --- a/src/vscode_plugin/src/gen/tools/gennapiinit.ts +++ b/src/vscode_plugin/src/gen/tools/gennapiinit.ts @@ -61,6 +61,10 @@ export function doGenNapiInitFile(rootInfo: GenInfo, fileContent: string) { let funcName = func.name; napiInitContent += replaceAll(napiFuncInitTemplate, '[func_name_replace]', funcName); + napiInitContent += replaceAll(napiFuncInitTemplate, + '[func_name_replace]', funcName + 'Async'); + napiInitContent += replaceAll(napiFuncInitTemplate, + '[func_name_replace]', funcName + 'Promise'); }); } // 写文件 diff --git a/src/vscode_plugin/src/template/func_template.ts b/src/vscode_plugin/src/template/func_template.ts index f516d5ac..695c2803 100644 --- a/src/vscode_plugin/src/template/func_template.ts +++ b/src/vscode_plugin/src/template/func_template.ts @@ -97,25 +97,82 @@ napi_value [func_name_replace](napi_env env, napi_callback_info info) */ const napi_extended_error_info *extended_error_info; /* [NAPI_GEN]: tag: 日志打印标签*/ - const char *tag = "[[get_error_msg_tag]]"; + const char *tag = "[[func_name_replace]]"; /* [NAPI_GEN]: get function param in*/ [func_getParam_replace] + // Todo: 调用原始类方法 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[func_name_replace]", "[func_name_replace] get return info begins"); [func_return_replace] } `; -// napi方法返回值处理 -export let napiFuncRetTemplate = ` // Todo: add business logic. 在这前后代码为框架所生成 +// napi callback方法 +export let napiFuncCallbackTemplate = ` +struct [func_name_replace]AsyncData { + napi_async_work work;// 异步工作句柄 + napi_deferred deferred;// Promise句柄(如果使用Promise) + napi_ref callback_ref;// JS回调引用 + [func_param_declare] + void result;// 返回值 + napi_status status;// 执行状态 +}; + +// 实际执行计算的线程池任务 +void [func_name_replace]AsyncExecuteWork(napi_env env, void* data) { + [func_name_replace]AsyncData* async_data = static_cast<[func_name_replace]AsyncData*>(data); + // Todo:调用原始类方法 + + async_data->result = res; // 实际计算 +} + +// 计算结果返回给JS事件循环 +void [func_name_replace]AsyncCompleteWork(napi_env env, napi_status status, void* data) { + [func_name_replace]AsyncData* async_data = static_cast<[func_name_replace]AsyncData*>(data); + + // 准备回调参数 + napi_value argv[2] = { nullptr }; + if (async_data->status == napi_ok) { + napi_get_null(env, &argv[0]); + } else { + napi_value error_msg; + napi_create_string_utf8(env, "[func_name_replace]Async failed", NAPI_AUTO_LENGTH, &error_msg); + napi_create_error(env, NULL, error_msg, &argv[1]); + napi_get_null(env, &argv[0]); + } + + // 获取JS回调函数 + napi_value callback; + napi_get_reference_value(env, async_data->callback_ref, &callback); + + // 调用回调 + napi_value global; + napi_get_global(env, &global); + napi_call_function(env, global, callback, 2, argv, nullptr); + + // 清理资源 + napi_delete_async_work(env, async_data->work); + napi_delete_reference(env, async_data->callback_ref); + delete async_data; +}; + +[async_func_replace] +`; - /* [NAPI_GEN]: function return value*/ +// napi方法返回值处理 +export let napiFuncRetTemplate = ` [return_replace] OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[func_name_replace]", "[func_name_replace] get return info ends"); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "[func_name_replace]", "[func_name_replace] ends"); return [return_name]Out; `; +export let napiAsyncFuncRet = ` + napi_value [return_name]Out = nullptr; + napi_get_undefined(env, &[return_name]Out); + // Todo: 创建返回参数 +` + // napi方法返回值各种类型模板 export let uint32tRet = ` napi_value [return_name_replace]Out; /* [NAPI_GEN]: 返回值是uint32_t类型时,napi_create_uint32创建一个包含32位无符号整数(uint32_t)的js数值对象 @@ -529,7 +586,7 @@ export let classMethodTemplate = ` napi_value [class_name_replace]::[class_method_name_replace](napi_env env, napi_callback_info info) { [class_method_param_in] - // Todo: business logic here. + // Todo: 调用原始类方法. [class_name_replace]* obj; // 通过napi_unwrap将jsThis之前绑定的C++对象取出,并对其进行操作 napi_unwrap(env, jsThis, reinterpret_cast(&obj)); -- Gitee