From a4eb8a8e67c2694188a85c9194774a3076413411 Mon Sep 17 00:00:00 2001 From: zhaojunxia Date: Thu, 12 May 2022 18:59:29 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90NAPI=E3=80=91=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E8=83=BD=E5=8A=9B=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhaojunxia --- src/gen/analyze.js | 115 ++++++++++---------- src/gen/analyze/function.js | 4 - src/gen/analyze/interface.js | 3 +- src/gen/analyze/namespace.js | 19 ++-- src/gen/analyze/params.js | 18 ++-- src/gen/analyze/return.js | 2 - src/gen/cmd_gen.js | 14 +-- src/gen/generate.js | 6 +- src/gen/generate/class.js | 160 ++++++++++++++++++++++++++++ src/gen/generate/interface.js | 18 ++-- src/gen/generate/namespace.js | 9 ++ src/gen/generate/return_generate.js | 41 ++++--- src/gen/test.js | 4 - src/gen/tools/NapiLog.js | 6 +- src/gen/tools/common.js | 6 ++ src/gen/tools/re.js | 3 +- src/gen/tools/tool.js | 3 +- 17 files changed, 301 insertions(+), 130 deletions(-) create mode 100644 src/gen/generate/class.js diff --git a/src/gen/analyze.js b/src/gen/analyze.js index 6cbb17eb..1df7a8be 100644 --- a/src/gen/analyze.js +++ b/src/gen/analyze.js @@ -13,21 +13,25 @@ * limitations under the License. */ const re = require("./tools/re"); -const { print, removeExplains, removeEmptyLine, checkOutBody, getLicense } = require("./tools/tool"); -const { FuncType, NumberIncrease } = require("./tools/common"); +const { removeExplains, removeEmptyLine, checkOutBody, getLicense } = require("./tools/tool"); +const { NumberIncrease } = require("./tools/common"); const { readFile } = require("./tools/FileRW"); const { analyzeNamespace } = require("./analyze/namespace"); +const { NapiLog } = require("./tools/NapiLog"); function analyzeFile(fn) { NumberIncrease.reset(); let data = readFile(fn); let licenseData = getLicense(data) - data = removeExplains(data)//去除注释 - data = removeEmptyLine(data)//去除空行 - while (true) {//去除import - let tt = re.search("import ([{}A-Za-z ,]+) from [\"']{1}([@./a-zA-Z]+)[\"']{1};*", data); - if (tt != null) data = re.removeReg(data, tt.regs[0]); + // 去除注释 + data = removeExplains(data) + // 去除空行 + data = removeEmptyLine(data) + while (true) { + // 去除import + let matchImport = re.search("import ([{}A-Za-z ,]+) from [\"']{1}([@./a-zA-Z]+)[\"']{1};*", data); + if (matchImport != null) data = re.removeReg(data, matchImport.regs[0]); else break; } let result = { @@ -46,58 +50,51 @@ function analyzeFile(fn) { while (true) { let oldData = data data = removeEmptyLine(data) - - let tt = re.match(" *\n*", data) - if (tt && tt.regs[0][1] == data.length) break//只剩下空格和回车时,解析完成 - - tt = re.match("export default ([a-zA-Z]+);", data); - if (tt != null) { - let exportName = re.getReg(data, tt.regs[1]) - data = re.removeReg(data, tt.regs[0]); + let matchs = re.match(" *\n*", data) + //只剩下空格和回车时,解析完成 + if (matchs && matchs.regs[0][1] == data.length) break + matchs = re.match("export default ([a-zA-Z]+);", data); + if (matchs != null) { + let exportName = re.getReg(data, matchs.regs[1]) + data = re.removeReg(data, matchs.regs[0]); result.exportDefault.push(exportName) } - - let matchType = analyzeMatchType(tt, data, result) + let matchType = analyzeMatchType(matchs, data, result) if (matchType != null) { data = matchType[0] result = matchType[1] } - - let namespace = analyzeMatchNamespace(tt, data, result) + let namespace = analyzeMatchNamespace(matchs, data, result) if (namespace != null) { data = namespace[0] result = namespace[1] } - - let interface = analyzeMatchInterface(tt, data, result) + let interface = analyzeMatchInterface(matchs, data, result) if (interface != null) { data = interface[0] result = interface[1] } - - let functionMatch = analyzeMatchFunction(tt, data, result) + let functionMatch = analyzeMatchFunction(matchs, data, result) if (functionMatch != null) { data = functionMatch[0] result = functionMatch[1] } - if (oldData == data) { - print("\nvvv 解析文件失败 vvv") - print("[", data.substring(0, data.length > 64 ? 64 : data.length), "]") - print("^^^ 解析文件失败 ^^^\n") + NapiLog.logError("解析文件失败"); + NapiLog.logError("[", data.substring(0, data.length > 64 ? 64 : data.length), "]"); break; } } return result } -function analyzeMatchNamespace(tt, data, result) { - tt = re.match("declare namespace ([a-zA-Z0-9]+) ({)", data); - if (tt != null)//解析declare - { - let namespaceName = re.getReg(data, tt.regs[1]) - let namespaceData = checkOutBody(data, tt.regs[2][0], null, true) - data = data.substring(tt.regs[2][1] + namespaceData.length + 1, data.length) +function analyzeMatchNamespace(matchs, data, result) { + matchs = re.match("declare namespace ([a-zA-Z0-9]+) ({)", data); + // 解析declare + if (matchs != null) { + let namespaceName = re.getReg(data, matchs.regs[1]) + let namespaceData = checkOutBody(data, matchs.regs[2][0], null, true) + data = data.substring(matchs.regs[2][1] + namespaceData.length + 1, data.length) result.declareNamespace.push({ name: namespaceName, body: analyzeNamespace(namespaceData) @@ -106,12 +103,12 @@ function analyzeMatchNamespace(tt, data, result) { return [data, result] } -function analyzeMatchInterface(tt, data, result) { - tt = re.match("(export )*(declare )*interface ([A-Za-z_0-9<>= ]+) (extends [a-zA-Z]+ )*({)", data) - if (tt) { - let interfaceName = re.getReg(data, tt.regs[3]) - let interfaceData = checkOutBody(data, tt.regs[5][0], null, true) - data = data.substring(tt.regs[5][1] + interfaceData.length + 1, data.length) +function analyzeMatchInterface(matchs, data, result) { + matchs = re.match("(export )*(declare )*interface ([A-Za-z_0-9<>= ]+) (extends [a-zA-Z]+ )*({)", data) + if (matchs) { + let interfaceName = re.getReg(data, matchs.regs[3]) + let interfaceData = checkOutBody(data, matchs.regs[5][0], null, true) + data = data.substring(matchs.regs[5][1] + interfaceData.length + 1, data.length) result.declareInterface.push({ name: interfaceName, body: {} @@ -120,13 +117,13 @@ function analyzeMatchInterface(tt, data, result) { return [data, result] } -function analyzeMatchFunction(tt, data, result) { - tt = re.match("declare function ([A-Za-z0-9_]+)\\(([\n a-zA-Z:;=,_0-9?<>{}|]*)\\) *:" +function analyzeMatchFunction(matchs, data, result) { + matchs = re.match("declare function ([A-Za-z0-9_]+)\\(([\n a-zA-Z:;=,_0-9?<>{}|]*)\\) *:" + "*([A-Za-z0-9_<>{}:, .]+);*", data) - if (tt) { - let functionName = re.getReg(data, tt.regs[1]) - let functionBody = re.getReg(data, tt.regs[2]) - data = re.removeReg(data, tt.regs[0]) + if (matchs) { + let functionName = re.getReg(data, matchs.regs[1]) + let functionBody = re.getReg(data, matchs.regs[2]) + data = re.removeReg(data, matchs.regs[0]) result.declareFunction.push({ name: functionName, body: functionBody @@ -135,31 +132,31 @@ function analyzeMatchFunction(tt, data, result) { return [data, result] } -function analyzeMatchType(tt, data, result) { - tt = re.match("(export )*type ([a-zA-Z]+) = ([()a-zA-Z :=>,\"| ]+);", data) - if (tt) { - let exportName = re.getReg(data, tt.regs[2]) - let exportBody = re.getReg(data, tt.regs[3]) - data = re.removeReg(data, tt.regs[0]); +function analyzeMatchType(matchs, data, result) { + matchs = re.match("(export )*type ([a-zA-Z]+) = ([()a-zA-Z :=>,\"| ]+);", data) + if (matchs) { + let exportName = re.getReg(data, matchs.regs[2]) + let exportBody = re.getReg(data, matchs.regs[3]) + data = re.removeReg(data, matchs.regs[0]); result.declareType.push({ name: exportName, body: exportBody }) - if (tt.regs[1][0] != -1) { + if (matchs.regs[1][0] != -1) { result.exports.push(exportName) } } - tt = re.match("(export )*type ([a-zA-Z]+) = ({)", data) - if (tt) { - let exportName = re.getReg(data, tt.regs[2]) - let exportBody = checkOutBody(data, tt.regs[3][0], null, true) - data = data.substring(tt.regs[3][1] + exportBody.length + 2, data.length) + matchs = re.match("(export )*type ([a-zA-Z]+) = ({)", data) + if (matchs) { + let exportName = re.getReg(data, matchs.regs[2]) + let exportBody = checkOutBody(data, matchs.regs[3][0], null, true) + data = data.substring(matchs.regs[3][1] + exportBody.length + 2, data.length) result.declareType.push({ name: exportName, body: exportBody }) - if (tt.regs[1][0] != -1) { + if (matchs.regs[1][0] != -1) { result.exports.push(exportName) } } diff --git a/src/gen/analyze/function.js b/src/gen/analyze/function.js index 039807be..c965d04b 100644 --- a/src/gen/analyze/function.js +++ b/src/gen/analyze/function.js @@ -13,7 +13,6 @@ * limitations under the License. */ const re = require("../tools/re"); -const { print, removeExplains, removeEmptyLine, checkOutBody } = require("../tools/tool"); const { FuncType, NumberIncrease } = require("../tools/common"); const { analyzeParams } = require("./params"); const { analyzeReturn } = require("./return"); @@ -24,18 +23,15 @@ function analyzeFunction(name, values, ret) { let tmp = analyzeParams(values) values = tmp[0] let funcType = tmp[1] - tmp = analyzeReturn(ret) ret = tmp[0] if (tmp[1]) funcType = FuncType.PROMISE - if (funcType == FuncType.ASYNC || funcType == FuncType.PROMISE) { // 查看是否有同名的函数,async_callback和promise, // 只需要保留一个,这里简单处理,忽略所有promise if (funcType == FuncType.PROMISE) return null; } - for (let j in values) { let v = values[j] if (v["type"].indexOf("number") >= 0) { diff --git a/src/gen/analyze/interface.js b/src/gen/analyze/interface.js index 1dd50812..f95b615f 100644 --- a/src/gen/analyze/interface.js +++ b/src/gen/analyze/interface.js @@ -13,8 +13,7 @@ * limitations under the License. */ const re = require("../tools/re"); -const { print, removeExplains, removeEmptyLine, checkOutBody } = require("../tools/tool"); -const { FuncType, NumberIncrease } = require("../tools/common"); +const { NumberIncrease } = require("../tools/common"); const { analyzeFunction } = require("./function"); diff --git a/src/gen/analyze/namespace.js b/src/gen/analyze/namespace.js index 0c99a750..80640374 100644 --- a/src/gen/analyze/namespace.js +++ b/src/gen/analyze/namespace.js @@ -71,17 +71,17 @@ function analyzeNamespace(data) { return result } -function parseNamespace(tt, data, result) { - tt = re.match("(export )*namespace ([a-zA-Z0-9]+) ({)", data) - if (tt) { - let namespaceName = re.getReg(data, tt.regs[2]) - let namespaceBody = checkOutBody(data, tt.regs[3][0], null, true) +function parseNamespace(matchs, data, result) { + matchs = re.match("(export )*namespace ([a-zA-Z0-9]+) ({)", data) + if (matchs) { + let namespaceName = re.getReg(data, matchs.regs[2]) + let namespaceBody = checkOutBody(data, matchs.regs[3][0], null, true) result.namespace.push({ name: namespaceName, body: analyzeNamespace(namespaceBody) }) - data = data.substring(tt.regs[3][0] + namespaceBody.length + 2, data.length) - if (tt.regs[1][0] != -1) { + data = data.substring(matchs.regs[3][0] + namespaceBody.length + 2, data.length) + if (matchs.regs[1][0] != -1) { result.exports.push(namespaceName) } } @@ -186,11 +186,9 @@ function parseFunction(matchs, data, result) { else { funcRet = "void" } - let funcDetail = analyzeFunction(funcName, funcValue.substring(1, funcValue.length - 1), funcRet) if (funcDetail != null) result.function.push(funcDetail) - if (matchs.regs[1][0] != -1) { result.exports.push(funcName) } @@ -222,17 +220,14 @@ function removeReg(matchs, data, result) { result.exports.push(exportName) data = re.removeReg(data, matchs.regs[0]) } - matchs = re.match("export import [a-zA-Z]+ = [a-zA-Z\\.]+;", data) if (matchs) { data = re.removeReg(data, matchs.regs[0]) } - matchs = re.match("readonly [a-zA-Z]+: [a-z\\[\\]]+;*", data) if (matchs) { data = re.removeReg(data, matchs.regs[0]) } - return data } module.exports = { diff --git a/src/gen/analyze/params.js b/src/gen/analyze/params.js index 52919f96..6528c8a0 100644 --- a/src/gen/analyze/params.js +++ b/src/gen/analyze/params.js @@ -13,8 +13,9 @@ * limitations under the License. */ const re = require("../tools/re"); -const { print, removeExplains, removeEmptyLine, checkOutBody } = require("../tools/tool"); -const { FuncType, NumberIncrease } = require("../tools/common"); +const { checkOutBody } = require("../tools/tool"); +const { FuncType } = require("../tools/common"); +const { NapiLog } = require("../tools/NapiLog"); /**函数参数解析 */ function analyzeParams(values) { @@ -25,19 +26,18 @@ function analyzeParams(values) { if (v == null) v = values values = values.substring(v.length, values.length) - let tt = re.match("([a-zA-Z0-9\\.]+)\\?*:([a-zA-Z<>_0-9\\(\\):='{}]+)", v) - if (tt != null) { - let type = re.getReg(v, tt.regs[2]) - result.push({ "name": re.getReg(v, tt.regs[1]), "type": type }) + let matchs = re.match("([a-zA-Z0-9\\.]+)\\?*:([a-zA-Z<>_0-9\\[\\]\\(\\):='{}]+)", v) + if (matchs != null) { + let type = re.getReg(v, matchs.regs[2]) + result.push({ "name": re.getReg(v, matchs.regs[1]), "type": type }) if (type.indexOf("AsyncCallback") >= 0) funcType = FuncType.ASYNC if (funcType == FuncType.DIRECT && type.indexOf("Callback") >= 0 && type.indexOf("AsyncCallback") < 0) funcType = FuncType.SYNC } else { - print("\nvvv 参数列表解析失败 vvv") - print(v, values) - print("^^^ 参数列表解析失败 ^^^\n") + NapiLog.logError("参数列表解析失败"); + NapiLog.logError("analyzeParams error params:" + v); } } return [result, funcType] diff --git a/src/gen/analyze/return.js b/src/gen/analyze/return.js index cb57dc9b..d651b952 100644 --- a/src/gen/analyze/return.js +++ b/src/gen/analyze/return.js @@ -13,8 +13,6 @@ * limitations under the License. */ const re = require("../tools/re"); -const { print, removeExplains, removeEmptyLine, checkOutBody } = require("../tools/tool"); -const { FuncType, NumberIncrease } = require("../tools/common"); /**函数返回值解析 */ function analyzeReturn(ret) { diff --git a/src/gen/cmd_gen.js b/src/gen/cmd_gen.js index ecc09fd9..a9a198fa 100644 --- a/src/gen/cmd_gen.js +++ b/src/gen/cmd_gen.js @@ -17,9 +17,7 @@ const re = require("./tools/re"); const { checkFileError } = require("./tools/common"); const { NapiLog } = require("./tools/NapiLog"); const path = require("path"); - const stdio = require("stdio"); - let ops = stdio.getopt({ 'filename': { key: 'f', args: 1, description: ".d.ts file" }, 'out': { key: 'o', args: 1, description: "output directory", default: "." }, @@ -27,29 +25,25 @@ let ops = stdio.getopt({ }); NapiLog.init(ops.loglevel, path.join("" + ops.out, "napi_gen.log")) - let fn = re.getFileInPath(ops.filename) - -let tt = re.match("@ohos.[a-zA-Z0-9]+.d.ts", fn) -if (tt) { +let matchOhosFile = re.match("@ohos.[a-zA-Z0-9]+.d.ts", fn) +if (matchOhosFile) { let result = checkFileError(ops.filename); if (result[0]) { main.doGenerate(ops.filename, ops.out) } else { - //console.log(result[1]) NapiLog.logError(result[1]); } } else { - //print("\n文件名 " + fn + " 校验失败,需要符合 @ohos.input_sample.d.ts") NapiLog.logError("file name " + fn + " format invalid, @ohos.input_sample.d.ts"); } let ret = NapiLog.getResult() if (ret[0]) { - console.log("success") + NapiLog.logError("success"); } else { - console.log("fail\n" + ret[1]) + NapiLog.logError("fail\n" + ret[1]); } diff --git a/src/gen/generate.js b/src/gen/generate.js index 6faffe48..d9c26055 100644 --- a/src/gen/generate.js +++ b/src/gen/generate.js @@ -14,7 +14,7 @@ */ //生成BUILD.gn //生成x_napi_tool.h,生成x_napi_tool.cpp -const { replaceAll, print } = require("./tools/tool"); +const { replaceAll } = require("./tools/tool"); const { generateNamespace } = require("./generate/namespace"); const { writeFile } = require("./tools/FileRW"); const re = require("./tools/re"); @@ -112,15 +112,12 @@ let implCppTemplete = `\ function generateAll(structOfTs, destDir, moduleName) { let ns0 = structOfTs.declareNamespace[0]; - let license = structOfTs.declareLicense[0]; let result = generateNamespace(ns0.name, ns0.body) - let numberUsing = "" for (let i = 1; i < NumberIncrease.get(); i++) { numberUsing += "using NUMBER_TYPE_%d = uint32_t;\n".format(i) } - let middleCpp = replaceAll(moduleCppTmplete, "[body_replace]", result.middleBody); middleCpp = replaceAll(middleCpp, "[init_replace]", result.middleInit); middleCpp = replaceAll(middleCpp, "[implName]", ns0.name); @@ -137,7 +134,6 @@ function generateAll(structOfTs, destDir, moduleName) { implCpp = implCpp.replaceAll("[implCpp_detail]", result.implCpp) writeFile(re.pathJoin(destDir, "%s.cpp".format(ns0.name)), null != license ? (license + "\n" + implCpp) : implCpp) - generateGYP(destDir, ns0.name, license)//生成ubuntu下测试的编译脚本 generateGN(destDir, ns0.name, license)//生成BUILD.gn for ohos generateBase(destDir, license)//x_napi_tool.h/cpp diff --git a/src/gen/generate/class.js b/src/gen/generate/class.js new file mode 100644 index 00000000..56e000d8 --- /dev/null +++ b/src/gen/generate/class.js @@ -0,0 +1,160 @@ +/* +* 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 { generateFunctionDirect } = require("./function_direct"); +const { generateFunctionSync } = require("./function_sync"); +const { generateFunctionAsync } = require("./function_async"); +const { FuncType, InterfaceList, getArrayType } = require("../tools/common"); +const { jsToC } = require("./param_generate"); +const { cToJs } = require("./return_generate"); +const re = require("../tools/re"); +const { NapiLog } = require("../tools/NapiLog"); + +let middleBodyTmplete = ` +class [className]_middle { +public: +static napi_value constructor(napi_env env, napi_callback_info info) +{ + XNapiTool *pxt = new XNapiTool(env, info); + + [className] *p = new [className](); + + napi_value thisvar = pxt->WrapInstance(p, release); + + return thisvar; +} +static void release(void *p) +{ + [className] *p2 = ([className] *)p; + delete p2; +} +[static_funcs] +};` + +function generateVariable(name, type, variable, className) { + 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 (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) + } 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 + NapiLog.logError(` + ---- generateVariable fail %s,%s ---- + `.format(name, type)); + variable.middleValue += ` + static napi_value getvalue_%s(napi_env env, napi_callback_info info) + { + XNapiTool *pxt = std::make_unique(env, info).release(); + %s *p = (%s *)pxt->UnWarpInstance(); + napi_value result; + `.format(name, className, className) + cToJs("p->" + name, type, "result") + ` + delete pxt; + return result; + } + static napi_value setvalue_%s(napi_env env, napi_callback_info info) + { + std::shared_ptr pxt = std::make_shared(env, info); + %s *p = (%s *)pxt->UnWarpInstance(); + `.format(name, className, className) + jsToC("p->" + name, "pxt->GetArgv(0)", type) + ` + return nullptr; + } +` +} + +function generateClass(name, data, inNamespace, functiontType) { + let resultConnect = connectResult(data, inNamespace, name) + let middleFunc = resultConnect[0] + let implH = functiontType == "static" ? "\n" + "static " + + resultConnect[1].substring(1, resultConnect[1].length) : resultConnect[1] + let implCpp = resultConnect[2] + let middleInit = resultConnect[3] + let selfNs = "" + if (inNamespace.length > 0) { + let nsl = inNamespace.split("::") + nsl.pop() + if (nsl.length >= 2) { + selfNs = ", " + nsl[nsl.length - 1] + } + } + middleInit += `\n pxt->DefineClass("%s", %s%s_middle::constructor, valueList ,funcList%s);\n}\n` + .format(name, inNamespace, name, selfNs) + let result = { + implH: ` +class %s { +public:%s +};`.format(name, implH), + implCpp: implCpp, + middleBody: middleBodyTmplete.replaceAll("[className]", name).replaceAll("[static_funcs]", middleFunc), + middleInit: middleInit + } + return result +} + +function connectResult(data, inNamespace, name) { + let implH = "" + let implCpp = "" + let middleFunc = "" + let middleInit = "" + let variable = { + hDefine: "", + middleValue: "", + } + middleInit = `{\n std::map> valueList;` + for (let i in data.value) { + let v = data.value[i] + generateVariable(v.name, v.type, variable, name) + middleInit += ` + valueList["%s"]["getvalue"]=%s%s_middle::getvalue_%s; + valueList["%s"]["setvalue"]=%s%s_middle::setvalue_%s;` + .format(v.name, inNamespace, name, v.name, v.name, inNamespace, name, v.name) + } + implH += variable.hDefine + middleFunc += variable.middleValue + middleInit += `\n std::map funcList;` + for (let i in data.function) { + let func = data.function[i] + let tmp; + switch (func.type) { + case FuncType.DIRECT: + tmp = generateFunctionDirect(func, '', name) + break; + case FuncType.SYNC: + tmp = generateFunctionSync(func, '', name) + break + case FuncType.ASYNC: + case FuncType.PROMISE: + tmp = generateFunctionAsync(func, '', name) + break + default: + return + } + middleFunc += tmp[0] + implH += tmp[1] + implCpp += tmp[2] + middleInit += `\n funcList["%s"] = %s%s_middle::%s_middle;`.format(func.name, inNamespace, name, func.name) + } + return [middleFunc, implH, implCpp, middleInit] +} + +module.exports = { + generateClass +} \ No newline at end of file diff --git a/src/gen/generate/interface.js b/src/gen/generate/interface.js index c9fcc38c..c902e08a 100644 --- a/src/gen/generate/interface.js +++ b/src/gen/generate/interface.js @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const { print } = require("../tools/tool"); const { generateFunctionDirect } = require("./function_direct"); const { generateFunctionSync } = require("./function_sync"); const { generateFunctionAsync } = require("./function_async"); @@ -49,12 +48,17 @@ function generateVariable(name, type, variable, className) { 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) + } 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 - print(` ----- generateVariable fail %s,%s ---- -`.format(name, type)) + NapiLog.logError(` + ---- generateVariable fail %s,%s ---- + `.format(name, type)); variable.middleValue += ` static napi_value getvalue_%s(napi_env env, napi_callback_info info) { @@ -129,14 +133,14 @@ function connectResult(data, inNamespace, name) { let tmp; switch (func.type) { case FuncType.DIRECT: - tmp = generateFunctionDirect(func, name) + tmp = generateFunctionDirect(func, data, name) break; case FuncType.SYNC: - tmp = generateFunctionSync(func, name) + tmp = generateFunctionSync(func, data, name) break case FuncType.ASYNC: case FuncType.PROMISE: - tmp = generateFunctionAsync(func, name) + tmp = generateFunctionAsync(func, data, name) break default: return diff --git a/src/gen/generate/namespace.js b/src/gen/generate/namespace.js index cc91fe2c..d735dc33 100644 --- a/src/gen/generate/namespace.js +++ b/src/gen/generate/namespace.js @@ -16,6 +16,7 @@ const { generateFunctionDirect } = require("./function_direct"); const { generateFunctionSync } = require("./function_sync"); const { generateFunctionAsync } = require("./function_async"); const { generateInterface } = require("./interface"); +const { generateClass } = require("./class"); const { FuncType, InterfaceList } = require("../tools/common"); //生成module_middle.cpp、module.h、module.cpp @@ -34,6 +35,14 @@ function generateNamespace(name, data, inNamespace = "") { implCpp += result.implCpp middleInit += result.middleInit } + for (let i in data.class) { + let ii = data.class[i] + let result = generateClass(ii.name, ii.body, inNamespace + name + "::", ii.functiontType) + middleFunc += result.middleBody + implH += result.implH + implCpp += result.implCpp + middleInit += result.middleInit + } for (let i in data.function) { let func = data.function[i] let tmp = generateFunction(func, data) diff --git a/src/gen/generate/return_generate.js b/src/gen/generate/return_generate.js index c2e8e8e4..f5714efc 100644 --- a/src/gen/generate/return_generate.js +++ b/src/gen/generate/return_generate.js @@ -12,8 +12,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const { replaceAll, print } = require("../tools/tool"); -const { InterfaceList, getArrayType } = require("../tools/common"); +const { InterfaceList, getArrayType, NumberIncrease } = require("../tools/common"); +const { NapiLog } = require("../tools/NapiLog"); + +function isEnum(type, data) { + let isEnum = false + if (null == data) { + return isEnum + } + for (let i in data.enum) { + let enumm = data.enum[i] + if (type == enumm.name) { + isEnum = true + } + } + return isEnum +} function cToJs(value, type, dest, deep = 1) { if (type == "void") @@ -26,16 +40,17 @@ function cToJs(value, type, dest, deep = 1) { return `%s = NUMBER_C_2_JS(pxt, %s);`.format(dest, value) else if (InterfaceList.getValue(type)) { let lt = deep - let tt = "" + let result = "" let ifl = InterfaceList.getValue(type) for (let i in ifl) { let name2 = ifl[i].name let type2 = ifl[i].type - let tt1 = cToJs("%s.%s".format(value, name2), type2, "tnv%d".format(lt), deep + 1) - tt += "{\nnapi_value tnv%d = nullptr;\n".format(lt) + tt1 + `\npxt->SetValueProperty(%s,"%s",tnv%d);\n}` - .format(dest, name2, lt) + let interfaceType = cToJs("%s.%s".format(value, name2), type2, "tnv%d".format(lt), deep + 1) + result += "{\nnapi_value tnv%d = nullptr;\n".format(lt) + + interfaceType + `\npxt->SetValueProperty(%s,"%s",tnv%d);\n}` + .format(dest, name2, lt) } - return tt + return result } else if (type.substring(0, 6) == "Array<") { let arrayType = getArrayType(type) @@ -60,18 +75,20 @@ function cToJs(value, type, dest, deep = 1) { return ret } else - print(`\n---- This type do not generate cToJs %s,%s,%s ----\n`.format(value, type, dest)) + NapiLog.logError(`This type do not generate cToJs %s,%s,%s`.format(value, type, dest)); } -function returnGenerate(type, param) { +function returnGenerate(type, param, data) { param.valueFill += "%svio->out".format(param.valueFill.length > 0 ? ", " : "") - param.valuePackage = "napi_value result = nullptr;\n " + cToJs("vio->out", type, "result") + if (!isEnum(type, data)) { + param.valuePackage = "napi_value result = nullptr;\n " + cToJs("vio->out", type, "result") + } if (type == "string") { param.valueOut = "std::string out;" param.valueDefine += "%sstd::string &out".format(param.valueDefine.length > 0 ? ", " : "") } else if (type == "void") { - + NapiLog.logInfo("The current type don't need generate return %s`.format(type)"); } else if (type == "boolean") { param.valueOut = "bool out;" @@ -92,7 +109,7 @@ function returnGenerate(type, param) { param.valueDefine += "%sstd::vector<%s> &out".format(param.valueDefine.length > 0 ? ", " : "", arrayType) } else { - print(`\n---- The current version do not support this type return %s ----\n`.format(type)) + NapiLog.logError("The current version do not support this type return %s`.format(type)"); } } diff --git a/src/gen/test.js b/src/gen/test.js index 7529da0b..fb05591b 100644 --- a/src/gen/test.js +++ b/src/gen/test.js @@ -12,9 +12,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const fs = require("fs"); -const path = require("path"); const main = require("./main"); -const { print } = require("./tools/tool"); - main.doGenerate("nodejs_test/gen/@ohos.napitest.d.ts"); \ No newline at end of file diff --git a/src/gen/tools/NapiLog.js b/src/gen/tools/NapiLog.js index ff1955a8..85452981 100755 --- a/src/gen/tools/NapiLog.js +++ b/src/gen/tools/NapiLog.js @@ -50,9 +50,11 @@ function recordLog(lev, ...args) { let dataStr = getDateString(); let detail = args.join(" "); saveLog(dataStr, LEV_STR[lev], detail); - logResultMessage = [false, detail]; + if (lev == NapiLog.LEV_ERROR) { + logResultMessage = [false, detail]; + } if (logLevel < lev) return; - console.log(dataStr, LEV_STR[lev], detail) + NapiLog.logInfo(dataStr + LEV_STR[lev] + detail); } NapiLog.logError = function (...args) { diff --git a/src/gen/tools/common.js b/src/gen/tools/common.js index 59aa5ad1..564316cb 100644 --- a/src/gen/tools/common.js +++ b/src/gen/tools/common.js @@ -85,10 +85,16 @@ function getArrayType(type) { return re.getReg(type, tt.regs[1]) } +function getArrayTypeTwo(type) { + let tt = re.match("([a-zA-Z_0-9]+)", type) + return re.getReg(type, tt.regs[1]) +} + module.exports = { FuncType, NumberIncrease, InterfaceList, getArrayType, + getArrayTypeTwo, checkFileError } \ No newline at end of file diff --git a/src/gen/tools/re.js b/src/gen/tools/re.js index 89a1c01a..71edcdb9 100644 --- a/src/gen/tools/re.js +++ b/src/gen/tools/re.js @@ -13,9 +13,10 @@ * limitations under the License. */ const path = require('path'); +const { NapiLog } = require('./NapiLog'); function print(...args) { - console.log(...args) + NapiLog.logInfo(...args); } function search(ss, data) { diff --git a/src/gen/tools/tool.js b/src/gen/tools/tool.js index 99d1b88a..a317d3f3 100644 --- a/src/gen/tools/tool.js +++ b/src/gen/tools/tool.js @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +const { NapiLog } = require("./NapiLog"); const re = require("./re"); let vscode = null; try { @@ -25,7 +26,7 @@ function print(...args) { if (vscode) { vscode.window.showInformationMessage(...args); } - console.log(...args) + NapiLog.logInfo(...args); } String.prototype.format = function (...args) { -- Gitee