1 2/* 3* Copyright (c) 2022 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*/ 16const { NapiLog } = require("../tools/NapiLog"); 17const { replaceAll, getTab } = require("../tools/tool"); 18const re = require("../tools/re"); 19const { iServiceHTemplate, proxyHTemplate, stubHTemplate, serviceHTemplate, proxyCppTemplate, 20 proxyFuncTemplate, stubCppTemplate, stubInnerFuncTemplate, serviceCppTemplate, serviceFuncImplTemplate, 21 clientCppTemplate, buildGnTemplate, bundleJsonTemplate, profileGnTemplate, profileXmlTemplate, serviceCfgTemplate, 22 serviceCfgGnTemplate, iServiceCppTemplate } = require("./fileTemplate"); 23const { DATA_W_MAP, DATA_R_MAP, VECTOR_W_MAP, VECTOR_R_MAP, getParcelType, AllParseFileList, MarshallInfo, 24 ProcessingClassList} = require("../tools/common"); 25 26let rootHFileSrc = ""; // .h文件的源码 27let dependSrcList = []; //在.h文件中定义并被接口使用到的class/struct类定义源码集合(接口没用到的class定义就不需要了) 28let marshallFuncList = []; // class类的消息序列化方法代码集合 29 30let fileContent = { 31 "iServiceHFile": {}, 32 "proxyHFile": {}, 33 "stubHFile": {}, 34 "serviceHFile": {}, 35 "proxyCppFile": {}, 36 "stubCppFile": {}, 37 "serviceCppFile": {}, 38 "clientCppFile": {}, 39 "buildGnFile": {}, 40 "bundleJsonFile": {}, 41 "profileGnFile": {}, 42 "profileXmlFile": {}, 43 "serviceCfgFile": {}, 44 "serviceCfgGnFile": {}, 45 "iServiceCppFile": {}, 46}; 47 48function getIncludeStr(includeList) { 49 let includeStr = ""; 50 for (let i = 0; i < includeList.length; ++i) { 51 includeStr += "#include " + includeList[i] + "\n"; 52 } 53 return includeStr; 54} 55 56function getUsingStr(usingList) { 57 let usingStr = ""; 58 for (usingName in usingList) { 59 usingStr += "\nusing " + usingList[usingName].raw_type + ";"; 60 } 61 return usingStr; 62} 63 64function getFuncParamStr(params) { 65 let paramStr = ""; 66 for (let i = 0; i < params.length; ++i) { 67 paramStr += (i == 0) ? "" : ", "; 68 paramStr += params[i].type + " " + params[i].name; 69 } 70 return paramStr; 71} 72 73/** 74 * 获取class类型在原始.h文件中的定义源码段 75 * @param className 待查找的class名称(可以是struct) 76 * @param rawContent .h文件源码 77 * @returns class类型在原始.h文件中的定义源码段 78 */ 79 function getClassSrc(className, rawContent) { 80 let beginPos = rawContent.indexOf(className); 81 if( beginPos < 0) { 82 NapiLog.logError("Warning: Can not find definition of " + className); 83 return null; 84 } 85 86 let firstBracesPos = rawContent.indexOf("{", beginPos); // class后面第一个{的位置 87 let firstSemiPos = rawContent.indexOf(";", beginPos); // class后面第一个分号的位置 88 if ( (firstBracesPos < 0) || (firstSemiPos < firstBracesPos)) { 89 // class定义后面找不到{},或先找到了结束符分号,视为该class没有相关的实现代码 90 NapiLog.logError("Warning: Can not find implementation of " + className); 91 return null; 92 } 93 94 let endPos = firstBracesPos + 1; 95 let bracesCount = 1; 96 for (; (endPos < rawContent.length) && (bracesCount != 0); ++endPos) { 97 if (rawContent.charAt(endPos) == "{") { 98 ++bracesCount; 99 } 100 if (rawContent.charAt(endPos) == "}") { 101 --bracesCount; 102 } 103 } 104 105 if (bracesCount != 0) { 106 // 左右括号不匹配 107 NapiLog.logError("Warning: The braces of %s do not match.".format(className)); 108 return null; 109 } 110 111 let classSrc = rawContent.substring(beginPos, endPos); 112 return classSrc; 113} 114 115/** 116 * 查看变量类型是否为class/struct类型,是否已生成指定的打包函数 117 * @param vType 变量类型 118 * @returns [class对应的打包函数(没有为null), class结构信息(没找到为null)] 119 */ 120function findClassGenInfo(vType) { 121 let marshallInfo = null; 122 for (let i = 0; i < marshallFuncList.length; ++i) { 123 if (marshallFuncList[i].className == vType) { 124 marshallInfo = marshallFuncList[i].marshallFuncs; 125 } 126 } 127 128 if (marshallInfo) { 129 // 该class已经有生成好的包装代码,就不用再到原始代码结构体AllParseFileList中去查找了。 130 return [marshallInfo, null]; 131 } 132 let classInfo = AllParseFileList.findClassByName(vType); 133 return [null, classInfo]; 134} 135 136function findGetSet(propName, classInfo) { 137 let upperName = propName.replace(propName[0], propName[0].toUpperCase()); 138 let getName = "get" + upperName; 139 let setName = "set" + upperName; 140 let findGet = false; 141 let findSet = false; 142 let result = null; 143 for (let i = 0; i < classInfo.methods.public.length; ++i) { 144 if (getName == classInfo.methods.public[i].name) { 145 findGet = true; 146 } 147 if (setName == classInfo.methods.public[i].name) { 148 findSet = true; 149 } 150 } 151 if (findGet && findSet) { 152 // get和set方法必须同时具备,成员对象属性才能序列化/反序列化,缺一不可。 153 result = {"name": propName, "getName": getName, "setName": setName}; 154 } 155 return result; 156} 157 158function privatePropMashall(parcelName, objName, classInfo, marshallInfo) { 159 let properties = classInfo.properties.protected.concat(classInfo.properties.private); 160 let propFuncs = []; // 保存成员属性对应的get/set方法 161 for (let i = 0; i < properties.length; ++i) { 162 let getSetInfo = findGetSet(properties[i].name, classInfo); 163 if (getSetInfo != null) { 164 getSetInfo.type = properties[i].type; 165 propFuncs.push(getSetInfo); 166 } else { 167 NapiLog.logError( 168 "Warning: Can not find get/set method of %s.%s, the property will be ignored in remote request." 169 .format(classInfo.name, properties[i].name)); 170 } 171 } 172 let writePropStr = ""; 173 let readPropStr = ""; 174 let tab = getTab(1); 175 for (let i = 0; i < propFuncs.length; ++i) { 176 writePropStr += "\n" + tab; 177 writePropStr += genWrite(objName + "." + propFuncs[i].getName + "()", parcelName, propFuncs[i].type); 178 179 readPropStr += "\n" + tab; 180 let destObj = { 181 "name": objName + "." + propFuncs[i].name, 182 "setFunc": objName + "." + propFuncs[i].setName, 183 "type": propFuncs[i].type 184 }; 185 readPropStr += genRead(parcelName, destObj); 186 } 187 marshallInfo.marshallFuncH = marshallInfo.marshallFuncH.replace("[privateMarshall]", writePropStr); 188 marshallInfo.unmarshallFuncH = marshallInfo.unmarshallFuncH.replace("[privateUnmarshall]", readPropStr); 189} 190 191function publicPropMashall(parcelName, objName, classInfo, marshallInfo) { 192 let properties = classInfo.properties.public; 193 let writePropStr = ""; 194 let readPropStr = ""; 195 let tab = getTab(1); 196 for (let i = 0; i < properties.length; ++i) { 197 writePropStr += "\n" + tab; 198 writePropStr += genWrite(objName + "." + properties[i].name, parcelName, properties[i].type); 199 200 readPropStr += "\n" + tab; 201 let destObj = { 202 "name": objName + "." + properties[i].name, 203 "setFunc": null, 204 "type": properties[i].type 205 }; 206 readPropStr += genRead(parcelName, destObj); 207 } 208 marshallInfo.marshallFuncH = marshallInfo.marshallFuncH.replace("[publicMarshall]", writePropStr); 209 marshallInfo.unmarshallFuncH = marshallInfo.unmarshallFuncH.replace("[publicUnmarshall]", readPropStr); 210} 211 212/** 213 * 保存远程接口用到的相关class/struct定义代码,以便后面写入到生成的iservice.h接口文件中 214 * @param classInfo 接口使用到的class信息 215 */ 216function saveClassSrc(classInfo) { 217 if (classInfo.isInclude) { 218 // 只有service class所在的主.h文件中定义的class/struct需要保存其源码 219 // 定义在其它include文件中的类,不需要保存定义源码。 220 return; 221 } 222 for (let i = 0; i < dependSrcList.length; ++i) { 223 if (dependSrcList[i].name == classInfo.name){ 224 // 该class的定义源码已经保存过了。 225 return; 226 } 227 } 228 229 let srcObj = {}; 230 srcObj.name = classInfo.name; 231 let className = classInfo.declaration_method + " " + classInfo.name; 232 233 // 从.h源码中获取该class定义的源码段 234 srcObj.srcCode = getClassSrc(className, rootHFileSrc); 235 if (srcObj.srcCode != null) { 236 dependSrcList.push(srcObj); 237 } 238} 239 240/** 241 * 创建class对象序列化/反序列化代码数据结构 242 * @param classInfo class类信息 243 */ 244function createMarshallInfo(classInfo) { 245 saveClassSrc(classInfo); 246 let newMarshall = new MarshallInfo(classInfo.name); 247 let objName = classInfo.name.toLowerCase(); 248 newMarshall.marshallFuncName = "marshalling" + classInfo.name; 249 newMarshall.unmarshallFuncName = "unmarshalling" + classInfo.name; 250 // 为了marshall方法的入参能同时支持左值引用marshall(xx.obj)和右值引用marshall(xx.getObj()),这里采用万能引用模板来实现 251 newMarshall.marshallFuncH = replaceAll( 252 "\ntemplate<typename T> // T should be [className]& or [className]&&", "[className]", classInfo.name); 253 newMarshall.marshallFuncH += 254 "\n%s bool %s(MessageParcel& data, T&& %s) {[publicMarshall][privateMarshall]\n return true;\n}\n" 255 .format("__attribute__((unused)) static", newMarshall.marshallFuncName, objName); 256 newMarshall.unmarshallFuncH = 257 "\n%s bool %s(MessageParcel& data, %s& %s) {[publicUnmarshall][privateUnmarshall]\n return true;\n}\n" 258 .format("__attribute__((unused)) static", newMarshall.unmarshallFuncName, classInfo.name, objName); 259 260 let marshallInfo = { 261 "className": classInfo.name, 262 "marshallFuncs": newMarshall 263 } 264 // 这里必须先将class放入处理列表中,以免后续的属性代码生成过程中再次遇到该class类型造成无限循环嵌套。 265 ProcessingClassList.push(marshallInfo); 266 267 // 继续生成属性代码 268 publicPropMashall("data", objName, classInfo, newMarshall); 269 privatePropMashall("data", objName, classInfo, newMarshall); 270 271 marshallFuncList.push(marshallInfo); 272 return newMarshall; 273} 274 275/** 276 * 生成class对象转换remote消息buffer(parcel data)的代码段 277 * @param objName 待写入的class对象名 278 * @param parcelName 写入目标(parcel data)变量的名称 279 * @param marshallInfo class对应的打包函数(没有为null) 280 * @param classInfo class结构信息 281 */ 282function genClassWriteString(objName, parcelName, marshallInfo, classInfo) { 283 let marshall = marshallInfo; 284 if (!marshall) { 285 // class的序列化代码还未生成,查看是否已在待处理列表中 286 let ProcessingClass = ProcessingClassList.findByName(classInfo.name); 287 if (ProcessingClass == null) { 288 // 待处理列表中没有,则创建该class的读写代码数据。 289 marshall = createMarshallInfo(classInfo); 290 } else { 291 // 待处理列表中存在(说明该class已经在递归生成代码的执行路径中),直接使用即将生成的marshalling方法名 292 marshall = ProcessingClass.marshallFuncs; 293 } 294 } 295 return "%s(%s, %s);".format(marshall.marshallFuncName, parcelName, objName); 296} 297 298/** 299 * 生成从remote消息buffer(parcel data)中读取class对象的代码段 300 * @param destObj 待读取的class对象信息 301 * @param parcelName 待读取的(parcel data)变量的名称 302 * @param marshallInfo class对应的打包函数(没有为null) 303 * @param classInfo class结构信息 304 */ 305 function genClassReadString(destObj, parcelName, marshallInfo, classInfo) { 306 let marshall = marshallInfo; 307 if (!marshall) { 308 marshall = createMarshallInfo(classInfo); 309 } 310 let readStr = ""; 311 if (destObj.setFunc) { // 有set方法的是私有成员,需要生成set代码 312 let className = destObj.type; 313 readStr = "%s tmp%s;\n %s(%s, tmp%s);\n %s(tmp%s);".format(className, className, 314 marshall.unmarshallFuncName, parcelName, className, destObj.setFunc, className); 315 } else { 316 readStr = "%s(%s, %s);".format(marshall.unmarshallFuncName, parcelName, destObj.name); 317 } 318 return readStr; 319} 320 321/** 322 * 生成vector集合写入remote消息buffer(parcel data)的代码段 323 * 324 * @param vectorName 待写入的vector变量名 325 * @param parcelName 写入目标(parcel data)变量的名称 326 * @param vecType vector变量类型 327 * @param matchs vector类型的正则匹配结果 328 * @returns 生成的vector变量序列化打包代码段 329 */ 330 function genVectorWrite(vectorName, parcelName, vecType, matchs) { 331 let rawType = re.getReg(vecType, matchs.regs[2]); 332 let parcelType = getParcelType(rawType); 333 let wFunc = VECTOR_W_MAP.get(parcelType); 334 if (!wFunc) { 335 NapiLog.logError("Unsupport writing with type: " + vecType); 336 return ""; 337 } 338 return "%s.%s(%s);".format(parcelName, wFunc, vectorName); 339} 340 341/** 342 * 生成c参数写入remote消息buffer(parcel data)的代码段 343 * @param srcName 待写入的c变量名 344 * @param parcelName 写入目标(parcel data)变量的名称 345 * @param vType c变量类型 346 * @returns 生成的代码段 347 */ 348function genWrite(srcName, parcelName, vType) { 349 let matchs = re.match("(std::)?vector<([\x21-\x7e]+)[ ]?>", vType); 350 if (matchs) { 351 // vector类型变量包装成parcel data 352 return genVectorWrite(srcName, parcelName, vType, matchs); 353 } 354 355 let parcelType = getParcelType(vType); 356 let wFunc = DATA_W_MAP.get(parcelType); 357 if (!wFunc) { 358 let result = findClassGenInfo(vType); 359 if (!result[0] && !result[1]) { 360 NapiLog.logError("Unsupport writing with type: " + vType); 361 return ""; 362 } 363 364 // class与struct类型变量包装成parcel data 365 return genClassWriteString(srcName, parcelName, result[0], result[1]); 366 } 367 368 // 基本类型变量包装成parcel data 369 return "%s.%s(%s);".format(parcelName, wFunc, srcName); 370} 371 372/** 373 * 生成从remote消息buffer(parcel data)中读取vector集合的代码段 374 * 375 * @param parcelName 待读取的消息buffer(parcel data)变量的名称 376 * @param vectorName 待写入的vector变量名 377 * @param vecType vector变量类型 378 * @param matchs vector类型的正则匹配结果 379 * @returns 生成的vector变量反序列化读取码段 380 */ 381 function genVectorRead(parcelName, vectorName, vecType, matchs) { 382 let rawType = re.getReg(vecType, matchs.regs[2]); 383 let parcelType = getParcelType(rawType); 384 let rFunc = VECTOR_R_MAP.get(parcelType); 385 if (!rFunc) { 386 NapiLog.logError("Unsupport reading with type: " + vecType); 387 return ""; 388 } 389 return "%s.%s(&(%s));".format(parcelName, rFunc, vectorName); 390} 391 392/** 393 * 生成从remote消息buffer(parcel data)读取c参数的代码段 394 * @param parcelName 待读取的parcel data变量名称 395 * @param destObj 读取出的内容写入的c变量信息 396 * @returns 生成的代码段 397 */ 398function genRead(parcelName, destObj) { 399 let matchs = re.match("(std::)?vector<([\x21-\x7e]+)[ ]?>", destObj.type); 400 if (matchs) { 401 // 从parcel data中读取vector类型变量 402 return genVectorRead(parcelName, destObj.name, destObj.type, matchs); 403 } 404 405 let parcelType = getParcelType(destObj.type); 406 let rFunc = DATA_R_MAP.get(parcelType); 407 if (!rFunc) { 408 let result = findClassGenInfo(destObj.type); 409 if (!result[0] && !result[1]) { 410 NapiLog.logError("Unsupport reading with type: " + destObj.type); 411 return ""; 412 } 413 414 // 从parcel data中读取class与struct类型变量 415 return genClassReadString(destObj, parcelName, result[0], result[1]); 416 } 417 418 // 从parcel data中读取基本类型变量 419 let result = destObj.setFunc ? "%s(%s.%s());".format(destObj.setFunc, parcelName, rFunc) 420 : "%s = %s.%s();".format(destObj.name, parcelName, rFunc) ; 421 return result; 422} 423 424function genProxyFunc(funcInfo, className, paramStr) { 425 let proxyFunc = replaceAll(proxyFuncTemplate, "[className]", className); 426 proxyFunc = replaceAll(proxyFunc, "[funcName]", funcInfo.name); 427 proxyFunc = replaceAll(proxyFunc, "[params]", paramStr); 428 proxyFunc = replaceAll(proxyFunc, "[retType]", funcInfo.retType); 429 proxyFunc = replaceAll(proxyFunc, "[funcEnum]", funcInfo.funcEnum); 430 431 // 入参处理 432 let writeDataStr = ""; 433 let tab = getTab(1); 434 for (let i = 0; i < funcInfo.params.length; ++i) { 435 let param = funcInfo.params[i]; 436 writeDataStr += (i == 0) ? "" : "\n" + tab; 437 writeDataStr += genWrite(param.name, "data", param.type); 438 } 439 proxyFunc = replaceAll(proxyFunc, "[writeData]", writeDataStr); 440 441 // 返回值处理 442 let readReplyStr = ""; 443 if (funcInfo.retType != "void") { 444 readReplyStr = "%s result;".format(funcInfo.retType); 445 let destObj = { 446 "name": "result", 447 "setFunc": null, 448 "type": funcInfo.retType 449 }; 450 readReplyStr += "\n" + tab + genRead("reply", destObj); 451 readReplyStr += "\n" + tab + "return result;"; 452 } 453 proxyFunc = replaceAll(proxyFunc, "[readReply]", readReplyStr); 454 455 return proxyFunc; 456} 457 458function genStubInnerFunc(funcInfo, className) { 459 let innerFunc = replaceAll(stubInnerFuncTemplate, "[className]", className); 460 innerFunc = replaceAll(innerFunc, "[funcName]", funcInfo.name); 461 462 // 入参处理 463 let readDataStr = ""; // 生成服务端读取客户端传参的代码段 464 let tab = getTab(1); 465 let innerParamStr = ""; // 调用业务方法时传入的入参列表 466 for (let i = 0; i < funcInfo.params.length; ++i) { 467 let param = funcInfo.params[i]; 468 let innerParamName = param.name + "Val"; 469 if (i > 0) { 470 readDataStr += "\n" + tab; 471 innerParamStr += " ,"; 472 } 473 474 //将remote请求中的参数值读取到内部参数变量中 475 readDataStr += "%s %s;".format(param.type, innerParamName); // 定义内部参数变量 476 let destObj = { 477 "name": param.name + "Val", 478 "setFunc": null, 479 "type": param.type 480 }; 481 readDataStr += "\n" + tab + genRead("data", destObj); 482 innerParamStr += innerParamName; 483 } 484 innerFunc = replaceAll(innerFunc, "[readData]", readDataStr); 485 486 // 调用service的实际业务逻辑实现方法 487 let writeReplyStr = ""; // 生成调用服务端实现并返回结果的代码段 488 if (funcInfo.retType === "void") { 489 writeReplyStr += "%s(%s); // call business implementation".format(funcInfo.name, innerParamStr); 490 writeReplyStr += "\n" + tab + "reply.WriteInt32(retCode);"; 491 } else { 492 writeReplyStr += "%s retVal = %s(%s); // call business implementation".format( 493 funcInfo.retType, funcInfo.name, innerParamStr); 494 writeReplyStr += "\n" + tab + "reply.WriteInt32(retCode);"; 495 writeReplyStr += "\n" + tab + genWrite("retVal", "reply", funcInfo.retType); 496 } 497 innerFunc = replaceAll(innerFunc, "[writeReply]", writeReplyStr); 498 return innerFunc; 499} 500 501function genServiceFunc(funcInfo, className, paramStr) { 502 let serviceFunc = replaceAll(serviceFuncImplTemplate, "[retType]", funcInfo.retType); 503 serviceFunc = replaceAll(serviceFunc, "[className]", className); 504 serviceFunc = replaceAll(serviceFunc, "[funcName]", funcInfo.name); 505 serviceFunc = replaceAll(serviceFunc, "[params]", paramStr); 506 return serviceFunc; 507} 508 509function genFunctions(classInfo, files) { 510 let res = genFunctionCode(classInfo); 511 files.iServiceH = replaceAll(files.iServiceH, "[funcEnum]", res.funcEnumStr); 512 files.iServiceH = replaceAll(files.iServiceH, "[functions]", res.iServiceFuncH); 513 files.proxyH = replaceAll(files.proxyH, "[functions]", res.proxyFuncH); 514 files.stubH = replaceAll(files.stubH, "[innerFuncDef]", res.stubInnerFuncH); 515 files.serviceH = replaceAll(files.serviceH, "[functions]", res.proxyFuncH); 516 files.proxyCpp = replaceAll(files.proxyCpp, "[remoteFuncImpl]", res.proxyFuncCpp); 517 files.stubCpp = replaceAll(files.stubCpp, "[innerFuncMap]", res.stubInnerFuncMap); 518 files.stubCpp = replaceAll(files.stubCpp, "[innerFuncImpl]", res.stubInnerFuncCpp); 519 files.serviceCpp = replaceAll(files.serviceCpp, "[serviceFuncImpl]", res.serviceFuncCpp); 520 files.clientCpp = replaceAll(files.clientCpp, "[clientFuncInvoke]", res.clientFuncCpp); 521} 522 523function genFilesByTemplate(upperServiceName, lowServiceName, rootInfo) { 524 let files = {}; 525 // 按模板生成.h和.cpp文件内容框架 526 files.iServiceH = replaceAll(iServiceHTemplate, "[marcoName]", upperServiceName); 527 files.proxyH = replaceAll(proxyHTemplate, "[marcoName]", upperServiceName); 528 files.stubH = replaceAll(stubHTemplate, "[marcoName]", upperServiceName); 529 files.serviceH = replaceAll(serviceHTemplate, "[marcoName]", upperServiceName); 530 files.proxyCpp = proxyCppTemplate; 531 files.stubCpp = stubCppTemplate; 532 files.serviceCpp = replaceAll(serviceCppTemplate, "[marcoName]", upperServiceName); 533 files.clientCpp = replaceAll(clientCppTemplate, "[marcoName]", upperServiceName); 534 files.iServiceCpp = iServiceCppTemplate; 535 536 // 按模板生成资源配置文件内容框架 537 files.buildGn = replaceAll(buildGnTemplate, "[lowServiceName]", lowServiceName); 538 files.buildGn = replaceAll(files.buildGn, "[stubCppFile]", fileContent.stubCppFile.name); 539 files.buildGn = replaceAll(files.buildGn, "[serviceCppFile]", fileContent.serviceCppFile.name); 540 files.buildGn = replaceAll(files.buildGn, "[proxyCppFile]", fileContent.proxyCppFile.name); 541 files.buildGn = replaceAll(files.buildGn, "[clientCppFile]", fileContent.clientCppFile.name); 542 files.buildGn = replaceAll(files.buildGn, "[iServiceCppFile]", fileContent.iServiceCppFile.name); 543 files.bundleJson = replaceAll(bundleJsonTemplate, "[lowServiceName]", lowServiceName); 544 files.profileGn = replaceAll(profileGnTemplate, "[lowServiceName]", lowServiceName); 545 files.profileGn = replaceAll(files.profileGn, "[serviceId]", rootInfo.serviceId); 546 files.profileXml = replaceAll(profileXmlTemplate, "[lowServiceName]", lowServiceName); 547 files.profileXml = replaceAll(files.profileXml, "[serviceId]", rootInfo.serviceId); 548 files.serviceCfg = replaceAll(serviceCfgTemplate, "[lowServiceName]", lowServiceName); 549 files.serviceGnCfg = replaceAll(serviceCfgGnTemplate, "[lowServiceName]", lowServiceName); 550 return files; 551} 552 553function replaceClassName(files, classInfo) { 554 files.iServiceH = replaceAll(files.iServiceH, "[className]", classInfo.name); 555 files.proxyH = replaceAll(files.proxyH, "[className]", classInfo.name); 556 files.stubH = replaceAll(files.stubH, "[className]", classInfo.name); 557 files.serviceH = replaceAll(files.serviceH, "[className]", classInfo.name); 558 files.proxyCpp = replaceAll(files.proxyCpp, "[className]", classInfo.name); 559 files.stubCpp = replaceAll(files.stubCpp, "[className]", classInfo.name); 560 files.serviceCpp = replaceAll(files.serviceCpp, "[className]", classInfo.name); 561 files.clientCpp = replaceAll(files.clientCpp, "[className]", classInfo.name); 562} 563 564function replaceServiceName(files, rootInfo) { 565 files.iServiceH = replaceAll(files.iServiceH, "[serviceName]", rootInfo.serviceName); 566 files.proxyH = replaceAll(files.proxyH, "[serviceName]", rootInfo.serviceName); 567 files.stubH = replaceAll(files.stubH, "[serviceName]", rootInfo.serviceName); 568 files.serviceH = replaceAll(files.serviceH, "[serviceName]", rootInfo.serviceName); 569 files.proxyCpp = replaceAll(files.proxyCpp, "[serviceName]", rootInfo.serviceName); 570 files.stubCpp = replaceAll(files.stubCpp, "[serviceName]", rootInfo.serviceName); 571 files.serviceCpp = replaceAll(files.serviceCpp, "[serviceName]", rootInfo.serviceName); 572 files.clientCpp = replaceAll(files.clientCpp, "[serviceName]", rootInfo.serviceName); 573} 574 575function replaceIncludes(files, rootInfo) { 576 files.iServiceH = replaceAll(files.iServiceH, "[includes]", getIncludeStr(rootInfo.includes)); 577 files.proxyH = replaceAll(files.proxyH, "[iServiceHInclude]", fileContent.iServiceHFile.name); 578 files.stubH = replaceAll(files.stubH, "[iServiceHInclude]", fileContent.iServiceHFile.name); 579 files.serviceH = replaceAll(files.serviceH, "[stubHInclude]", fileContent.stubHFile.name); 580 files.proxyCpp = replaceAll(files.proxyCpp, "[proxyHInclude]", fileContent.proxyHFile.name); 581 files.stubCpp = replaceAll(files.stubCpp, "[stubHInclude]", fileContent.stubHFile.name); 582 files.serviceCpp = replaceAll(files.serviceCpp, "[serviceHInclude]", fileContent.serviceHFile.name); 583 files.clientCpp = replaceAll(files.clientCpp, "[proxyHInclude]", fileContent.proxyHFile.name); 584 files.iServiceCpp = replaceAll(files.iServiceCpp, "[iServiceHInclude]", fileContent.iServiceHFile.name); 585} 586 587function replaceUsing(files, rootInfo) { 588 files.iServiceH = replaceAll(files.iServiceH, "[using]", getUsingStr(rootInfo.using)); 589} 590 591function genFileNames(lowServiceName, rootInfo) { 592 fileContent.iServiceHFile.name = "i_%s_service.h".format(lowServiceName); 593 fileContent.proxyHFile.name = "%s_service_proxy.h".format(lowServiceName); 594 fileContent.stubHFile.name = "%s_service_stub.h".format(lowServiceName); 595 fileContent.serviceHFile.name = "%s_service.h".format(lowServiceName); 596 fileContent.proxyCppFile.name = "%s_service_proxy.cpp".format(lowServiceName); 597 fileContent.stubCppFile.name = "%s_service_stub.cpp".format(lowServiceName); 598 fileContent.serviceCppFile.name = "%s_service.cpp".format(lowServiceName); 599 fileContent.clientCppFile.name = "%s_client.cpp".format(lowServiceName); 600 fileContent.buildGnFile.name = "BUILD.gn"; 601 fileContent.bundleJsonFile.name = "bundle.json"; 602 fileContent.profileGnFile.name = "BUILD.gn"; 603 fileContent.profileXmlFile.name = rootInfo.serviceId + ".xml"; 604 fileContent.serviceCfgFile.name = "%s_service.cfg".format(lowServiceName); 605 fileContent.serviceCfgGnFile.name = "BUILD.gn"; 606 fileContent.iServiceCppFile.name = "i_%s_service.cpp".format(lowServiceName); 607} 608 609function genFunctionCode(classInfo) { 610 let funcList = classInfo.functions; 611 let genResult = {} 612 genResult.funcEnumStr = ""; 613 genResult.iServiceFuncH = ""; //i_service.h 方法定义 614 genResult.proxyFuncH = ""; //proxy.h 方法定义 615 genResult.stubInnerFuncH = ""; // stub.h 的inner方法定义 616 genResult.proxyFuncCpp = ""; //proxy.cpp 方法实现 617 genResult.stubInnerFuncMap = ""; // stub.cpp 的inner方法映射表 618 genResult.stubInnerFuncCpp = ""; // stub.cpp 的inner方法实现 619 genResult.serviceFuncCpp = ""; // service.cpp的方法实现 620 genResult.clientFuncCpp = ""; // client.cpp 的inner方法定义 621 622 let enumTab = getTab(2); 623 let funcTab = getTab(1); 624 for (var i = 0; i < funcList.length; ++i) { 625 funcList[i].funcEnum = funcList[i].name.toUpperCase(); // remote方法的枚举值 626 genResult.funcEnumStr += (i == 0) ? "" : ",\n" + enumTab; 627 genResult.funcEnumStr += funcList[i].funcEnum; 628 629 let paramStr = getFuncParamStr(funcList[i].params); 630 genResult.iServiceFuncH += (i == 0) ? "" : "\n" + funcTab; 631 genResult.iServiceFuncH += "virtual %s %s(%s) = 0;".format(funcList[i].retType, funcList[i].name, paramStr); 632 633 genResult.proxyFuncH += (i == 0) ? "" : "\n" + funcTab; 634 genResult.proxyFuncH += "%s %s(%s) override;".format(funcList[i].retType, funcList[i].name, paramStr); 635 636 genResult.stubInnerFuncH += (i == 0) ? "" : "\n" + funcTab; 637 genResult.stubInnerFuncH += 638 "ErrCode %sInner(MessageParcel &data, MessageParcel &reply);".format(funcList[i].name); 639 640 genResult.proxyFuncCpp += genProxyFunc(funcList[i], classInfo.name, paramStr); 641 642 genResult.stubInnerFuncMap += (i == 0) ? "" : "\n" + funcTab; 643 genResult.stubInnerFuncMap += "innerFuncs_[%s] = &%sStub::%sInner;".format( 644 funcList[i].funcEnum, classInfo.name, funcList[i].name); 645 646 genResult.stubInnerFuncCpp += genStubInnerFunc(funcList[i], classInfo.name); 647 genResult.serviceFuncCpp += genServiceFunc(funcList[i], classInfo.name, paramStr); 648 649 genResult.clientFuncCpp += (i == 0) ? "" : "\n" + funcTab; 650 genResult.clientFuncCpp += "// proxy->%s(%s);".format(funcList[i].name, paramStr); 651 } 652 return genResult; 653} 654 655function genMarshallFuncs(files) { 656 let marshallFuncH = ""; 657 for (let i = 0; i < marshallFuncList.length; ++i) { 658 marshallFuncH += marshallFuncList[i].marshallFuncs.marshallFuncH; 659 marshallFuncH += marshallFuncList[i].marshallFuncs.unmarshallFuncH; 660 } 661 files.iServiceH = files.iServiceH.replace("[marshallFunctions]", marshallFuncH); 662} 663 664function genDependClasses(files) { 665 let dependSrc = ""; 666 for (let i = 0; i < dependSrcList.length; ++i) { 667 dependSrc += dependSrcList[i].srcCode + ";\n\n"; 668 } 669 files.iServiceH = files.iServiceH.replace("[dependClasses]", dependSrc); 670} 671 672function doGenerate(rootInfo) { 673 rootHFileSrc = rootInfo.rawContent; 674 let lowServiceName = rootInfo.serviceName.toLowerCase(); 675 let upperServiceName = rootInfo.serviceName.toUpperCase(); 676 677 // 生成文件名 678 genFileNames(lowServiceName, rootInfo); 679 680 // 按模板生成.h和.cpp文件内容框架 681 let files = genFilesByTemplate(upperServiceName, lowServiceName, rootInfo); 682 683 // 替换文件includes 684 replaceIncludes(files, rootInfo); 685 686 // 替换文件using 687 replaceUsing(files, rootInfo); 688 689 // 替换namespace 690 replaceServiceName(files, rootInfo); 691 692 // 替换类名 693 let classInfo = rootInfo.class[0] 694 replaceClassName(files, classInfo); 695 696 // 生成函数定义与实现 697 genFunctions(classInfo, files); 698 699 // 生成复合对象的序列化反序列化方法 700 genMarshallFuncs(files); 701 702 // 生成依赖的class定义代码 703 genDependClasses(files); 704 705 // 文件内容汇总 706 fileContent.iServiceHFile.content = files.iServiceH; 707 fileContent.proxyHFile.content = files.proxyH; 708 fileContent.stubHFile.content = files.stubH; 709 fileContent.serviceHFile.content = files.serviceH; 710 fileContent.proxyCppFile.content = files.proxyCpp; 711 fileContent.stubCppFile.content = files.stubCpp; 712 fileContent.serviceCppFile.content = files.serviceCpp; 713 fileContent.clientCppFile.content = files.clientCpp; 714 fileContent.buildGnFile.content = files.buildGn; 715 fileContent.bundleJsonFile.content = files.bundleJson; 716 fileContent.profileGnFile.content = files.profileGn; 717 fileContent.profileXmlFile.content = files.profileXml; 718 fileContent.serviceCfgFile.content = files.serviceCfg; 719 fileContent.serviceCfgGnFile.content = files.serviceGnCfg; 720 fileContent.iServiceCppFile.content = files.iServiceCpp; 721 return fileContent; 722} 723 724module.exports = { 725 doGenerate 726} 727