diff --git a/OAT.xml b/OAT.xml index 2c7675cac65220f0490e708a1ea616b8021077ce..a970fb32ce50ae280d4bbabeaf82a2b9dbc83218 100644 --- a/OAT.xml +++ b/OAT.xml @@ -56,6 +56,7 @@ Note:If the text contains special characters, please escape them according to th + diff --git a/src/vscode_plugin/src/gen/genCommonFile.ts b/src/vscode_plugin/src/gen/genCommonFile.ts new file mode 100644 index 0000000000000000000000000000000000000000..3bc1b8054974ef8b0732449450763c4b409fce1b --- /dev/null +++ b/src/vscode_plugin/src/gen/genCommonFile.ts @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2025 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 * as fs from 'fs'; +import { HdfRootInfo, ServiceRootInfo } from "./datatype"; +import { replaceAll } from '../common/tool'; + +// 生成sa非特殊处理的文件, 如xxx.cfg +export function genSaCommonFile(rootInfo: ServiceRootInfo, filePath: string, fileContent: string) { + fileContent = replaceAll(fileContent, '[serviceName]', rootInfo.serviceName); + fileContent = replaceAll(fileContent, '[marcoName]', rootInfo.serviceName.toUpperCase()); + fileContent = replaceAll(fileContent, '[lowServiceName]', rootInfo.serviceName.toLowerCase()); + fileContent = replaceAll(fileContent, '[serviceId]', rootInfo.serviceId); + fs.writeFileSync(filePath, fileContent); +} + +// 生成hdf非特殊处理的文件, 如xxx.hcs +export function genHdfCommonFile(rootInfo: HdfRootInfo, filePath: string, fileContent: string) { + let upperName = rootInfo.driverName.substring(0, 1).toLocaleUpperCase(); + let marcoName = upperName + rootInfo.driverName.substring(1, rootInfo.driverName.length); + let upperDriverName = rootInfo.driverName.toLocaleUpperCase(); + fileContent = replaceAll(fileContent, '[driverName]', rootInfo.driverName); + fileContent = replaceAll(fileContent, '[marcoName]', marcoName); + fileContent = replaceAll(fileContent, '[driverUpperName]', upperDriverName); + fs.writeFileSync(filePath, fileContent); +} + diff --git a/src/vscode_plugin/src/gen/genCommonFunc.ts b/src/vscode_plugin/src/gen/genCommonFunc.ts new file mode 100644 index 0000000000000000000000000000000000000000..98c9eb463cb0aeb6d742bbae8dc548af15b81265 --- /dev/null +++ b/src/vscode_plugin/src/gen/genCommonFunc.ts @@ -0,0 +1,104 @@ +/* +* Copyright (c) 2025 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 { getTab } from '../common/tool'; +import { getReg, match } from '../common/re'; +import { format } from 'util' +import { FuncObj, ParamObj } from './datatype'; +import { transferMap } from '../template/functypemap_template' + +export function getFuncParamStr(params: ParamObj[]) { + let paramStr = ''; + for (let i = 0; i < params.length; ++i) { + paramStr += (i === 0) ? '' : ', '; + paramStr += params[i].type + ' ' + params[i].name; + } + return paramStr; +} + +// 生成头文件中的方法声明内容 +export function genDeclareContent(funcList: FuncObj[]) { + let funcTab = getTab(1); + let saFuncHContent = ''; + for (let i = 0; i < funcList.length; ++i) { + let paramStr = getFuncParamStr(funcList[i].parameters); + // proxy.h中的方法定义 + saFuncHContent += (i === 0) ? '' : '\n' + funcTab; + saFuncHContent += format('%s %s(%s) override;', funcList[i].returns, funcList[i].name, paramStr); + } + return saFuncHContent; +} + +// 常用类型转换表, 将C语言常见类型(key)转换为remote data读写函数使用的类型(value) +// 例如 ErrCode 类型在框架中的系统原型为int类型,这里映射成int32_t, +// 因为int32_t类型在 DATA_W_MAP/DATA_R_MAP 表中有对应的读写数据方法(WriteInt32/ReadInt32) +const TYPE_DEF_MAP = new Map( + [['ErrCode', 'int32_t'], ['char', 'int8_t'], ['short', 'int16_t'], ['int', 'int32_t'], ['long', 'int64_t'], + ['unsigned char', 'uint8_t'], ['unsigned short', 'uint16_t'], ['unsigned int', 'uint32_t'], + ['unsigned long', 'uint64_t'], ['double_t', 'double'], ['float_t', 'float'], ['size_t', 'double'], + ['long long', 'double'], ['long double', 'double'], ['std::string', 'string'] + ]); + +function getParcelType(srcType: string) { + let parcelType = TYPE_DEF_MAP.get(srcType); + return parcelType === undefined ? srcType : parcelType; +} + +function getTransferContent(parcelVecType: string, isWrite: number) { + let rwFunc = ''; + for (let index = 0; index < transferMap.length; index++) { + if (parcelVecType === transferMap[index].fromType) { + rwFunc = transferMap[index].tranferContent[isWrite]; + } + } + return rwFunc; +} + +export function genWrite(srcName: string, parcelName: string, vType: string) { + let matchs = match('(std::)?vector<([\x21-\x7e]+)[ ]?>', vType); + if (matchs) { + // vector类型变量包装成parcel data + let rawType = getReg(vType, matchs.regs[2]); + let parcelVecType = 'vector<' + getParcelType(rawType) + '>'; + let wVecFunc = getTransferContent(parcelVecType, 0); + if (wVecFunc === '') { + return ''; + } + return format('%s.%s(%s);', parcelName, wVecFunc, srcName); + } + + let parcelType = getParcelType(vType); + let wFunc = getTransferContent(parcelType, 0); + + return format('%s.%s(%s);', parcelName, wFunc, srcName); +} + +export function genRead(parcelName: string, destObj: ParamObj) { + let matchs = match('(std::)?vector<([\x21-\x7e]+)[ ]?>', destObj.type); + if (matchs) { + // 从parcel data中读取vector类型变量 + let rawType = getReg(destObj.type, matchs.regs[2]); + let parcelVecType = getParcelType(rawType); + let rVecFunc = 'vector<' + getTransferContent(parcelVecType, 1) + '>'; + if (rVecFunc === '') { + return ''; + } + return format('%s.%s(&(%s));', parcelName, rVecFunc, parcelName); + } + + let parcelType = getParcelType(destObj.type); + let rFunc = getTransferContent(parcelType, 1); + return format('%s = %s.%s();', destObj.name, parcelName, rFunc); +} \ No newline at end of file diff --git a/src/vscode_plugin/src/gen/genclientcppfile.ts b/src/vscode_plugin/src/gen/genclientcppfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..3d6f92f9230f8d462e6302d113eee318c458c793 --- /dev/null +++ b/src/vscode_plugin/src/gen/genclientcppfile.ts @@ -0,0 +1,46 @@ + +/* +* Copyright (c) 2025 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 { replaceAll, getTab } from '../common/tool'; +import * as fs from 'fs'; +import { format } from 'util' +import { FuncObj, ParamObj, ServiceRootInfo } from './datatype'; + +function getClientFuncParamStr(params: ParamObj[]) { + let paramStr = ''; + for (let i = 0; i < params.length; ++i) { + paramStr += (i === 0) ? '' : ', '; + paramStr += params[i].name; + } + return paramStr; +} + +// 生成xxx_client.cpp +export function genClientCppFile(rootInfo: ServiceRootInfo, filePath: string, fileContent: string) { + let clientFuncCpp = ''; + let funcList: FuncObj[] = rootInfo.funcs; + let funcTab = getTab(1); + for (let i = 0; i < funcList.length; ++i) { + let clientParamStr = getClientFuncParamStr(funcList[i].parameters); + clientFuncCpp += (i === 0) ? '' : '\n' + funcTab; + clientFuncCpp += format('// proxy->%s(%s);', funcList[i].name, clientParamStr); + } + fileContent = replaceAll(fileContent, '[serviceName]', rootInfo.serviceName); + fileContent = replaceAll(fileContent, '[marcoName]', rootInfo.serviceName.toUpperCase()); + fileContent = replaceAll(fileContent, '[lowServiceName]', rootInfo.serviceName.toLowerCase()); + fileContent = replaceAll(fileContent, '[clientFuncInvoke]', clientFuncCpp); + fs.writeFileSync(filePath, fileContent); +} \ No newline at end of file diff --git a/src/vscode_plugin/src/gen/genhdf.ts b/src/vscode_plugin/src/gen/genhdf.ts index 1b1bf2d8c92764e4da11e31ac95882b46348aed7..a982393070e74ea43b3f1d934b864e15b4ebebf3 100644 --- a/src/vscode_plugin/src/gen/genhdf.ts +++ b/src/vscode_plugin/src/gen/genhdf.ts @@ -15,191 +15,61 @@ import * as path from 'path'; import * as fs from 'fs'; -import { DirTemp, FuncObj, HdfRootInfo } from "./datatype"; -import { hdf4_1dir } from '../template/hdf/hdfdir'; -import { idlTransferType } from '../template/functypemap_template'; -import { format } from 'util'; -import { getTab, replaceAll } from '../common/tool'; -import { hdiServiceFuncTemplate } from '../template/func_template'; - - -// 常用类型转换表, 将C语言常见类型(key)转换为remote data读写函数使用的类型(value) -// 例如 ErrCode 类型在框架中的系统原型为int类型,这里映射成int32_t, -// 因为int32_t类型在 DATA_W_MAP/DATA_R_MAP 表中有对应的读写数据方法(WriteInt32/ReadInt32) -const TYPE_DEF_MAP = new Map( - [['std::string', 'string'], ['char *', 'string'] -]); - -interface GenResult { - // idl文件中方法的定义 - idlFuncDefine: string, - // xxx_interface_service.h文件中方法的定义 - hdiServiceFuncH: string, - // xxx_interface_service.cpp中方法的实现 - hdiServiceFuncCpp: string, -} - -let nameObj = { - marcoName: '', - upperDriverName: '' -} - -function getParcelType(srcType: string) { - let parcelType = TYPE_DEF_MAP.get(srcType); - return parcelType === undefined ? srcType : parcelType; -} - -function replaceContent(fileContent: string, funcContent: GenResult, rootInfo: HdfRootInfo) { - fileContent = replaceAll(fileContent, '[driverName]', rootInfo.driverName); - fileContent = replaceAll(fileContent, '[marcoName]', nameObj.marcoName); - fileContent = replaceAll(fileContent, '[driverUpperName]', nameObj.upperDriverName); - - // 替换方法的[xxx]模板 - fileContent = replaceAll(fileContent, '[idlFunDeclare]', funcContent.idlFuncDefine); - fileContent = replaceAll(fileContent, '[serviceFuncDeclare]', funcContent.hdiServiceFuncH); - fileContent = replaceAll(fileContent, '[serviceFuncListImpl]', funcContent.hdiServiceFuncCpp); - - return fileContent; -} +import { DirTemp, HdfRootInfo } from "./datatype"; +import { hdf_version_map } from '../template/hdf/hdfdir'; +import { genIdlFile } from './genidlfile'; +import { genServiceHFile } from './genservicehfile'; +import { genServiceCppFile } from './genservicecppfile'; +import { genHdfCommonFile } from './genCommonFile'; + +const fileHandlers: { [key: string]: Function } = { + 'I[marcoName]Interface.idl': genIdlFile, + '[driverName]_interface_service.h': genServiceHFile, + '[driverName]_interface_service.cpp': genServiceCppFile, + '[driverName]_interface_driver.cpp': genHdfCommonFile, + 'BUILD.gn': genHdfCommonFile, + 'bundle.json': genHdfCommonFile, + 'hello_dump.h': genHdfCommonFile, + 'hello_dump.c': genHdfCommonFile, + 'device_info.hcs': genHdfCommonFile, + 'readme.md': genHdfCommonFile, +}; // 循环写入文件, 并将funcContent的内容写入模板 -function genDir(dirItem: DirTemp, funcContent: GenResult, rootInfo: HdfRootInfo, out: string) -{ +function genDir(dirItem: DirTemp, rootInfo: HdfRootInfo, out: string) { let dirPath = path.join(out, dirItem.name.replace('[driverName]', rootInfo.driverName)); - // 创建目录 if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); - } - - // 遍历文件 + } + // 生成当前目录文件 dirItem.files.forEach(file => { let fileName = file.name.replace('[driverName]', rootInfo.driverName); - fileName = fileName.replace('[marcoName]', nameObj.marcoName); + let upperName = rootInfo.driverName.substring(0, 1).toLocaleUpperCase(); + let marcoName = upperName + rootInfo.driverName.substring(1, rootInfo.driverName.length); + fileName = fileName.replace('[marcoName]', marcoName); let filePath = path.join(dirPath, fileName); - // 将content写入文件, 这里的content是模板,需要replace里面的部分内容 if (!fs.existsSync(filePath)) { - // replace file content - // 这里的替换是替换模板公共的东西,方法的替换在哪里生成呢? - let fileContent = replaceContent(file.content, funcContent, rootInfo) - fs.writeFileSync(filePath, fileContent); + const handler = fileHandlers[file.name]; + if (handler) { + // 调用对应的生成文件方法 + handler(rootInfo, filePath, file.content); + } } }) - - // 递归遍历子目录 + // 遍历生成子目录文件 dirItem.dirs.forEach(subDir => { - genDir(subDir, funcContent, rootInfo, dirPath); + genDir(subDir, rootInfo, dirPath); }) } -// idlTransferType -function getIdlType(cType: string) { - let rawType = getParcelType(cType); - for (let index = 0; index < idlTransferType.length; index++) { - if (rawType === idlTransferType[index].fromType) { - return idlTransferType[index].tranferContent; - } - } - return cType; -} - -function isReturn(type: string) { - console.log('isReturn in type: ', type); - if (type) { - if (type.indexOf('&')>0 || type.indexOf('**')>0) { - return true; - } - } - return false; -} - -function getIdlFuncParamStr(funcObj: FuncObj) { - let idlParams = ''; - for (let i = 0; i < funcObj.parameters.length; ++i) { - let type = getIdlType(funcObj.parameters[i].type); - // idlParams += (i === 0) && (funcObj.returns !== 'void') ? '' : ', '; - if (isReturn(funcObj.parameters[i].type)) { - idlParams += '[out] ' + type + ' ' + funcObj.parameters[i].name + ', '; - } else { - idlParams += '[in] ' + type + ' ' + funcObj.parameters[i].name + ', '; - } - } - if (funcObj.returns !== 'void') { - let retType = getIdlType(funcObj.returns); - let outName = funcObj.name + 'Out' - idlParams += '[out] ' + retType + ' ' + outName; - } else { - // 如果返回值是void, 去掉参数列表结尾逗号 - idlParams = idlParams.substring(0, idlParams.length - 2); - } - - return idlParams; -} - -// 生成方法实现 -function getServiceFuncParamStr(funcObj: FuncObj) { - let paramStr = ''; - for (let i = 0; i < funcObj.parameters.length; ++i) { - // paramStr += (i === 0) ? '' : ', '; - // paramStr += funcObj.parameters[i].type + ' ' + funcObj.parameters[i].name + ', '; - paramStr += format('const %s& %s, ', funcObj.parameters[i].type, funcObj.parameters[i].name); - } - if (funcObj.returns !== 'void') { - let outName = funcObj.name + 'Out' - if (funcObj.returns === 'string') { - funcObj.returns = 'std::string'; - } - paramStr += funcObj.returns + '& ' + outName; - } else { - // 如果返回值是void, 去掉参数列表结尾逗号 - paramStr = paramStr.substring(0, paramStr.length - 2); - } - return paramStr; -} - -function generateFunctionCode(rootInfo: HdfRootInfo) { - let funcList: FuncObj[] = rootInfo.funcs; - // 分析方法列表,并返回方法 - let genResult: GenResult = { - idlFuncDefine: '', - hdiServiceFuncH: '', - hdiServiceFuncCpp: '', - } - let funcTab = getTab(1); - for (let i = 0; i < funcList.length; ++i) { - - // 生成idl接口定义 - let paramIdlStr = getIdlFuncParamStr(funcList[i]); - genResult.idlFuncDefine += (i === 0) ? '' : '\n' + funcTab; - genResult.idlFuncDefine += format('%s(%s);', funcList[i].name, paramIdlStr); - - // 生成方法的定义与实现 - // xxx_interface_service.h方法定义 - let paramStr = getServiceFuncParamStr(funcList[i]); - genResult.hdiServiceFuncH += (i === 0) ? '' : '\n' + funcTab; - genResult.hdiServiceFuncH += format('int32_t %s(%s) override;', funcList[i].name, paramStr) - - // xxx_interface_service.cpp的实现 - let serviceCppContent = replaceAll(hdiServiceFuncTemplate, '[functionName]', funcList[i].name); - serviceCppContent = replaceAll(serviceCppContent, '[marcoName]', nameObj.marcoName); - genResult.hdiServiceFuncCpp = replaceAll(serviceCppContent, '[params]', paramStr); - } - - return genResult; -} - export function genHdfFile(rootInfo: HdfRootInfo, out: string) { console.info("rootInfo: " + JSON.stringify(rootInfo)) - let upperName = rootInfo.driverName.substring(0,1).toLocaleUpperCase(); - nameObj.marcoName = upperName + rootInfo.driverName.substring(1, rootInfo.driverName.length); - nameObj.upperDriverName = rootInfo.driverName.toLocaleUpperCase(); - - // 获取方法相关 - let res: GenResult = generateFunctionCode(rootInfo); - - // 生成文件 和 文件夹 - genDir(hdf4_1dir, res, rootInfo, out); + let dirContentTemplete = hdf_version_map.get(rootInfo.versionTag); + if (dirContentTemplete !== undefined) { + genDir(dirContentTemplete, rootInfo, out); + } console.info('generate success!') } \ No newline at end of file diff --git a/src/vscode_plugin/src/gen/genidlfile.ts b/src/vscode_plugin/src/gen/genidlfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..ed573f51e6bf6afe6c3e05ba40fe3db15c0445b2 --- /dev/null +++ b/src/vscode_plugin/src/gen/genidlfile.ts @@ -0,0 +1,93 @@ +/* +* Copyright (c) 2025 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 * as fs from 'fs'; +import { FuncObj, HdfRootInfo } from "./datatype"; +import { idlTransferType } from '../template/functypemap_template'; +import { format } from 'util'; +import { getTab, replaceAll } from '../common/tool'; + +// 常用类型转换表, 将C语言常见类型(key)转换为remote data读写函数使用的类型(value) +// 例如 ErrCode 类型在框架中的系统原型为int类型,这里映射成int32_t, +// 因为int32_t类型在 DATA_W_MAP/DATA_R_MAP 表中有对应的读写数据方法(WriteInt32/ReadInt32) +const TYPE_DEF_MAP = new Map( + [['std::string', 'string'], ['char *', 'string'] +]); + +function getParcelType(srcType: string) { + let parcelType = TYPE_DEF_MAP.get(srcType); + return parcelType === undefined ? srcType : parcelType; +} + +// idlTransferType +function getIdlType(cType: string) { + let rawType = getParcelType(cType); + for (let index = 0; index < idlTransferType.length; index++) { + if (rawType === idlTransferType[index].fromType) { + return idlTransferType[index].tranferContent; + } + } + return cType; +} + +function isReturn(type: string) { + if (type) { + if (type.indexOf('&')>0 || type.indexOf('**')>0) { + return true; + } + } + return false; +} + +function getIdlFuncParamStr(funcObj: FuncObj) { + let idlParams = ''; + for (let i = 0; i < funcObj.parameters.length; ++i) { + let type = getIdlType(funcObj.parameters[i].type); + // idlParams += (i === 0) && (funcObj.returns !== 'void') ? '' : ', '; + if (isReturn(funcObj.parameters[i].type)) { + idlParams += '[out] ' + type + ' ' + funcObj.parameters[i].name + ', '; + } else { + idlParams += '[in] ' + type + ' ' + funcObj.parameters[i].name + ', '; + } + } + if (funcObj.returns !== 'void') { + let retType = getIdlType(funcObj.returns); + let outName = funcObj.name + 'Out' + idlParams += '[out] ' + retType + ' ' + outName; + } else { + // 如果返回值是void, 去掉参数列表结尾逗号 + idlParams = idlParams.substring(0, idlParams.length - 2); + } + return idlParams; +} + +// 每个方法一个文件 +export function genIdlFile(rootInfo: HdfRootInfo, filePath: string, fileContent: string) { + let funcTab = getTab(1); + let idlFuncDefine = ''; + let funcList: FuncObj[] = rootInfo.funcs; + for (let i = 0; i < funcList.length; ++i) { + // 生成idl接口定义 + let paramIdlStr = getIdlFuncParamStr(funcList[i]); + idlFuncDefine += (i === 0) ? '' : '\n' + funcTab; + idlFuncDefine += format('%s(%s);', funcList[i].name, paramIdlStr); + } + let upperName = rootInfo.driverName.substring(0, 1).toLocaleUpperCase(); + let marcoName = upperName + rootInfo.driverName.substring(1, rootInfo.driverName.length); + fileContent = replaceAll(fileContent, '[driverName]', rootInfo.driverName); + fileContent = replaceAll(fileContent, '[marcoName]', marcoName); + fileContent = replaceAll(fileContent, '[idlFunDeclare]', idlFuncDefine); + fs.writeFileSync(filePath, fileContent); +} \ No newline at end of file diff --git a/src/vscode_plugin/src/gen/geniservicehfile.ts b/src/vscode_plugin/src/gen/geniservicehfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..b498ca3512dd8138284f1aef6f93c44e96de72a0 --- /dev/null +++ b/src/vscode_plugin/src/gen/geniservicehfile.ts @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2025 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 { replaceAll, getTab } from '../common/tool'; +import * as fs from 'fs'; +import { format } from 'util' +import { FuncObj, ServiceRootInfo } from './datatype'; +import { getFuncParamStr } from './genCommonFunc'; + +export function genIServiceHFile(rootInfo: ServiceRootInfo, filePath: string, fileContent: string) { + let iServiceFuncH = ''; + let funcEnumStr = ''; + let funcList: FuncObj[] = rootInfo.funcs; + let funcTab = getTab(1); + let enumTab = getTab(2); + for (let i = 0; i < funcList.length; ++i) { + let funcEnum = funcList[i].name.toUpperCase(); + let paramStr = getFuncParamStr(funcList[i].parameters); + iServiceFuncH += (i === 0) ? '' : '\n' + funcTab; + iServiceFuncH += format('virtual %s %s(%s) = 0;', funcList[i].returns, funcList[i].name, paramStr); + funcEnumStr += (i === 0) ? '' : ',\n' + enumTab; + funcEnumStr += funcEnum; + } + fileContent = replaceAll(fileContent, '[serviceName]', rootInfo.serviceName); + fileContent = replaceAll(fileContent, '[marcoName]', rootInfo.serviceName.toUpperCase()); + fileContent = replaceAll(fileContent, '[funcEnum]', funcEnumStr); + fileContent = replaceAll(fileContent, '[iServiceHFunctions]', iServiceFuncH); + fs.writeFileSync(filePath, fileContent); +} \ No newline at end of file diff --git a/src/vscode_plugin/src/gen/genproxycppfile.ts b/src/vscode_plugin/src/gen/genproxycppfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..9df530625890d7415c5b5b9808f43a8fba3be23d --- /dev/null +++ b/src/vscode_plugin/src/gen/genproxycppfile.ts @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2025 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 { getTab, replaceAll } from '../common/tool'; +import * as fs from 'fs'; +import { format } from 'util' +import { FuncObj, ParamObj, ServiceRootInfo } from './datatype'; +import { genRead, genWrite, getFuncParamStr } from './genCommonFunc'; +import { proxyFuncTemplate } from '../template/func_template'; + +function genProxyFunc(funcInfo: FuncObj, className: string, paramStr: string, funcEnum: string) { + let proxyFunc = replaceAll(proxyFuncTemplate, '[serviceName]', className); + proxyFunc = replaceAll(proxyFunc, '[funcName]', funcInfo.name); + proxyFunc = replaceAll(proxyFunc, '[params]', paramStr); + proxyFunc = replaceAll(proxyFunc, '[retType]', funcInfo.returns); + proxyFunc = replaceAll(proxyFunc, '[funcEnum]', funcEnum); + + // 入参处理 + let writeDataStr = ''; + let tab = getTab(1); + for (let i = 0; i < funcInfo.parameters.length; ++i) { + let param = funcInfo.parameters[i]; + writeDataStr += (i === 0) ? '' : '\n' + tab; + writeDataStr += genWrite(param.name, 'data', param.type) + } + proxyFunc = replaceAll(proxyFunc, '[writeData]', writeDataStr); + + // 返回值处理 + let readReplyStr = ''; + if (funcInfo.returns !== 'void') { + readReplyStr = format('%s result;', funcInfo.returns); + let destObj: ParamObj = { + 'name': 'result', + 'type': funcInfo.returns, + 'arraySize': -1, + }; + readReplyStr += '\n' + tab + genRead('reply', destObj); + readReplyStr += '\n' + tab + 'return result;'; + } + proxyFunc = replaceAll(proxyFunc, '[readReply]', readReplyStr); + + return proxyFunc; +} + +// 生成 xxx_service_proxy.cpp +export function genProxyCppFile(rootInfo: ServiceRootInfo, filePath: string, fileContent: string) { + let funcList: FuncObj[] = rootInfo.funcs; + let proxyFuncCpp = ''; + for (let i = 0; i < funcList.length; ++i) { + let funcEnum = funcList[i].name.toUpperCase(); + let paramStr = getFuncParamStr(funcList[i].parameters); + // proxy.cpp中的方法实现 + proxyFuncCpp += genProxyFunc(funcList[i], rootInfo.serviceName, paramStr, funcEnum); + } + fileContent = replaceAll(fileContent, '[serviceName]', rootInfo.serviceName); + fileContent = replaceAll(fileContent, '[marcoName]', rootInfo.serviceName.toUpperCase()); + fileContent = replaceAll(fileContent, '[lowServiceName]', rootInfo.serviceName.toLowerCase()); + fileContent = replaceAll(fileContent, '[remoteFuncImpl]', proxyFuncCpp); + fs.writeFileSync(filePath, fileContent); +} \ No newline at end of file diff --git a/src/vscode_plugin/src/gen/genproxyhfile.ts b/src/vscode_plugin/src/gen/genproxyhfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..0df4d1884f521376bbbcb0f83ab095328f03427c --- /dev/null +++ b/src/vscode_plugin/src/gen/genproxyhfile.ts @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2025 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 { replaceAll } from '../common/tool'; +import * as fs from 'fs'; +import { FuncObj, ServiceRootInfo } from './datatype'; +import { genDeclareContent } from './genCommonFunc'; + +// 生成 xxx_service_proxy.h +export function genProxyHFile(rootInfo: ServiceRootInfo, filePath: string, fileContent: string) { + let funcList: FuncObj[] = rootInfo.funcs; + let proxyFuncHContent = genDeclareContent(funcList); + fileContent = replaceAll(fileContent, '[serviceName]', rootInfo.serviceName); + fileContent = replaceAll(fileContent, '[marcoName]', rootInfo.serviceName.toUpperCase()); + fileContent = replaceAll(fileContent, '[lowServiceName]', rootInfo.serviceName.toLowerCase()); + fileContent = replaceAll(fileContent, '[proxyHFunctions]', proxyFuncHContent); + fs.writeFileSync(filePath, fileContent); +} \ No newline at end of file diff --git a/src/vscode_plugin/src/gen/gensa.ts b/src/vscode_plugin/src/gen/gensa.ts index 1a2c83a935f36d3fe790caa2ff9be87b31e0f261..7cdd108f7cb0f4fec27f24a0b0bb86b3c7b327ce 100644 --- a/src/vscode_plugin/src/gen/gensa.ts +++ b/src/vscode_plugin/src/gen/gensa.ts @@ -14,360 +14,71 @@ * limitations under the License. */ -import { replaceAll, getTab } from '../common/tool'; -import { getReg, match } from '../common/re'; -const numericTypes = ['short', 'int', 'long', 'long long', 'float', 'double']; -const boolType = ['bool']; -const charType = ['char', 'string']; -import { service4_1_dir, service3_2_dir } from '../template/sa/sadir'; -import { proxyFuncTemplate, stubInnerFuncTemplate, serviceFuncImplTemplate } from '../template/func_template'; +import { sa_version_map } from '../template/sa/sadir'; import * as path from 'path'; import * as fs from 'fs'; -import { format } from 'util' -import { DirTemp, FuncObj, ParamObj, ServiceRootInfo } from './datatype'; -import { transferMap } from '../template/functypemap_template' - -// 常用类型转换表, 将C语言常见类型(key)转换为remote data读写函数使用的类型(value) -// 例如 ErrCode 类型在框架中的系统原型为int类型,这里映射成int32_t, -// 因为int32_t类型在 DATA_W_MAP/DATA_R_MAP 表中有对应的读写数据方法(WriteInt32/ReadInt32) -const TYPE_DEF_MAP = new Map( - [['ErrCode', 'int32_t'], ['char', 'int8_t'], ['short', 'int16_t'], ['int', 'int32_t'], ['long', 'int64_t'], - ['unsigned char', 'uint8_t'], ['unsigned short', 'uint16_t'], ['unsigned int', 'uint32_t'], - ['unsigned long', 'uint64_t'], ['double_t', 'double'], ['float_t', 'float'], ['size_t', 'double'], - ['long long', 'double'], ['long double', 'double'], ['std::string', 'string'] -]); - -interface DestObj { - name: string, - type: string, -} - -interface GenResult { - funcEnumStr: string, - // i_service.h 方法定义 - iServiceFuncH: string, - // proxy.h 方法定义 - proxyFuncH: string, - // stub.h 的inner方法定义 - stubInnerFuncH: string, - // proxy.cpp 方法实现 - proxyFuncCpp: string, - // stub.cpp 的inner方法映射表 - stubInnerFuncMap: string, - // stub.cpp 的inner方法实现 - stubInnerFuncCpp: string, - // service.cpp的方法实现: 参数初始化 - serviceFuncCpp: string, - // client.cpp 的inner方法定义 - clientFuncCpp: string, +import { DirTemp, ServiceRootInfo } from './datatype'; +import { genProxyHFile } from './genproxyhfile'; +import { genProxyCppFile } from './genproxycppfile'; +import { genSaHFile } from './gensahfile'; +import { genSaCppFile } from './gensacppfile'; +import { genIServiceHFile } from './geniservicehfile'; +import { genStubHFile } from './genstubhfile'; +import { genStubCppFile } from './genstubcppfile'; +import { genClientCppFile } from './genclientcppfile'; +import { genSaCommonFile } from './genCommonFile'; + +const fileHandlers: { [key: string]: Function } = { + '[serviceName]_service_proxy.h': genProxyHFile, + '[serviceName]_service_proxy.cpp': genProxyCppFile, + '[serviceName]_service.h': genSaHFile, + '[serviceName]_service.cpp': genSaCppFile, + 'i_[serviceName]_service.h': genIServiceHFile, + '[serviceName]_service_stub.h': genStubHFile, + '[serviceName]_service_stub.cpp': genStubCppFile, + '[serviceName]_client.cpp': genClientCppFile, + 'BUILD.gn': genSaCommonFile, + 'bundle.json': genSaCommonFile, + '[serviceName]_service.cfg': genSaCommonFile, + '[serviceId].json': genSaCommonFile, + '[serviceId].xml': genSaCommonFile, + 'readme.md': genSaCommonFile }; -function getParcelType(srcType: string) { - let parcelType = TYPE_DEF_MAP.get(srcType); - return parcelType === undefined ? srcType : parcelType; -} - -function getFuncParamStr(params: ParamObj[]) { - let paramStr = ''; - for (let i = 0; i < params.length; ++i) { - paramStr += (i === 0) ? '' : ', '; - paramStr += params[i].type + ' ' + params[i].name; - } - return paramStr; -} - -function getClientFuncParamStr(params: ParamObj[]) { - let paramStr = ''; - for (let i = 0; i < params.length; ++i) { - paramStr += (i === 0) ? '' : ', '; - paramStr += params[i].name; - } - return paramStr; -} - -function getTransferContent(parcelVecType: string, isWrite: number) { - let rwFunc = ''; - for (let index = 0; index < transferMap.length; index++) { - if (parcelVecType === transferMap[index].fromType) { - rwFunc = transferMap[index].tranferContent[isWrite]; - } - } - return rwFunc; -} - -function genWrite(srcName: string, parcelName: string, vType: string) { - let matchs = match('(std::)?vector<([\x21-\x7e]+)[ ]?>', vType); - if (matchs) { - // vector类型变量包装成parcel data - let rawType = getReg(vType, matchs.regs[2]); - let parcelVecType = 'vector<' + getParcelType(rawType) + '>'; - let wVecFunc = getTransferContent(parcelVecType, 0); - if (wVecFunc === '') { - return ''; - } - return format('%s.%s(%s);', parcelName, wVecFunc, srcName); - } - - let parcelType = getParcelType(vType); - let wFunc = getTransferContent(parcelType, 0); - - return format('%s.%s(%s);', parcelName, wFunc, srcName); -} - -function genRead(parcelName: string, destObj: DestObj) { - let matchs = match('(std::)?vector<([\x21-\x7e]+)[ ]?>', destObj.type); - if (matchs) { - // 从parcel data中读取vector类型变量 - let rawType = getReg(destObj.type, matchs.regs[2]); - let parcelVecType = getParcelType(rawType); - let rVecFunc = 'vector<' + getTransferContent(parcelVecType, 1) + '>'; - if (rVecFunc === '') { - return ''; - } - return format('%s.%s(&(%s));', parcelName, rVecFunc, parcelName); - } - - let parcelType = getParcelType(destObj.type); - let rFunc = getTransferContent(parcelType, 1); - return format('%s = %s.%s();', destObj.name, parcelName, rFunc); -} - -function genProxyFunc(funcInfo: FuncObj, className: string, paramStr: string, funcEnum: string) { - let proxyFunc = replaceAll(proxyFuncTemplate, '[serviceName]', className); - proxyFunc = replaceAll(proxyFunc, '[funcName]', funcInfo.name); - proxyFunc = replaceAll(proxyFunc, '[params]', paramStr); - proxyFunc = replaceAll(proxyFunc, '[retType]', funcInfo.returns); - proxyFunc = replaceAll(proxyFunc, '[funcEnum]', funcEnum); - - // 入参处理 - let writeDataStr = ''; - let tab = getTab(1); - for (let i = 0; i < funcInfo.parameters.length; ++i) { - let param = funcInfo.parameters[i]; - writeDataStr += (i === 0) ? '' : '\n' + tab; - writeDataStr += genWrite(param.name, 'data', param.type) - } - proxyFunc = replaceAll(proxyFunc, '[writeData]', writeDataStr); - - // 返回值处理 - let readReplyStr = ''; - if (funcInfo.returns !== 'void') { - readReplyStr = format('%s result;', funcInfo.returns); - let destObj: DestObj = { - 'name': 'result', - 'type': funcInfo.returns - }; - readReplyStr += '\n' + tab + genRead('reply', destObj); - readReplyStr += '\n' + tab + 'return result;'; - } - proxyFunc = replaceAll(proxyFunc, '[readReply]', readReplyStr); - - return proxyFunc; -} - -function genStubInnerFunc(funcInfo: FuncObj, className: string) { - let innerFunc = replaceAll(stubInnerFuncTemplate, '[serviceName]', className); - innerFunc = replaceAll(innerFunc, '[funcName]', funcInfo.name); - - // 入参处理 - // 生成服务端读取客户端传参的代码段 - let readDataStr = ''; - let tab = getTab(1); - // 调用业务方法时传入的入参列表 - let innerParamStr = ''; - for (let i = 0; i < funcInfo.parameters.length; ++i) { - let param = funcInfo.parameters[i]; - let innerParamName = param.name + 'Val'; - if (i > 0) { - readDataStr += '\n' + tab; - innerParamStr += ' ,'; - } - - //将remote请求中的参数值读取到内部参数变量中 - // 定义内部参数变量 - readDataStr += format('%s %s;', param.type, innerParamName); - let destObj = { - 'name': param.name + 'Val', - 'type': param.type - }; - readDataStr += '\n' + tab + genRead('data', destObj); - innerParamStr += innerParamName; - } - innerFunc = replaceAll(innerFunc, '[readData]', readDataStr); - - // 调用service的实际业务逻辑实现方法 - // 生成调用服务端实现并返回结果的代码段 - let writeReplyStr = ''; - if (funcInfo.returns === 'void') { - writeReplyStr += format('%s(%s); // call business implementation', funcInfo.name, innerParamStr); - writeReplyStr += '\n' + tab + 'reply.WriteInt32(retCode);'; - } else { - writeReplyStr += format('%s retVal = %s(%s); // call business implementation', - funcInfo.returns, funcInfo.name, innerParamStr); - writeReplyStr += '\n' + tab + 'reply.WriteInt32(retCode);'; - writeReplyStr += '\n' + tab + genWrite('retVal', 'reply', funcInfo.returns); - } - innerFunc = replaceAll(innerFunc, '[writeReply]', writeReplyStr); - return innerFunc; -} - -function genServiceFunc(funcInfo: FuncObj, className: string, paramStr: string) { - let serviceFunc = replaceAll(serviceFuncImplTemplate, '[retType]', funcInfo.returns); - // 根据类型初始化返回值 - let initRetvalue; - // let paramsName = ''; - if (numericTypes.includes(funcInfo.returns)) { - // 数值类型初始化为0 - initRetvalue = '0'; - } else if (boolType.includes(funcInfo.returns)) { - // 布尔类型初始化为true - initRetvalue = 'true'; - } else if (charType.includes(funcInfo.returns)) { - // 字符类型初始化为空字符'' - initRetvalue = ''; - } else { - // 对于其他类型,这里可以根据需要进行处理 - // 假设是指针类型或其他复杂类型 - initRetvalue = 'nullptr'; - }8 - serviceFunc = replaceAll(serviceFunc, '[initRetvalue]', initRetvalue); - serviceFunc = replaceAll(serviceFunc, '[serviceName]', className); - serviceFunc = replaceAll(serviceFunc, '[funcName]', funcInfo.name); - serviceFunc = replaceAll(serviceFunc, '[params]', paramStr); - return serviceFunc; -} - -function generateFunctionCode(rootInfo: ServiceRootInfo) { - let funcList: FuncObj[] = rootInfo.funcs; - let genResult: GenResult = { - funcEnumStr:'', - // i_service.h 方法定义 - iServiceFuncH: '', - // proxy.h 方法定义 - proxyFuncH: '', - // stub.h 的inner方法定义 - stubInnerFuncH: '', - // proxy.cpp 方法实现 - proxyFuncCpp: '', - // stub.cpp 的inner方法映射表 - stubInnerFuncMap: '', - // stub.cpp 的inner方法实现 - stubInnerFuncCpp: '', - // service.cpp的方法实现: 参数初始化 - serviceFuncCpp: '', - // client.cpp 的inner方法定义 - clientFuncCpp: '', - }; - let enumTab = getTab(2); - let funcTab = getTab(1); - - for (let i = 0; i < funcList.length; ++i) { - // remote方法的枚举值 - let funcEnum = funcList[i].name.toUpperCase(); - // 生成proxy端的方法 - let paramStr = getFuncParamStr(funcList[i].parameters); - // proxy.h中的方法定义 - genResult.proxyFuncH += (i === 0) ? '' : '\n' + funcTab; - genResult.proxyFuncH += format('%s %s(%s) override;', funcList[i].returns, funcList[i].name, paramStr); - // proxy.cpp中的方法实现 - genResult.proxyFuncCpp += genProxyFunc(funcList[i], rootInfo.serviceName, paramStr, funcEnum); - // 生成stub端的方法 - // stub.h中的inner方法定义 - genResult.stubInnerFuncH += (i === 0) ? '' : '\n' + funcTab; - genResult.stubInnerFuncH += - format('ErrCode %sInner(MessageParcel &data, MessageParcel &reply);', funcList[i].name); - // stub.cpp中的inner方法实现 - genResult.stubInnerFuncCpp += genStubInnerFunc(funcList[i], rootInfo.serviceName); - - // stub.cpp中的inner方法映射表 - genResult.stubInnerFuncMap += format('innerFuncs_[%s] = &%sStub::%sInner;', - funcEnum, rootInfo.serviceName, funcList[i].name); - - // 生成serviceImpl的方法 - // 生成i_xxx_service.h中方法枚举 - genResult.funcEnumStr += (i === 0) ? '' : ',\n' + enumTab; - genResult.funcEnumStr += funcEnum; - // i_service.h 方法定义 - genResult.iServiceFuncH += (i === 0) ? '' : '\n' + funcTab; - genResult.iServiceFuncH += format('virtual %s %s(%s) = 0;', funcList[i].returns, funcList[i].name, paramStr); - // service.cpp中的方法实现 这里不需要有实现,对参数进行初始化即可 - genResult.serviceFuncCpp += genServiceFunc(funcList[i], rootInfo.serviceName, paramStr); - - // 生成client端的方法 - // client.cpp中的方法实现:inner方法定义 - let clientParamStr = getClientFuncParamStr(funcList[i].parameters); - genResult.clientFuncCpp += (i === 0) ? '' : '\n' + funcTab; - genResult.clientFuncCpp += format('// proxy->%s(%s);', funcList[i].name, clientParamStr); - } - - return genResult; -} - -function replaceContent(fileContent: string, funcContent: GenResult, rootInfo: ServiceRootInfo) { - let lowServiceName = rootInfo.serviceName.toLowerCase(); - let upperServiceName = rootInfo.serviceName.toUpperCase(); - fileContent = replaceAll(fileContent, '[serviceName]', rootInfo.serviceName); - fileContent = replaceAll(fileContent, '[marcoName]', upperServiceName); - fileContent = replaceAll(fileContent, '[serviceId]', rootInfo.serviceId); - fileContent = replaceAll(fileContent, '[lowServiceName]', lowServiceName); - - // 替换方法中的[xxx]模板 - fileContent = replaceAll(fileContent, '[funcEnum]', funcContent.funcEnumStr); - fileContent = replaceAll(fileContent, '[iServiceHFunctions]', funcContent.iServiceFuncH); - fileContent = replaceAll(fileContent, '[proxyHFunctions]', funcContent.proxyFuncH); - fileContent = replaceAll(fileContent, '[innerFuncDef]', funcContent.stubInnerFuncH); - fileContent = replaceAll(fileContent, '[serviceHFunctions]', funcContent.proxyFuncH); - fileContent = replaceAll(fileContent, '[remoteFuncImpl]', funcContent.proxyFuncCpp); - fileContent = replaceAll(fileContent, '[innerFuncMap]', funcContent.stubInnerFuncMap); - fileContent = replaceAll(fileContent, '[innerFuncImpl]', funcContent.stubInnerFuncCpp); - fileContent = replaceAll(fileContent, '[serviceFuncImpl]', funcContent.serviceFuncCpp); - fileContent = replaceAll(fileContent, '[clientFuncInvoke]', funcContent.clientFuncCpp); - - return fileContent; -} - -// 循环写入文件, 并将funcContent的内容写入模板 -function genDir(dirItem: DirTemp, funcContent: GenResult, rootInfo: ServiceRootInfo, out: string) -{ +// 遍历数据结构,拿到模板内容,并生成文件内容 +function genDir(dirItem: DirTemp, rootInfo: ServiceRootInfo, out: string) { let dirPath = path.join(out, dirItem.name.replace('[serviceName]', rootInfo.serviceName)); - // 创建目录 if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); - } - - // 遍历文件 + } + // 遍历生成当前目录文件 dirItem.files.forEach(file => { let fileName = file.name.replace('[serviceName]', rootInfo.serviceName); fileName = fileName.replace('[serviceId]', rootInfo.serviceId); let filePath = path.join(dirPath, fileName); // 将content写入文件, 这里的content是模板,需要replace里面的部分内容 if (!fs.existsSync(filePath)) { - // replace file content - // 这里的替换是替换模板公共的东西,方法的替换在哪里生成呢? - let fileContent = replaceContent(file.content, funcContent, rootInfo) - fs.writeFileSync(filePath, fileContent); + // 拿到每个文件并且根据文件生成内容并写入 + const handler = fileHandlers[file.name]; + if (handler) { + // 调用对应的生成文件方法 + handler(rootInfo, filePath, file.content); + } } }) - - // 递归遍历子目录 + // 遍历子目录,生成子目录的文件 dirItem.dirs.forEach(subDir => { - genDir(subDir, funcContent, rootInfo, dirPath); + genDir(subDir, rootInfo, dirPath); }) } export function genServiceFile(rootInfo: ServiceRootInfo, out: string) { console.info("rootInfo: " + JSON.stringify(rootInfo)) - // 获取方法相关 - let res: GenResult = generateFunctionCode(rootInfo); - - // 生成文件 和 文件夹 - if (rootInfo.versionTag === '4.1') { - genDir(service4_1_dir, res, rootInfo, out); - } else { - // 默认生成3.2 - genDir(service3_2_dir, res, rootInfo, out); + let dirContentTemplete = sa_version_map.get(rootInfo.versionTag); + if (dirContentTemplete !== undefined) { + genDir(dirContentTemplete, rootInfo, out); } console.info('generate success!') diff --git a/src/vscode_plugin/src/gen/gensacppfile.ts b/src/vscode_plugin/src/gen/gensacppfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..3a893d7672e883f8423590639572a34af5c9f3f9 --- /dev/null +++ b/src/vscode_plugin/src/gen/gensacppfile.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2025 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 { replaceAll } from '../common/tool'; +const numericTypes = ['short', 'int', 'long', 'long long', 'float', 'double']; +const boolType = ['bool']; +const charType = ['char', 'string']; +import { serviceFuncImplTemplate } from '../template/func_template'; +import * as fs from 'fs'; +import { FuncObj, ServiceRootInfo } from './datatype'; +import { getFuncParamStr } from './genCommonFunc'; + +function genServiceFunc(funcInfo: FuncObj, className: string, paramStr: string) { + let serviceFunc = replaceAll(serviceFuncImplTemplate, '[retType]', funcInfo.returns); + // 根据类型初始化返回值 + let initRetvalue; + // let paramsName = ''; + if (numericTypes.includes(funcInfo.returns)) { + // 数值类型初始化为0 + initRetvalue = '0'; + } else if (boolType.includes(funcInfo.returns)) { + // 布尔类型初始化为true + initRetvalue = 'true'; + } else if (charType.includes(funcInfo.returns)) { + // 字符类型初始化为空字符'' + initRetvalue = ''; + } else { + // 对于其他类型,这里可以根据需要进行处理 + // 假设是指针类型或其他复杂类型 + initRetvalue = 'nullptr'; + } + serviceFunc = replaceAll(serviceFunc, '[initRetvalue]', initRetvalue); + serviceFunc = replaceAll(serviceFunc, '[serviceName]', className); + serviceFunc = replaceAll(serviceFunc, '[funcName]', funcInfo.name); + serviceFunc = replaceAll(serviceFunc, '[params]', paramStr); + return serviceFunc; +} + +// 生成 xxx_service.cpp +export function genSaCppFile(rootInfo: ServiceRootInfo, filePath: string, fileContent: string) { + let funcList: FuncObj[] = rootInfo.funcs; + let serviceFuncCpp = ''; + for (let i = 0; i < funcList.length; ++i) { + let paramStr = getFuncParamStr(funcList[i].parameters); + serviceFuncCpp += genServiceFunc(funcList[i], rootInfo.serviceName, paramStr); + } + fileContent = replaceAll(fileContent, '[serviceName]', rootInfo.serviceName); + fileContent = replaceAll(fileContent, '[marcoName]', rootInfo.serviceName.toUpperCase()); + fileContent = replaceAll(fileContent, '[lowServiceName]', rootInfo.serviceName.toLowerCase()); + fileContent = replaceAll(fileContent, '[serviceFuncImpl]', serviceFuncCpp); + fs.writeFileSync(filePath, fileContent); +} \ No newline at end of file diff --git a/src/vscode_plugin/src/gen/gensahfile.ts b/src/vscode_plugin/src/gen/gensahfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..b5a8f9f8290c8cda06289207476262795b6f9d7c --- /dev/null +++ b/src/vscode_plugin/src/gen/gensahfile.ts @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2025 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 { replaceAll } from '../common/tool'; +import * as fs from 'fs'; +import { FuncObj, ServiceRootInfo } from './datatype'; +import { genDeclareContent } from './genCommonFunc'; + +// 生成 xxx_service.h +export function genSaHFile(rootInfo: ServiceRootInfo, filePath: string, fileContent: string) { + let funcList: FuncObj[] = rootInfo.funcs; + let saFuncHContent = genDeclareContent(funcList); + fileContent = replaceAll(fileContent, '[serviceName]', rootInfo.serviceName); + fileContent = replaceAll(fileContent, '[marcoName]', rootInfo.serviceName.toUpperCase()); + fileContent = replaceAll(fileContent, '[lowServiceName]', rootInfo.serviceName.toLowerCase()); + fileContent = replaceAll(fileContent, '[serviceHFunctions]', saFuncHContent); + fs.writeFileSync(filePath, fileContent); +} \ No newline at end of file diff --git a/src/vscode_plugin/src/gen/genservicecppfile.ts b/src/vscode_plugin/src/gen/genservicecppfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f5b3667301a9bd2a148d664f98553cb8c6db43ff --- /dev/null +++ b/src/vscode_plugin/src/gen/genservicecppfile.ts @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2025 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 * as fs from 'fs'; +import { FuncObj, HdfRootInfo } from "./datatype"; +import { replaceAll } from '../common/tool'; +import { getServiceFuncParamStr } from './genservicehfile'; +import { hdiServiceFuncTemplate } from '../template/func_template'; + +export function genServiceCppFile(rootInfo: HdfRootInfo, filePath: string, fileContent: string) { + let hdiServiceFuncCpp = ''; + let funcList: FuncObj[] = rootInfo.funcs; + let upperName = rootInfo.driverName.substring(0, 1).toLocaleUpperCase(); + let marcoName = upperName + rootInfo.driverName.substring(1, rootInfo.driverName.length); + for (let i = 0; i < funcList.length; ++i) { + // xxx_interface_service.cpp的实现 + let paramStr = getServiceFuncParamStr(funcList[i]); + let serviceCppContent = replaceAll(hdiServiceFuncTemplate, '[functionName]', funcList[i].name); + serviceCppContent = replaceAll(serviceCppContent, '[marcoName]', marcoName); + hdiServiceFuncCpp = replaceAll(serviceCppContent, '[params]', paramStr); + } + fileContent = replaceAll(fileContent, '[driverName]', rootInfo.driverName); + fileContent = replaceAll(fileContent, '[marcoName]', marcoName); + fileContent = replaceAll(fileContent, '[serviceFuncListImpl]', hdiServiceFuncCpp); + fs.writeFileSync(filePath, fileContent); +} \ No newline at end of file diff --git a/src/vscode_plugin/src/gen/genservicehfile.ts b/src/vscode_plugin/src/gen/genservicehfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..1b9a8311a054bb43732118c046527a7e6d9cbf13 --- /dev/null +++ b/src/vscode_plugin/src/gen/genservicehfile.ts @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2025 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 * as fs from 'fs'; +import { FuncObj, HdfRootInfo } from "./datatype"; +import { format } from 'util'; +import { getTab, replaceAll } from '../common/tool'; + +// 干脆这个用来表示hdf的service.h算了, 暂时先把hdf和sa的分开 + +// 生成方法实现 +export function getServiceFuncParamStr(funcObj: FuncObj) { + let paramStr = ''; + for (let i = 0; i < funcObj.parameters.length; ++i) { + // paramStr += (i === 0) ? '' : ', '; + // paramStr += funcObj.parameters[i].type + ' ' + funcObj.parameters[i].name + ', '; + paramStr += format('const %s& %s, ', funcObj.parameters[i].type, funcObj.parameters[i].name); + } + if (funcObj.returns !== 'void') { + let outName = funcObj.name + 'Out' + if (funcObj.returns === 'string') { + funcObj.returns = 'std::string'; + } + paramStr += funcObj.returns + '& ' + outName; + } else { + // 如果返回值是void, 去掉参数列表结尾逗号 + paramStr = paramStr.substring(0, paramStr.length - 2); + } + return paramStr; +} + +export function genServiceHFile(rootInfo: HdfRootInfo, filePath: string, fileContent: string) { + let hdiServiceFuncH = ''; + let funcTab = getTab(1); + let funcList: FuncObj[] = rootInfo.funcs; + for (let i = 0; i < funcList.length; ++i) { + // xxx_interface_service.h方法定义 + let paramStr = getServiceFuncParamStr(funcList[i]); + hdiServiceFuncH += (i === 0) ? '' : '\n' + funcTab; + hdiServiceFuncH += format('int32_t %s(%s) override;', funcList[i].name, paramStr) + } + let upperName = rootInfo.driverName.substring(0, 1).toLocaleUpperCase(); + let marcoName = upperName + rootInfo.driverName.substring(1, rootInfo.driverName.length); + let upperDriverName = rootInfo.driverName.toLocaleUpperCase(); + fileContent = replaceAll(fileContent, '[driverName]', rootInfo.driverName); + fileContent = replaceAll(fileContent, '[marcoName]', marcoName); + fileContent = replaceAll(fileContent, '[driverUpperName]', upperDriverName); + fileContent = replaceAll(fileContent, '[serviceFuncDeclare]', hdiServiceFuncH); + fs.writeFileSync(filePath, fileContent); +} \ No newline at end of file diff --git a/src/vscode_plugin/src/gen/genstubcppfile.ts b/src/vscode_plugin/src/gen/genstubcppfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..b171181f92d32c73f12528ad00f940b2a8450f28 --- /dev/null +++ b/src/vscode_plugin/src/gen/genstubcppfile.ts @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2025 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 { replaceAll, getTab } from '../common/tool'; +import { stubInnerFuncTemplate } from '../template/func_template'; +import * as fs from 'fs'; +import { format } from 'util' +import { FuncObj, ServiceRootInfo } from './datatype'; +import { genRead, genWrite } from './genCommonFunc'; + +function genStubInnerFunc(funcInfo: FuncObj, className: string) { + let innerFunc = replaceAll(stubInnerFuncTemplate, '[serviceName]', className); + innerFunc = replaceAll(innerFunc, '[funcName]', funcInfo.name); + + // 入参处理 + // 生成服务端读取客户端传参的代码段 + let readDataStr = ''; + let tab = getTab(1); + // 调用业务方法时传入的入参列表 + let innerParamStr = ''; + for (let i = 0; i < funcInfo.parameters.length; ++i) { + let param = funcInfo.parameters[i]; + let innerParamName = param.name + 'Val'; + if (i > 0) { + readDataStr += '\n' + tab; + innerParamStr += ' ,'; + } + + //将remote请求中的参数值读取到内部参数变量中 + // 定义内部参数变量 + readDataStr += format('%s %s;', param.type, innerParamName); + let destObj = { + 'name': param.name + 'Val', + 'type': param.type, + 'arraySize': -1 + }; + readDataStr += '\n' + tab + genRead('data', destObj); + innerParamStr += innerParamName; + } + innerFunc = replaceAll(innerFunc, '[readData]', readDataStr); + + // 调用service的实际业务逻辑实现方法 + // 生成调用服务端实现并返回结果的代码段 + let writeReplyStr = ''; + if (funcInfo.returns === 'void') { + writeReplyStr += format('%s(%s); // call business implementation', funcInfo.name, innerParamStr); + writeReplyStr += '\n' + tab + 'reply.WriteInt32(retCode);'; + } else { + writeReplyStr += format('%s retVal = %s(%s); // call business implementation', + funcInfo.returns, funcInfo.name, innerParamStr); + writeReplyStr += '\n' + tab + 'reply.WriteInt32(retCode);'; + writeReplyStr += '\n' + tab + genWrite('retVal', 'reply', funcInfo.returns); + } + innerFunc = replaceAll(innerFunc, '[writeReply]', writeReplyStr); + return innerFunc; +} + +// 生成 xxx_service_stub.cpp +export function genStubCppFile(rootInfo: ServiceRootInfo, filePath: string, fileContent: string) { + let stubInnerFuncMap = ''; + let stubInnerFuncCpp = ''; + let funcList: FuncObj[] = rootInfo.funcs; + for (let i = 0; i < funcList.length; ++i) { + let funcEnum = funcList[i].name.toUpperCase(); + stubInnerFuncMap += format('innerFuncs_[%s] = &%sStub::%sInner;', funcEnum, rootInfo.serviceName, funcList[i].name); + stubInnerFuncCpp += genStubInnerFunc(funcList[i], rootInfo.serviceName); + } + fileContent = replaceAll(fileContent, '[serviceName]', rootInfo.serviceName); + fileContent = replaceAll(fileContent, '[lowServiceName]', rootInfo.serviceName.toLowerCase()); + fileContent = replaceAll(fileContent, '[innerFuncMap]', stubInnerFuncMap); + fileContent = replaceAll(fileContent, '[innerFuncImpl]', stubInnerFuncCpp); + fs.writeFileSync(filePath, fileContent); +} \ No newline at end of file diff --git a/src/vscode_plugin/src/gen/genstubhfile.ts b/src/vscode_plugin/src/gen/genstubhfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..4f59ac0c1cb90c37c64c7b142fbffe42164d1522 --- /dev/null +++ b/src/vscode_plugin/src/gen/genstubhfile.ts @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2025 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 { replaceAll, getTab } from '../common/tool'; +import * as fs from 'fs'; +import { format } from 'util' +import { FuncObj, ServiceRootInfo } from './datatype'; + +// 生成 xxx_service_stub.h +export function genStubHFile(rootInfo: ServiceRootInfo, filePath: string, fileContent: string) { + let stubInnerFuncH = ''; + let funcList: FuncObj[] = rootInfo.funcs; + let funcTab = getTab(1); + for (let i = 0; i < funcList.length; ++i) { + stubInnerFuncH += (i === 0) ? '' : '\n' + funcTab; + stubInnerFuncH += + format('ErrCode %sInner(MessageParcel &data, MessageParcel &reply);', funcList[i].name); + } + fileContent = replaceAll(fileContent, '[serviceName]', rootInfo.serviceName); + fileContent = replaceAll(fileContent, '[marcoName]', rootInfo.serviceName.toUpperCase()); + fileContent = replaceAll(fileContent, '[lowServiceName]', rootInfo.serviceName.toLowerCase()); + fileContent = replaceAll(fileContent, '[innerFuncDef]', stubInnerFuncH); + fs.writeFileSync(filePath, fileContent); +} \ No newline at end of file diff --git a/src/vscode_plugin/src/template/hdf/hdfdir.ts b/src/vscode_plugin/src/template/hdf/hdfdir.ts index fefc68ca2b532efcbee0d0b6bbc9d1f5d064dd86..4aaec734e81f85b7db639e77147924b1062e7117 100644 --- a/src/vscode_plugin/src/template/hdf/hdfdir.ts +++ b/src/vscode_plugin/src/template/hdf/hdfdir.ts @@ -93,4 +93,7 @@ export let hdf4_1dir: DirTemp = { name: '[driverName]hdf', files: [hdfReadmeTemplate], dirs: [hdf_interface, hdf_peripheral, hdf_hcsconfig] -} \ No newline at end of file +} + +// ʹmap汾 +export const hdf_version_map = new Map([['4.1', hdf4_1dir]]); \ No newline at end of file diff --git a/src/vscode_plugin/src/template/sa/sadir.ts b/src/vscode_plugin/src/template/sa/sadir.ts index 4ec9b8b33a8ddfe753fad53de389d83c3b2ce08d..7aecfada9b262a19d7410005d1982b5fc3a83883 100644 --- a/src/vscode_plugin/src/template/sa/sadir.ts +++ b/src/vscode_plugin/src/template/sa/sadir.ts @@ -88,4 +88,7 @@ export let service3_2_dir: DirTemp = { name: "[serviceName]service", files: [buildGnTemplate, bundleJsonTemplate, saReadmeTemplate], dirs: [etc3_2_dir, include_dir, src_dir, interface_dir, sa_profile3_2_dir], -} \ No newline at end of file +} + +// һmapڱsaĸ汾 +export const sa_version_map = new Map([['3.2', service3_2_dir], ['4.1', service4_1_dir]]); \ No newline at end of file