1 2/* 3* Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development Co., Ltd. 4* Licensed under the Apache License, Version 2.0 (the "License"); 5* you may not use this file except in compliance with the License. 6* You may obtain a copy of the License at 7* 8* http://www.apache.org/licenses/LICENSE-2.0 9* 10* Unless required by applicable law or agreed to in writing, software 11* distributed under the License is distributed on an "AS IS" BASIS, 12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13* See the License for the specific language governing permissions and 14* limitations under the License. 15*/ 16import { FuncObj, GenInfo, ParamObj } from "../datatype"; 17import { classMethodGetParamTemplate, classMethodNoParamTemplate, classMethodTemplate, classPropertyGetTemplate, 18 classPropertySetTemplate, classTemplate, funcGetParamTemplate, napiFuncCppTemplate, napiFuncRetTemplate, 19 paramGenTemplate } from "../../template/func_template"; 20import { replaceAll } from "../../common/tool"; 21import * as path from 'path'; 22import * as fs from 'fs'; 23import { transCkey2NapiInkey, transCkey2NapiOutkey } from "./gencommonfunc"; 24 25export function genClassMethodContent(funcInfo: FuncObj, className: string, classMethodContent: string) { 26 let methodContent = replaceAll(classMethodTemplate, '[class_method_name_replace]', funcInfo.name); 27 methodContent = replaceAll(methodContent, '[class_name_replace]', className); 28 if (funcInfo.parameters.length <= 0) { 29 methodContent = replaceAll(methodContent, '[class_method_param_in]', classMethodNoParamTemplate); 30 } else { 31 // 方法入参替换 32 let paramGenResult = ''; 33 let methodParamIn = replaceAll(classMethodGetParamTemplate, '[param_count_replace]', 'PARAMS' + funcInfo.parameters.length); 34 for (let i = 0; i < funcInfo.parameters.length; ++i) { 35 // 这里是入参替换 比如输入2个参数 double/int napi_get_double_value/ napi_get_int32_value 36 let getParamInTemplate = transCkey2NapiInkey(funcInfo.parameters[i].type); 37 // 如果getParamInTemplate是空,则默认是对象输入,不做任何处理 38 if (getParamInTemplate === '') { 39 paramGenResult += '// Todo: handle object input.\n'; 40 continue; 41 } 42 let getParam = replaceAll(getParamInTemplate, '[param_index_replace]', 43 'PARAMS' + i); 44 getParam = replaceAll(getParam, '[param_name_replace]', 45 funcInfo.parameters[i].name); 46 let paramGen = replaceAll(paramGenTemplate, '[param_index_replace]', 47 'PARAMS' + i); 48 paramGen = replaceAll(paramGen, '[param_name_replace]', 49 funcInfo.parameters[i].name); 50 paramGen = replaceAll(paramGen, '[getParam_replace]', getParam); 51 paramGenResult += paramGen; 52 } 53 // 替换get param in 54 methodParamIn = replaceAll(methodParamIn, '[class_method_get_param]', paramGenResult); 55 methodContent = replaceAll(methodContent, '[class_method_param_in]', methodParamIn); 56 } 57 // 方法返回值替换 58 let returnGenResult = genCppReturnGen(funcInfo); 59 methodContent = replaceAll(methodContent, '[class_method_return]', returnGenResult); 60 // 该class的所有成员方法内容拼接起来 61 classMethodContent += methodContent; 62 return classMethodContent; 63} 64 65export function genClassGetSetContent(variableInfo: ParamObj, className: string, classPropertyGetSetContent: string) { 66 let name = variableInfo.name.toLocaleLowerCase(); 67 name = name.substring(0, 1).toLocaleUpperCase() + name.substring(1); 68 // class的属性get函数生成 69 let getPropertyContent = replaceAll(classPropertyGetTemplate, '[class_property_name_replace]', name); 70 getPropertyContent = replaceAll(getPropertyContent, '[class_name_replace]', className); 71 let returnGetfuncContent = transCkey2NapiOutkey(variableInfo.type); 72 returnGetfuncContent = replaceAll(returnGetfuncContent, '[return_name_replace]', variableInfo.name); 73 getPropertyContent = replaceAll(getPropertyContent, '[class_property_get]', returnGetfuncContent); 74 classPropertyGetSetContent += getPropertyContent; 75 // class的属性set函数生成 76 let setPropertyContent = replaceAll(classPropertySetTemplate, '[class_property_name_replace]', name); 77 setPropertyContent = replaceAll(setPropertyContent, '[class_name_replace]', className); 78 let returnSetfuncContent = transCkey2NapiInkey(variableInfo.type); 79 returnSetfuncContent = replaceAll(returnSetfuncContent, '[param_index_replace]', 'PARAMS0'); 80 returnSetfuncContent = replaceAll(returnSetfuncContent, '[param_name_replace]', variableInfo.name); 81 setPropertyContent = replaceAll(setPropertyContent, '[class_property_set]', returnSetfuncContent); 82 classPropertyGetSetContent += setPropertyContent; 83 return classPropertyGetSetContent; 84} 85 86// 方法输入参数的处理,只处理基本类型,像数组/map/set/class/struct等都全部当作 87// object,且不做处理 88export function getCppParamGen(funcInfo: FuncObj): string { 89 // 处理输入的参数,生成napi的参数处理代码 90 if (funcInfo.parameters.length === 0) { 91 return '// no input params'; 92 } 93 94 // 下面这段代码是不是可以优化一下,把下面这段代码提取出来,放到一个函数中,class与struct生成成员方法的时候也可以调用 95 let paramGenResult = ''; 96 for (let i = 0; i < funcInfo.parameters.length; ++i) { 97 let getParamInTemplate = transCkey2NapiInkey(funcInfo.parameters[i].type); 98 // 如果getParamInTemplate是空,则默认是对象输入,不做任何处理 99 if (getParamInTemplate === '') { 100 paramGenResult += '// Todo: handle object input.\n'; 101 continue; 102 } 103 let getParam = replaceAll(getParamInTemplate, '[param_index_replace]', 104 'PARAMS' + i); 105 getParam = replaceAll(getParam, '[param_name_replace]', 106 funcInfo.parameters[i].name); 107 let paramGen = replaceAll(paramGenTemplate, '[param_index_replace]', 108 'PARAMS' + i); 109 paramGen = replaceAll(paramGen, '[param_name_replace]', 110 funcInfo.parameters[i].name); 111 paramGen = replaceAll(paramGen, '[getParam_replace]', getParam); 112 paramGenResult += paramGen; 113 } 114 let genParamReplace = replaceAll(funcGetParamTemplate, '[param_length]', 115 'PARAMS' + funcInfo.parameters.length); 116 genParamReplace = replaceAll(genParamReplace, '[func_name_replace]', 117 funcInfo.name); 118 genParamReplace = replaceAll(genParamReplace, '[getAllParam_replace]', 119 paramGenResult); 120 return genParamReplace 121} 122 123// 方法返回值的处理 124export function genCppReturnGen(funcInfo: FuncObj): string { 125 // 如果函数返回值是空,直接返回NULL 126 if (funcInfo.returns === 'void') { 127 return ' return NULL;\n'; 128 } 129 let returnName = funcInfo.name; 130 let funcReturnReplace = replaceAll(napiFuncRetTemplate, '[return_name]', 131 returnName); 132 let retGenResult = transCkey2NapiOutkey(funcInfo.returns); 133 retGenResult = replaceAll(retGenResult, '[return_name_replace]', returnName); 134 funcReturnReplace = replaceAll(funcReturnReplace, '[func_name_replace]', 135 funcInfo.name); 136 funcReturnReplace = replaceAll(funcReturnReplace, '[return_replace]', 137 retGenResult); 138 return funcReturnReplace; 139} 140 141export function doGenNapiCppFile(rootInfo: GenInfo, fileContent: string) { 142 let napiCppContent = ''; 143 144 // class的实现 145 if (rootInfo.parseObj && rootInfo.parseObj.classes) { 146 let classesContent = ''; 147 rootInfo.parseObj.classes.forEach(classInfo => { 148 // 拿到每个class的信息 这里是类的主体 149 let className = classInfo.name; // class的名字 150 let classInfoContent = replaceAll(classTemplate, '[class_name_replace]', className) 151 152 let classPropertyGetSetContent = ''; 153 // class中属性的生成 把一个class的所有属性都生成对应的get set函数 154 classInfo.variableList.forEach(variableInfo => { 155 classPropertyGetSetContent = genClassGetSetContent(variableInfo, className, classPropertyGetSetContent); 156 }); 157 classInfoContent = replaceAll(classInfoContent, '[class_property_get_set_replace]', 158 classPropertyGetSetContent) 159 160 let classMethodContent = ''; 161 // class中方法的生成 把一个class的所有方法都生成对应的函数 162 classInfo.functionList.forEach(funcInfo => { 163 // 替换每个方法主体 生成每个方法的函数 164 classMethodContent = genClassMethodContent(funcInfo, className, classMethodContent); 165 }); 166 classInfoContent = replaceAll(classInfoContent, '[class_method_content_replace]', 167 classMethodContent); 168 // 所有class拼接起来 169 classesContent += classInfoContent; 170 }); 171 // 将class的生成内容写入cpp文件 172 napiCppContent += classesContent; 173 } 174 175 // struct的实现 176 if (rootInfo.parseObj && rootInfo.parseObj.structs) { 177 // structs的生成内容 178 let structsContent = ''; 179 rootInfo.parseObj.structs.forEach(structInfo => { 180 let className = structInfo.name; 181 let structInfoContent = replaceAll(classTemplate, '[class_name_replace]', className) 182 183 let classPropertyGetSetContent = ''; 184 // struct中属性的生成 把一个struct的所有属性都生成对应的get set函数 185 structInfo.members.forEach(variableInfo => { 186 classPropertyGetSetContent = genClassGetSetContent(variableInfo, className, classPropertyGetSetContent); 187 }); 188 structInfoContent = replaceAll(structInfoContent, '[class_property_get_set_replace]', 189 classPropertyGetSetContent) 190 191 let structMethodContent = ''; 192 // struct中方法的生成 把一个class的所有方法都生成对应的函数 193 structInfo.functions.forEach(funcInfo => { 194 // 替换每个方法主体 生成每个方法的函数 195 structMethodContent = genClassMethodContent(funcInfo, className, structMethodContent); 196 }); 197 structInfoContent = replaceAll(structInfoContent, '[class_method_content_replace]', 198 structMethodContent); 199 // 所有struct拼接起来 200 structsContent += structInfoContent; 201 }); 202 // 将struct的生成内容写入cpp文件 203 napiCppContent += structsContent; 204 } 205 206 // funcs的napi实现 207 if (rootInfo.parseObj && rootInfo.parseObj.funcs) { 208 rootInfo.parseObj.funcs.forEach(funcInfo => { 209 // 替换每个方法主体 210 let hFileName = path.basename(rootInfo.rawFilePath); 211 let bodyReplace = replaceAll(napiFuncCppTemplate, '[func_name_replace]', 212 funcInfo.name); 213 bodyReplace = replaceAll(bodyReplace, '[get_error_msg_tag]', 214 funcInfo.name); 215 bodyReplace = replaceAll(bodyReplace, '[file_introduce_replace]', 216 hFileName); 217 // 生成方法注释 218 let funcInfoParams = funcInfo.parameters.length > 0 ? '' : 'void'; 219 let funcInfoParamTemp = '[paramName]: [paramType]; '; 220 for (let i = 0; i < funcInfo.parameters.length; i++) { 221 let funcInfoParamReplace = replaceAll(funcInfoParamTemp, '[paramName]', 222 funcInfo.parameters[i].name); 223 funcInfoParamReplace = replaceAll(funcInfoParamReplace, '[paramType]', 224 funcInfo.parameters[i].type); 225 funcInfoParams += funcInfoParamReplace; 226 } 227 bodyReplace = replaceAll(bodyReplace, '[input_introduce_replace]', 228 funcInfoParams === '' ? 'void' : funcInfoParams); 229 bodyReplace = replaceAll(bodyReplace, '[output_introduce_replace]', 230 funcInfo.returns); 231 // 方法参数的处理,解析参数类型,生成napi的参数处理代码 232 let paramGenResult = getCppParamGen(funcInfo); 233 bodyReplace = replaceAll(bodyReplace, '[func_getParam_replace]', 234 paramGenResult); 235 // 方法返回值的处理,解析返回值类型,生成napi的返回值处理代码 236 let returnGenResult = genCppReturnGen(funcInfo); 237 bodyReplace = replaceAll(bodyReplace, '[func_return_replace]', 238 returnGenResult); 239 // 组合一个个方法 240 napiCppContent += bodyReplace; 241 }); 242 } 243 244 fileContent = replaceAll(fileContent, '[fileName]', rootInfo.fileName); 245 fileContent = replaceAll(fileContent, '[func_content_replace]', napiCppContent); 246 return fileContent; 247} 248export function genNapiCppFile(rootInfo: GenInfo, filePath: string, 249 fileContent: string) { 250 fileContent = doGenNapiCppFile(rootInfo, fileContent); 251 fs.writeFileSync(filePath, fileContent); 252}