diff --git a/src/gen/analyze/enum.js b/src/gen/analyze/enum.js new file mode 100644 index 0000000000000000000000000000000000000000..2df1d06f9a1a21ac469c65afc35087ce1278729d --- /dev/null +++ b/src/gen/analyze/enum.js @@ -0,0 +1,71 @@ +/* +* 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 re = require("../tools/re"); + +/** Enum解析 */ +function analyzeEnum(data) { + let body = re.replaceAll(data, "\n", "").split(",") + let result = { + element: [], + function: [], + enumValueType: 0// 0代表数字,1代表字符串 + } + for (let i in body) { + let bodyContent = body[i] + while (bodyContent.length > 0 && bodyContent[0] == ' ') { + bodyContent = bodyContent.substring(1, bodyContent.length) + } + while (bodyContent.length > 0 && bodyContent[-1] == ' ') { + bodyContent = bodyContent.substring(0, bodyContent.length - 1) + } + if (bodyContent == "") { + break + } + let regString = re.match(" *([a-zA-Z0-9_]+) * = *\"([a-zA-Z_0-9<>-]+)\"", bodyContent) + let regSingleQuotes = re.match(" *([a-zA-Z0-9_]+) * = *'([a-zA-Z_0-9<>-]+)'", bodyContent) + let regNumber = re.match(" *([a-zA-Z0-9_]+) * = *([a-zA-Z_0-9<>-]+)", bodyContent) + if (regString) { + let elementName = re.getReg(bodyContent, regString.regs[1]) + let elementValue = re.getReg(bodyContent, regString.regs[2]) + result.element.push({ + name: elementName, + value: elementValue + }) + result.enumValueType = 1 + } else if (regSingleQuotes) { + let elementName = re.getReg(bodyContent, regSingleQuotes.regs[1]) + let elementValue = re.getReg(bodyContent, regSingleQuotes.regs[2]) + result.element.push({ + name: elementName, + value: elementValue + }) + result.enumValueType = 1 + } else if (regNumber) { + let elementName = re.getReg(bodyContent, regNumber.regs[1]) + let elementValue = re.getReg(bodyContent, regNumber.regs[2]) + typeof (elementValue) + result.element.push({ + name: elementName, + value: elementValue + }) + result.enumValueType = 0 + } + } + return result +} + +module.exports = { + analyzeEnum +} \ No newline at end of file diff --git a/src/gen/analyze/namespace.js b/src/gen/analyze/namespace.js index 80640374a6ab086f8a42cdb35a49561fb9bcd744..775e6f2c36f64c24744a16de202de0144f79bcd3 100644 --- a/src/gen/analyze/namespace.js +++ b/src/gen/analyze/namespace.js @@ -17,6 +17,7 @@ const { removeEmptyLine, checkOutBody } = require("../tools/tool"); const { analyzeFunction } = require("./function"); const { analyzeInterface } = require("./interface"); const { analyzeClass } = require("./class"); +const { analyzeEnum } = require("./enum"); const { NapiLog } = require("../tools/NapiLog"); /**namespace解析 */ @@ -35,7 +36,7 @@ function analyzeNamespace(data) { let oldData = data data = removeEmptyLine(data) let matchs = re.match(" *\n*", data) - //只剩下空格和回车时,解析完成 + // 只剩下空格和回车时,解析完成 if (matchs && matchs.regs[0][1] == data.length) break let parseEnumResult = parseEnum(matchs, data, result) if (parseEnumResult != null) { @@ -113,13 +114,13 @@ function parseEnum(matchs, data, result) { let enumBody = checkOutBody(data, matchs.regs[3][0], null, null) result.enum.push({ name: enumName, + body: analyzeEnum(enumBody.substring(1, enumBody.length - 1)) }) data = data.substring(matchs.regs[3][0] + enumBody.length) if (matchs.regs[1][0] != -1) { result.exports.push(enumName) } } - matchs = re.match("(export )*const ([a-zA-Z_]+) *[:=]{1} ([a-zA-Z0-9]+);", data) if (matchs) { let constName = re.getReg(data, matchs.regs[1]) @@ -148,7 +149,6 @@ function parseType(matchs, data, result) { result.exports.push(typeName) } } - matchs = re.match("(export )*type ([a-zA-Z]+) = ({)", data) if (matchs) { let typeName = re.getReg(data, matchs.regs[2]); diff --git a/src/gen/generate/enum.js b/src/gen/generate/enum.js new file mode 100644 index 0000000000000000000000000000000000000000..ccdc7aa0ddefc71c76f42c40d93f5f132731db81 --- /dev/null +++ b/src/gen/generate/enum.js @@ -0,0 +1,43 @@ +/* +* 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 re = require("../tools/re"); +function generateEnum(name, data) { + let implH = "" + let implCpp = "" + + if (re.match("[a-zA-Z]", data.element[0].value)) { + implH = `class %s {\npublic:\n`.format(name, implH) + } else { + implH = `\nenum %s {\n`.format(name, implH) + } + for (let i in data.element) { + let v = data.element[i] + if (re.match("[a-zA-Z]", v.value)) { + implH += ` static const std::string %s,\n`.format(v.name) + implCpp += `const std::string %s::%s = "%s";\n`.format(name, v.name, v.value) + } else { + implH += ` %s = %s,\n`.format(v.name, v.value) + } + } + implH += `};\n` + let result = { + implH: implH, + implCpp: implCpp + } + return result +} +module.exports = { + generateEnum +} \ No newline at end of file diff --git a/src/gen/generate/namespace.js b/src/gen/generate/namespace.js index d735dc33eafd3212c3de1400f8ce778014b41262..cab3c08abb827afeed61a2b02d404fa370f91ce5 100644 --- a/src/gen/generate/namespace.js +++ b/src/gen/generate/namespace.js @@ -18,6 +18,7 @@ const { generateFunctionAsync } = require("./function_async"); const { generateInterface } = require("./interface"); const { generateClass } = require("./class"); const { FuncType, InterfaceList } = require("../tools/common"); +const { generateEnum } = require("./enum"); //生成module_middle.cpp、module.h、module.cpp function generateNamespace(name, data, inNamespace = "") { @@ -43,6 +44,7 @@ function generateNamespace(name, data, inNamespace = "") { implCpp += result.implCpp middleInit += result.middleInit } + generateEnumResult(data, implH, implCpp); for (let i in data.function) { let func = data.function[i] let tmp = generateFunction(func, data) @@ -67,6 +69,15 @@ function generateNamespace(name, data, inNamespace = "") { return generateResult(name, implH, implCpp, middleFunc, middleInit) } +function generateEnumResult(data, implH, implCpp) { + for (let i in data.enum) { + let enumm = data.enum[i] + let result = generateEnum(enumm.name, enumm.body) + implH += result.implH + implCpp += result.implCpp + } +} + function generateResult(name, implH, implCpp, middleFunc, middleInit) { let result = { implH: `namespace %s {%s\n}`.format(name, implH), diff --git a/src/gen/generate/param_generate.js b/src/gen/generate/param_generate.js index 1059a895b74efa0e398de8c90e0163545e64a4bd..afcf275417f4161bca021af7bac6ea22bbbe3737 100644 --- a/src/gen/generate/param_generate.js +++ b/src/gen/generate/param_generate.js @@ -12,7 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const { InterfaceList, getArrayType, getArrayTypeTwo, NumberIncrease } = require("../tools/common"); +const { InterfaceList, getArrayType, getArrayTypeTwo, NumberIncrease, + enumIndex, isEnum, EnumValueType } = require("../tools/common"); const re = require("../tools/re"); const { NapiLog } = require("../tools/NapiLog"); @@ -133,6 +134,19 @@ function paramGenerateArray(p, name, type, param) { } } +function paramGenerateEnum(data, type, param, name, p) { + let index = enumIndex(type, data) + if (data.enum[index].body.enumValueType == EnumValueType.ENUM_VALUE_TYPE_NUMBER) { + type = "NUMBER_TYPE_" + NumberIncrease.getAndIncrease() + } else if (data.enum[index].body.enumValueType == EnumValueType.ENUM_VALUE_TYPE_STRING) { + type = "string" + } else { + NapiLog.logError(`paramGenerate is not support`); + return + } + paramGenerate(p, name, type, param, data) +} + // 函数的参数处理 function paramGenerate(p, name, type, param, data) { if (type == "string") { @@ -165,7 +179,11 @@ function paramGenerate(p, name, type, param, data) { param.valueCheckout += jsToC("vio->in" + p, "pxt->GetArgv(%d)".format(p), type) param.valueFill += "%svio->in%d".format(param.valueFill.length > 0 ? ", " : "", p) param.valueDefine += "%sbool &%s".format(param.valueDefine.length > 0 ? ", " : "", name) - } else { + } + else if (isEnum(type, data)) { + paramGenerateEnum(data, type, param, name, p) + } + else { paramGenerateArray(p, name, type, param); } } diff --git a/src/gen/generate/return_generate.js b/src/gen/generate/return_generate.js index f5714efc295ea8aff16a985cd6833996e971a0ae..e5d86b9e14dc6e38ed96ec6710aa5dffc9bedf60 100644 --- a/src/gen/generate/return_generate.js +++ b/src/gen/generate/return_generate.js @@ -12,23 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const { InterfaceList, getArrayType, NumberIncrease } = require("../tools/common"); +const { InterfaceList, getArrayType, NumberIncrease, enumIndex, isEnum, EnumValueType } = 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") return "%s = pxt->UndefinedValue();".format(dest); @@ -94,6 +80,9 @@ function returnGenerate(type, param, data) { param.valueOut = "bool out;" param.valueDefine += "%sbool &out".format(param.valueDefine.length > 0 ? ", " : "") } + else if (isEnum(type, data)) { + returnGenerateEnum(data, type, param) + } else if (type.substring(0, 12) == "NUMBER_TYPE_") { param.valueOut = type + " out;" param.valueDefine += "%s%s &out".format(param.valueDefine.length > 0 ? ", " : "", type) @@ -113,6 +102,27 @@ function returnGenerate(type, param, data) { } } +function returnGenerateEnum(data, type, param) { + let index = enumIndex(type, data) + if (data.enum[index].body.enumValueType == EnumValueType.ENUM_VALUE_TYPE_NUMBER) { + type = "NUMBER_TYPE_" + NumberIncrease.getAndIncrease() + } else if (data.enum[index].body.enumValueType == EnumValueType.ENUM_VALUE_TYPE_STRING) { + type = "string" + } else { + NapiLog.logError(`returnGenerate is not support`); + return + } + 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.substring(0, 12) == "NUMBER_TYPE_") { + param.valueOut = type + " out;" + param.valueDefine += "%s%s &out".format(param.valueDefine.length > 0 ? ", " : "", type) + } +} + module.exports = { cToJs, returnGenerate diff --git a/src/gen/tools/common.js b/src/gen/tools/common.js index 564316cb236ef3622c59615b21686bf6032b6a90..6d3030675b925e7ce85a9e8b281505177b2aac6c 100644 --- a/src/gen/tools/common.js +++ b/src/gen/tools/common.js @@ -90,11 +90,46 @@ function getArrayTypeTwo(type) { return re.getReg(type, tt.regs[1]) } +class EnumValueType { } +EnumValueType.ENUM_VALUE_TYPE_NUMBER = 0 +EnumValueType.ENUM_VALUE_TYPE_STRING = 1 + +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 enumIndex(type, data) { + let index; + if (null == data) { + return index + } + for (let i in data.enum) { + let enumm = data.enum[i] + if (type == enumm.name) { + index = i + } + } + return index +} + module.exports = { FuncType, + EnumValueType, NumberIncrease, InterfaceList, getArrayType, getArrayTypeTwo, - checkFileError + checkFileError, + isEnum, + enumIndex } \ No newline at end of file diff --git a/test/storytest/test_enum/@ohos.test.d.ts b/test/storytest/test_enum/@ohos.test.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..a6a4b13454e17ce5d411095e27a93f2b1997553a --- /dev/null +++ b/test/storytest/test_enum/@ohos.test.d.ts @@ -0,0 +1,33 @@ +/* +* 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. +*/ + +declare namespace napitest { + export enum GrantStatus { + PERMISSION_DEFAULT = "", + PERMISSION_DENIED = "-1", + PERMISSION_GRANTED = "2", + PERMISSION_PASS = "3", + } + + export enum HttpStatus { + STATUS0 = 0, + STATUS1 = 500, + STATUS2 = 503, + } + function fun1(v1: GrantStatus): HttpStatus; + function fun2(v1: HttpStatus): GrantStatus; +} + +export default napitest; diff --git a/test/storytest/test_enum/test.js b/test/storytest/test_enum/test.js new file mode 100644 index 0000000000000000000000000000000000000000..fec85c464145942708288012269c18b1ef84177d --- /dev/null +++ b/test/storytest/test_enum/test.js @@ -0,0 +1,41 @@ +/* +* 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 { fun1, fun2 } = require("./out/build/Release/napitest") +var assert = require("assert"); + +describe('String', function () { + var GrantStatus = { + PERMISSION_DEFAULT: "", + PERMISSION_DENIED: "-1", + PERMISSION_GRANTED: "2", + PERMISSION_PASS: "3", + } + var HttpStatus = { + STATUS0: 0, + STATUS1: 500, + STATUS2: 503, + } + + it('test fun1', function () { + let ret = fun1(GrantStatus.PERMISSION_DENIED); + assert.strictEqual(ret, HttpStatus.STATUS0); + }); + + it('test fun2', function () { + let ret = fun2(HttpStatus.STATUS1); + assert.strictEqual(ret, GrantStatus.PERMISSION_DEFAULT); + }); +}); +