From 284af8cb413ee293809f293bb6081b9d490c58d1 Mon Sep 17 00:00:00 2001 From: zhangzhicheng007 Date: Tue, 23 Aug 2022 15:56:58 +0800 Subject: [PATCH] fix issues of void callbak and array Signed-off-by: zhangzhicheng007 --- src/gen/generate.js | 2 +- src/gen/generate/interface.js | 20 +++++--- src/gen/generate/return_generate.js | 52 ++++++++++++++----- src/gen/tools/common.js | 13 ++++- test/storytest/test_callback/@ohos.test.d.ts | 31 +++++++++++ test/storytest/test_callback/test.js | 54 ++++++++++++++++++++ 6 files changed, 149 insertions(+), 23 deletions(-) create mode 100644 test/storytest/test_callback/@ohos.test.d.ts create mode 100644 test/storytest/test_callback/test.js diff --git a/src/gen/generate.js b/src/gen/generate.js index 22c964f5..aead93c7 100644 --- a/src/gen/generate.js +++ b/src/gen/generate.js @@ -69,7 +69,7 @@ let moduleCppTmplete = `\ delete p; \\ } -static napi_value number_c_to_js(XNapiTool *pxt, const std::type_info &n, void *num) +__attribute__((unused)) static napi_value number_c_to_js(XNapiTool *pxt, const std::type_info &n, void *num) { if (n == typeid(int32_t)) return pxt->SwapC2JsInt32(*(int32_t *)num); diff --git a/src/gen/generate/interface.js b/src/gen/generate/interface.js index ea3a205c..b3734042 100644 --- a/src/gen/generate/interface.js +++ b/src/gen/generate/interface.js @@ -15,7 +15,8 @@ const { generateFunctionDirect } = require("./function_direct"); const { generateFunctionSync } = require("./function_sync"); const { generateFunctionAsync } = require("./function_async"); -const { FuncType, InterfaceList, getArrayType, getMapType, EnumList } = require("../tools/common"); +const { FuncType, InterfaceList, getArrayType, getArrayTypeTwo, getMapType, EnumList, jsType2CType } + = require("../tools/common"); const { jsToC } = require("./param_generate"); const { cToJs } = require("./return_generate"); const re = require("../tools/re"); @@ -45,21 +46,24 @@ public: function getHDefineOfVariable(name, type, variable) { if (type == "string") variable.hDefine += "\n std::string %s;".format(name) - else if (type.substring(0, 12) == "NUMBER_TYPE_") variable.hDefine += "\n %s %s;".format(type, name) else if (InterfaceList.getValue(type)) variable.hDefine += "\n %s %s;".format(type, name) else if (EnumList.getValue(type)) variable.hDefine += "\n %s %s;".format(type, name) else if (type.indexOf("Array<") == 0) { - let type2 = getArrayType(type) - if (type2 == "string") type2 = "std::string" - if (type2 == "boolean") type2 = "bool" - variable.hDefine += "\n std::vector<%s> %s;".format(type2, name) + let arrayType = getArrayType(type) + let cType = jsType2CType(arrayType) + variable.hDefine += "\n std::vector<%s> %s;".format(cType, name) } else if (type == "boolean") { variable.hDefine += "\n bool %s;".format(name) - } else if (type.indexOf("[]") == 0) { - variable.hDefine += "\n std::vector<%s> %s;".format(type, name) + } else if (type.substring(type.length - 2) == "[]") { + let arrayType = getArrayTypeTwo(type) + let cType = jsType2CType(arrayType) + variable.hDefine += "\n std::vector<%s> %s;".format(cType, name) } else if (type.substring(0, 4) == "Map<" || type.indexOf("{") == 0) { variable.hDefine += mapTypeString(type, name) } + else if (type.substring(0, 12) == "NUMBER_TYPE_") { + variable.hDefine += "\n %s %s;".format(type, name) + } else { NapiLog.logError(` ---- generateVariable fail %s,%s ---- diff --git a/src/gen/generate/return_generate.js b/src/gen/generate/return_generate.js index 116073d9..99eb2f27 100644 --- a/src/gen/generate/return_generate.js +++ b/src/gen/generate/return_generate.js @@ -65,8 +65,6 @@ function cToJs(value, type, dest, deep = 1) { return "%s = pxt->SwapC2JsBool(%s);".format(dest, value); else if (type == "string") return `%s = pxt->SwapC2JsUtf8(%s.c_str());`.format(dest, value) - else if (type.substring(0, 12) == "NUMBER_TYPE_") - return `%s = NUMBER_C_2_JS(pxt, %s);`.format(dest, value) else if (InterfaceList.getValue(type)) { return cToJsForInterface(value, type, dest, deep); } @@ -88,6 +86,9 @@ function cToJs(value, type, dest, deep = 1) { else if (type.substring(0, 4) == "Map<" || type.indexOf("{") == 0) { return mapTempleteFunc(type, deep, dest, value) } + else if (type.substring(0, 12) == "NUMBER_TYPE_") { + return `%s = NUMBER_C_2_JS(pxt, %s);`.format(dest, value) + } else { NapiLog.logError(`\n---- This type do not generate cToJs %s,%s,%s ----\n`.format(value, type, dest)); } @@ -107,8 +108,8 @@ function checkArrayParamType(type) { function arrayTempleteFunc(arrayType, deep, dest, value) { let lt = deep let tnv = dest - let tnvdef = `uint32_t len%d=%s.size(); - for(uint32_t i=0;iSetArrayElement(%s, i, tnv%d); @@ -120,6 +121,9 @@ function arrayTempleteFunc(arrayType, deep, dest, value) { else if (arrayType == "string") { ret = tnvdef.replaceAll("[calc_out]", `tnv%d = pxt->SwapC2JsUtf8(%s[i].c_str());`.format(lt, value)) } + else if (arrayType == "boolean") { + ret = tnvdef.replaceAll("[calc_out]", `tnv%d = pxt->SwapC2JsBool(%s[i]);`.format(lt, value)) + } else if (InterfaceList.getValue(arrayType)) { ret = tnvdef.replaceAll("[calc_out]", cToJs(value + "[i]", arrayType, "tnv" + lt, deep + 1)) } @@ -314,14 +318,35 @@ function returnGenerateMap(returnInfo, param) { .format(param.valueDefine.length > 0 ? ", " : "", mapTypeString, modifiers) } -function returnGenerate(returnInfo, param, data) { +/** + * 获取方法返回参数的填充代码 + * @param returnInfo 方法的返回参数信息 + * @param param 方法的所有参数信息 + * @returns 返回参数的填充代码 + */ +function getReturnFill(returnInfo, param) { let type = returnInfo.type - let valueFillStr = "%svio->out" - if (returnInfo.isAsync) { - valueFillStr = "%svio->outErrCode, vio->out" - param.valueDefine += "%suint32_t& outErrCode".format(param.valueDefine.length > 0 ? ", " : "") + let valueFillStr = "" + if (param.callback) { // callback方法的返回参数处理 + if (param.callback.isAsync) { + // 异步callback方法返回的是一个结构体,包含errcode和data两部分, 详见basic.d.ts中AsyncCallback的定义 + valueFillStr = "vio->outErrCode" + param.valueDefine += "%suint32_t& outErrCode".format(param.valueDefine.length > 0 ? ", " : "") + } + + if (type != "void") { + // callback 中的xxx不是void时,生成的capp代码才需要用户填充out参数 + valueFillStr += "%svio->out".format(valueFillStr.length > 0 ? ", " : "") + } + } else { // 普通方法的返回参数处理 + valueFillStr = "vio->out" } - param.valueFill += valueFillStr.format(param.valueFill.length > 0 ? ", " : "") + return valueFillStr +} +function returnGenerate(returnInfo, param, data) { + let type = returnInfo.type + let valueFillStr = getReturnFill(returnInfo, param) + param.valueFill += ("%s" + valueFillStr).format(param.valueFill.length > 0 ? ", " : "") let outParam = returnInfo.optional ? "(*vio->out)" : "vio->out" let modifiers = returnInfo.optional ? "*" : "&" if (returnInfo.optional) { @@ -344,13 +369,13 @@ function returnGenerate(returnInfo, param, data) { else if (isEnum(type, data)) { returnGenerateEnum(data, returnInfo, param) } + else if(generateType(type)){ + returnGenerate2(returnInfo, param, data) + } else if (type.substring(0, 12) == "NUMBER_TYPE_") { param.valueOut = type + (returnInfo.optional ? "* out = nullptr;" : " out;") param.valueDefine += "%s%s%s out".format(param.valueDefine.length > 0 ? ", " : "", type, modifiers) } - else if(generateType(type)){ - returnGenerate2(returnInfo, param, data) - } else { NapiLog.logError("Do not support returning the type [%s].".format(type)); } @@ -393,6 +418,7 @@ function returnGenerate2(returnInfo, param, data){ else if (type.substring(type.length - 2) == "[]") { let arrayType = getArrayTypeTwo(type) if (arrayType == "string") arrayType = "std::string" + if (arrayType == "boolean") arrayType = "bool" param.valueOut = returnInfo.optional ? "std::vector<%s>* out = nullptr;".format(arrayType) : "std::vector<%s> out;".format(arrayType) param.valueDefine += "%sstd::vector<%s>%s out".format( diff --git a/src/gen/tools/common.js b/src/gen/tools/common.js index e6e3e110..8a97905f 100644 --- a/src/gen/tools/common.js +++ b/src/gen/tools/common.js @@ -138,6 +138,16 @@ function getArrayTypeTwo(type) { return re.getReg(type, tt.regs[1]) } +function jsType2CType(jsTypeName) { + if (jsTypeName == "string") { + return "std::string" + } else if (jsTypeName == "boolean") { + return "bool" + } else { + return jsTypeName + } +} + class EnumValueType { } EnumValueType.ENUM_VALUE_TYPE_NUMBER = 0 EnumValueType.ENUM_VALUE_TYPE_STRING = 1 @@ -216,5 +226,6 @@ module.exports = { isEnum, enumIndex, getMapType, - EnumList + EnumList, + jsType2CType } \ No newline at end of file diff --git a/test/storytest/test_callback/@ohos.test.d.ts b/test/storytest/test_callback/@ohos.test.d.ts new file mode 100644 index 00000000..16d63f14 --- /dev/null +++ b/test/storytest/test_callback/@ohos.test.d.ts @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import { AsyncCallback, Callback } from './../basic'; + +declare namespace napitest { + interface TestClass1 { + fun11(cb: Callback): void; + fun12(cb: Callback): void; + fun13(cb: AsyncCallback): void; + fun14(cb: AsyncCallback): void; + } + + function fun1(cb: Callback): void; + function fun2(cb: Callback): void; + function fun3(cb: AsyncCallback): void; + function fun4(cb: AsyncCallback): void; +} + +export default napitest; diff --git a/test/storytest/test_callback/test.js b/test/storytest/test_callback/test.js new file mode 100644 index 00000000..e1cd391e --- /dev/null +++ b/test/storytest/test_callback/test.js @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +const { TestClass1 } = require("./out/build/Release/napitest") +const testObj = require("./out/build/Release/napitest") +var assert = require("assert"); + +function onCallback (ret) { + assert.strictEqual(ret, 0); +} + +function onVoidCallback (ret) { + assert.strictEqual(ret, undefined); +} + +function onAsyncCallback (err, ret) { + assert.strictEqual(err.code, 0); + assert.strictEqual(ret, 0); +} + +function onVoidAsyncCallback (err, ret) { + assert.strictEqual(err.code, 0); + assert.strictEqual(ret, undefined); +} + +describe('Test callback', function () { + it('test callback in interface', function () { + let testClass = new TestClass1(); + testClass.fun11(onCallback); + testClass.fun12(onVoidCallback); + testClass.fun13(onAsyncCallback); + testClass.fun14(onVoidAsyncCallback); + }); + + it('test common func callback', function () { + let testClass = new TestClass1(); + testObj.fun1(onCallback); + testObj.fun2(onVoidCallback); + testObj.fun3(onAsyncCallback); + testObj.fun4(onVoidAsyncCallback); + }); +}); + -- Gitee