1/* 2* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3* Licensed under the Apache License, Version 2.0 (the "License"); 4* you may not use this file except in compliance with the License. 5* You may obtain a copy of the License at 6* 7* http://www.apache.org/licenses/LICENSE-2.0 8* 9* Unless required by applicable law or agreed to in writing, software 10* distributed under the License is distributed on an "AS IS" BASIS, 11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12* See the License for the specific language governing permissions and 13* limitations under the License. 14*/ 15const { isMappedTypeNode } = require("typescript"); 16const { InterfaceList, getArrayType, NumberIncrease, enumIndex, 17 isEnum, EnumValueType, getArrayTypeTwo, getMapType, EnumList, 18 jsType2CType, getUnionType } = require("../tools/common"); 19const { NapiLog } = require("../tools/NapiLog"); 20const { print } = require("../tools/tool"); 21 22const specialPrefixArr = ["p->", "vio->out."]; 23 24/** 25 * Get the real value name by deleting prefix like "p->", "vio->out.", e.g. 26 * @param {*} valueName, example: p->xxx, vio->out.yyy 27 * @returns the real value without prefix, example: xxx, yyy 28 */ 29function delPrefix(valueName) { 30 for ( var i in specialPrefixArr) { 31 if (valueName.indexOf(specialPrefixArr[i]) == 0) { 32 // Find special prefix and delete it. 33 return valueName.substring(specialPrefixArr[i].length, valueName.length); 34 } 35 } 36 // Without special prefix, nothing is changed. 37 return valueName; 38} 39 40function cToJsForInterface(value, type, dest, deep) { 41 let lt = deep 42 let result = "" 43 let ifl = InterfaceList.getValue(type) 44 for (let i in ifl) { 45 let name2 = ifl[i].name 46 let type2 = ifl[i].type 47 let isSubEnum = EnumList.getValue(type2) ? true : false; 48 let subDest = isSubEnum ? dest : "tnv%d".format(lt) 49 let interfaceType = cToJs("%s.%s".format(value, name2), type2, subDest, deep + 1) 50 if (isSubEnum) { 51 // interface include enum properties 52 result += interfaceType 53 } else { 54 result += "{\nnapi_value tnv%d = nullptr;\n".format(lt) + 55 interfaceType + `\npxt->SetValueProperty(%s,"%s",tnv%d);\n}\n` 56 .format(dest, name2, lt) 57 } 58 } 59 return result 60} 61 62function cToJs(value, type, dest, deep = 1) { 63 var propertyName = delPrefix(value); 64 if (type.indexOf("|") >= 0) { 65 return unionTempleteFunc(value, type, dest); 66 } else if (type == "void") 67 return "%s = pxt->UndefinedValue();".format(dest); 68 else if (type == "boolean") 69 return "%s = pxt->SwapC2JsBool(%s);".format(dest, value); 70 else if (type == "string") 71 return `%s = pxt->SwapC2JsUtf8(%s.c_str());`.format(dest, value) 72 else if (InterfaceList.getValue(type)) { 73 return cToJsForInterface(value, type, dest, deep); 74 } 75 else if(EnumList.getValue(type)){ 76 let lt = deep 77 let result = "" 78 let ifl = EnumList.getValue(type) 79 let type2 = ifl[0].type 80 let enumCtoJsStr = cToJs("enumInt%d".format(lt), type2, "tnv%d".format(lt), deep + 1) 81 result += "{\nnapi_value tnv%d = nullptr;\n".format(lt) + "int enumInt%d = %s;\n".format(lt, value) + 82 enumCtoJsStr + `\npxt->SetValueProperty(%s,"%s",tnv%d);\n}\n` 83 .format(dest, propertyName, lt) 84 return result 85 } 86 else if (type.substring(0, 6) == "Array<" || type.substring(type.length - 2) == "[]") { 87 let arrayType = checkArrayParamType(type) 88 return arrayTempleteFunc(arrayType, deep, dest, value) 89 } 90 else if (type.substring(0, 4) == "Map<" || type.indexOf("{[key:") == 0) { 91 return mapTempleteFunc(type, deep, dest, value) 92 } 93 else if (type.substring(0, 12) == "NUMBER_TYPE_") { 94 return `%s = NUMBER_C_2_JS(pxt, %s);`.format(dest, value) 95 } 96 else if (type == "any") { 97 return anyTempleteFunc(value) 98 } 99 else if (type == "Object" || type == "object") { 100 return objectTempleteFuncReturn(value) 101 } 102 else { 103 NapiLog.logError(`\n---- This type do not generate cToJs %s,%s,%s ----\n`.format(value, type, dest)); 104 } 105} 106 107function objectTempleteFuncReturn(value) { 108 let objectTemplete = `pxt->GetObjectValue(result, %s);` 109 .format(value) 110 return objectTemplete 111} 112 113function unionTempleteFunc(value, type, dest){ 114 let unionType = getUnionType(type) 115 let unionTypeString = '' 116 for (let i = 0; i < unionType.length; i++) { 117 if (unionType[i] == "string") { 118 unionTypeString += `if (%s_type == "string"){ 119 %s 120 %s 121 }\n`.format(value, "std::string union_string = std::any_cast<std::string>("+value+");", 122 cToJs("union_string", unionType[i], dest)) 123 } else if (unionType[i].substring(0, 12) == "NUMBER_TYPE_") { 124 unionTypeString += `if (%s_type == "number"){ 125 %s 126 %s 127 }\n`.format(value, "std::uint32_t union_number = std::any_cast<std::uint32_t>("+value+");", 128 cToJs("union_number", unionType[i], dest)) 129 } else if (unionType[i] == "boolean") { 130 unionTypeString += `if (%s_type == "boolean"){ 131 %s 132 %s 133 }\n`.format(value, "bool union_boolean = std::any_cast<bool>("+value+");", 134 cToJs("union_boolean", unionType[i], dest)) 135 } 136 } 137 return unionTypeString 138} 139 140function checkArrayParamType(type) { 141 let arrayType 142 if (type.substring(type.length - 2) == "[]") { 143 arrayType = getArrayTypeTwo(type) 144 } 145 else { 146 arrayType = getArrayType(type) 147 } 148 return arrayType 149} 150 151function arrayTempleteFunc(arrayType, deep, dest, value) { 152 let lt = deep 153 let tnv = dest 154 let tnvdef = `pxt->CreateArray(%s); 155 uint32_t outLen%d = %s.size(); 156 for(uint32_t i = 0; i < outLen%d; i++) { 157 napi_value tnv%d = nullptr; 158 [calc_out] 159 pxt->SetArrayElement(%s, i, tnv%d); 160 }`.format(tnv, lt, value, lt, lt, tnv, lt) 161 let ret = "" 162 if (arrayType.substring(0, 12) == "NUMBER_TYPE_") { 163 ret = tnvdef.replaceAll("[calc_out]", `tnv%d = NUMBER_C_2_JS(pxt,%s[i]);`.format(lt, value)) 164 } 165 else if (arrayType == "string") { 166 ret = tnvdef.replaceAll("[calc_out]", `tnv%d = pxt->SwapC2JsUtf8(%s[i].c_str());`.format(lt, value)) 167 } 168 else if (arrayType == "boolean") { 169 ret = tnvdef.replaceAll("[calc_out]", `tnv%d = pxt->SwapC2JsBool(%s[i]);`.format(lt, value)) 170 } 171 else if (arrayType == "any") { 172 return anyArrayTempleteFuncReturn(value) 173 } 174 else if (InterfaceList.getValue(arrayType)) { 175 ret = tnvdef.replaceAll("[calc_out]", cToJs(value + "[i]", arrayType, "tnv" + lt, deep + 1)) 176 } 177 return ret 178} 179 180function mapTempleteFunc(type, deep, dest, value) { 181 let mapType = getMapType(type) 182 let lt = deep 183 let tnv = dest 184 let tnvdef = `result = nullptr; 185 for (auto i = %s.begin(); i != %s.end(); i++) 186 { 187 const char * tnv%d; 188 napi_value tnv%d = nullptr; 189 [calc_out] 190 pxt->SetMapElement(%s, tnv%d, tnv%d); 191 }`.format(value, value, lt, lt + 1, tnv, lt, lt + 1) 192 let ret = "" 193 if (mapType[1] != undefined && mapType[2] == undefined) { 194 ret = mapTempleteValue(mapType, tnvdef, lt, value, tnv) 195 } 196 else if (mapType[2] != undefined) { 197 ret = mapTempleteMap(mapType, tnvdef, lt) 198 } 199 else if (mapType[3] != undefined) { 200 ret = mapTempleteArray(mapType, tnvdef, lt) 201 } 202 return ret 203} 204 205function anyTempleteFunc(value) { 206 let anyTemplete = `pxt->GetAnyValue(%s_type, result, %s);` 207 .format(value, value) 208 209 return anyTemplete 210} 211 212function anyArrayTempleteFuncReturn(value) { 213 let anyTemplete = `pxt->GetAnyValue(%s_type, result, %s);` 214 .format(value, value) 215 216 return anyTemplete 217} 218 219function mapInterface(value, lt, tnv, mapType) { 220 let ret 221 let tnvdefInterface = `result = nullptr; 222 for (auto i = %s.begin(); i != %s.end(); i++) 223 { 224 const char *tnv%d; 225 [calc_out] 226 }`.format(value, value, lt, lt + 1, tnv, lt, lt + 1) 227 let interfaceValue = InterfaceList.getValue(mapType[1]) 228 let interfaceVarName = "" 229 let interfaceVar = "" 230 let interfaceFun = "" 231 for (let i = 0; i < interfaceValue.length; i++) { 232 if (interfaceValue[i].type == 'string') { 233 interfaceVarName += `const char * tnv_%s_name; 234 napi_value tnv_%s = nullptr;\n`.format(interfaceValue[i].name, interfaceValue[i].name) 235 interfaceVar += `tnv_%s_name = "%s"; 236 tnv_%s = pxt->SwapC2JsUtf8(i->second.%s.c_str());\n` 237 .format(interfaceValue[i].name, interfaceValue[i].name, interfaceValue[i].name, interfaceValue[i].name) 238 interfaceFun += `pxt->SetMapElement(result_obj, tnv_%s_name, tnv_%s);\n` 239 .format(interfaceValue[i].name, interfaceValue[i].name, interfaceValue[i].name) 240 } 241 else if (interfaceValue[i].type.substring(0, 12) == "NUMBER_TYPE_") { 242 interfaceVarName += `const char * tnv_%s_name; 243 napi_value tnv_%s = nullptr;\n`.format(interfaceValue[i].name, interfaceValue[i].name) 244 interfaceVar += `tnv_%s_name = "%s"; 245 tnv_%s = NUMBER_C_2_JS(pxt,i->second.%s);\n` 246 .format(interfaceValue[i].name, interfaceValue[i].name, interfaceValue[i].name, interfaceValue[i].name) 247 interfaceFun += `pxt->SetMapElement(result_obj, tnv_%s_name, tnv_%s);\n` 248 .format(interfaceValue[i].name, interfaceValue[i].name, interfaceValue[i].name) 249 } 250 else if (interfaceValue[i].type == 'boolean') { 251 interfaceVarName += `const char * tnv_%s_name; 252 napi_value tnv_%s = nullptr;\n`.format(interfaceValue[i].name, interfaceValue[i].name) 253 interfaceVar += `tnv_%s_name = "%s"; 254 tnv_%s = pxt->SwapC2JsBool(i->second.%s);\n` 255 .format(interfaceValue[i].name, interfaceValue[i].name, interfaceValue[i].name, interfaceValue[i].name) 256 interfaceFun += `pxt->SetMapElement(result_obj, tnv_%s_name, tnv_%s);\n` 257 .format(interfaceValue[i].name, interfaceValue[i].name, interfaceValue[i].name) 258 } 259 } 260 ret = tnvdefInterface.replaceAll("[calc_out]", `tnv%d = (i -> first).c_str(); 261 napi_value result_obj = nullptr; 262 %s 263 %s 264 %s 265 pxt->SetMapElement(result, tnv%d, result_obj);` 266 .format(lt, interfaceVarName, interfaceVar, interfaceFun, lt)) 267 return ret 268} 269 270function mapTempleteValue(mapType, tnvdef, lt, value, tnv) { 271 let ret 272 if (mapType[1] == "string") { 273 ret = tnvdef.replaceAll("[calc_out]", `tnv%d = (i -> first).c_str(); 274 tnv%d = pxt->SwapC2JsUtf8(i->second.c_str());`.format(lt, lt + 1)) 275 } else if (mapType[1] == "boolean") { 276 ret = tnvdef.replaceAll("[calc_out]", `tnv%d = (i -> first).c_str(); 277 tnv%d = pxt->SwapC2JsBool(i->second);`.format(lt, lt + 1)) 278 } else if (mapType[1].substring(0, 12) == "NUMBER_TYPE_") { 279 ret = tnvdef.replaceAll("[calc_out]", `tnv%d = (i -> first).c_str(); 280 tnv%d = NUMBER_C_2_JS(pxt,i->second);`.format(lt, lt + 1)) 281 } else if (mapType[1] == "any") { 282 ret = tnvdef.replaceAll("[calc_out]", `tnv%d = (i -> first).c_str(); 283 pxt->GetAnyValue(%s_type, tnv%d, i->second);`.format(lt, value, lt + 1)) 284 } 285 else if (InterfaceList.getValue(mapType[1])) { 286 ret = mapInterface(value, lt, tnv, mapType) 287 } 288 else 289 NapiLog.logError(`This type do not generate cToJs %s,%s,%s`.format(value, type, dest)); 290 return ret 291} 292 293function mapTempleteMap(mapType, tnvdef, lt) { 294 let ret 295 if (mapType[2] == "string") { 296 ret = tnvdef.replaceAll("[calc_out]", `tnv%d = i->first.c_str(); 297 for(auto j = i->second.begin(); j != i->second.end(); j++){ 298 const char * tt%d; 299 napi_value tt%d; 300 tt%d = j->first.c_str(); 301 tt%d = pxt->SwapC2JsUtf8(j->second.c_str()); 302 pxt->SetMapElement(tnv%d, tt%d, tt%d); 303 }`.format(lt, lt + 2, lt + 3, lt + 2, lt + 3, lt + 1, lt + 2, lt + 3)) 304 } 305 else if (mapType[2] == "boolean") { 306 ret = tnvdef.replaceAll("[calc_out]", `tnv%d = i->first.c_str(); 307 for(auto j = i->second.begin(); j != i->second.end(); j++){ 308 const char * tt%d; 309 napi_value tt%d; 310 tt%d = j->first.c_str(); 311 tt%d = pxt->SwapC2JsBool(j->second); 312 pxt->SetMapElement(tnv%d, tt%d, tt%d); 313 }`.format(lt, lt + 2, lt + 3, lt + 2, lt + 3, lt + 1, lt + 2, lt + 3)) 314 } 315 if (mapType[2].substring(0, 12) == "NUMBER_TYPE_") { 316 ret = tnvdef.replaceAll("[calc_out]", `tnv%d = i->first.c_str(); 317 for(auto j = i->second.begin(); j != i->second.end(); j++){ 318 const char * tt%d; 319 napi_value tt%d; 320 tt%d = j->first.c_str(); 321 tt%d = NUMBER_C_2_JS(pxt,j->second); 322 pxt->SetMapElement(tnv%d, tt%d, tt%d); 323 }`.format(lt, lt + 2, lt + 3, lt + 2, lt + 3, lt + 1, lt + 2, lt + 3)) 324 } 325 return ret 326} 327 328function mapTempleteArray(mapType, tnvdef, lt) { 329 let ret 330 if (mapType[3] == "string") { 331 ret = tnvdef.replaceAll("[calc_out]", `napi_value tnv%d = nullptr; 332 pxt->CreateArray(tnv%d); 333 tnv%d = (i -> first).c_str(); 334 uint32_t len%d = i->second.size(); 335 for(uint32_t j=0;j<len%d;j++) { 336 tnv%d = pxt->SwapC2JsUtf8(i->second[j].c_str()); 337 pxt->SetArrayElement(tnv%d, j, tnv%d); 338 }`.format(lt + 2, lt + 2, lt, lt, lt, lt + 2, lt + 1, lt + 2)) 339 } else if (mapType[3] == "boolean") { 340 ret = tnvdef.replaceAll("[calc_out]", `napi_value tnv%d = nullptr; 341 pxt->CreateArray(tnv%d); 342 tnv%d = (i -> first).c_str(); 343 uint32_t len%d = i->second.size(); 344 for(uint32_t j=0;j<len%d;j++) { 345 tnv%d = pxt->SwapC2JsBool(i->second[j]); 346 pxt->SetArrayElement(tnv%d, j, tnv%d); 347 }`.format(lt + 2, lt + 2, lt, lt, lt, lt + 2, lt + 1, lt + 2)) 348 } else if (mapType[3].substring(0, 12) == "NUMBER_TYPE_") { 349 ret = tnvdef.replaceAll("[calc_out]", `napi_value tnv%d = nullptr; 350 pxt->CreateArray(tnv%d); 351 tnv%d = (i -> first).c_str(); 352 uint32_t len%d = i->second.size(); 353 for(uint32_t j=0;j<len%d;j++) { 354 tnv%d = NUMBER_C_2_JS(pxt,i->second[j]); 355 pxt->SetArrayElement(tnv%d, j, tnv%d); 356 }`.format(lt + 2, lt + 2, lt, lt, lt, lt + 2, lt + 1, lt + 2)) 357 } 358 return ret 359} 360 361function returnGenerateMap(returnInfo, param) { 362 let type = returnInfo.type 363 let mapType = getMapType(type) 364 let mapTypeString 365 if (mapType[1] != undefined && mapType[2] == undefined) { 366 if (mapType[1] == "string") { mapTypeString = "std::string" } 367 else if (mapType[1].substring(0, 12) == "NUMBER_TYPE_") { mapTypeString = mapType[1] } 368 else if (mapType[1] == "boolean") { mapTypeString = "bool" } 369 else if (mapType[1] == "any") { mapTypeString = "std::any" } 370 else { mapTypeString = mapType[1] } 371 } 372 else if (mapType[2] != undefined) { 373 if (mapType[2] == "string") { mapTypeString = "std::map<std::string,std::string>" } 374 else if (mapType[2].substring(0, 12) == "NUMBER_TYPE_") { "std::map<std::string,"+mapType[2]+">" } 375 else if (mapType[2] == "boolean") { mapTypeString = "std::map<std::string,bool>" } 376 } 377 else if (mapType[3] != undefined) { 378 if (mapType[3] == "string") { mapTypeString = "std::vector<std::string>" } 379 else if (mapType[3].substring(0, 12) == "NUMBER_TYPE_") { mapTypeString = "std::vector<"+mapType[3]+">" } 380 else if (mapType[3] == "boolean") { mapTypeString = "std::vector<bool>" } 381 } 382 let modifiers = returnInfo.optional ? "*" : "&" 383 param.valueOut = returnInfo.optional ? "std::map<std::string,%s>* out = nullptr;".format(mapTypeString) 384 : "std::map<std::string,%s> out;".format(mapTypeString) 385 param.valueDefine += "%sstd::map<std::string,%s>%s out" 386 .format(param.valueDefine.length > 0 ? ", " : "", mapTypeString, modifiers) 387} 388 389function returnGenerateUnion (param) { 390 param.valueOut = `std::any out; 391 std::string out_type;` 392 param.valueDefine += "%sstd::any &out".format(param.valueDefine.length > 0 ? ", " : "") 393} 394 395function returnGenerateObject(returnInfo, param, data) { 396 param.valueOut = `std::map<std::string, std::any> out;` 397 param.valueDefine += "%sstd::map<std::string, std::any> &out".format(param.valueDefine.length > 0 ? ", " : "") 398 399} 400 401/** 402 * 获取方法返回参数的填充代码 403 * @param returnInfo 方法的返回参数信息 404 * @param param 方法的所有参数信息 405 * @returns 返回参数的填充代码123 返回测试的值 406 */ 407function getReturnFill(returnInfo, param) { 408 let type = returnInfo.type 409 let valueFillStr = "" 410 if (param.callback) { // callback方法的返回参数处理 411 if (param.callback.isAsync) { 412 // 异步callback方法返回的是一个结构体,包含errcode和data两部分, 详见basic.d.ts中AsyncCallback的定义 413 valueFillStr = "vio->outErrCode" 414 param.valueDefine += "%suint32_t& outErrCode".format(param.valueDefine.length > 0 ? ", " : "") 415 } 416 417 if (type != "void") { 418 // callback<xxx> 中的xxx不是void时,生成的capp代码才需要用户填充out参数 419 valueFillStr += "%svio->out".format(valueFillStr.length > 0 ? ", " : "") 420 } 421 } else { // 普通方法的返回参数处理 422 valueFillStr = "vio->out" 423 } 424 return valueFillStr 425} 426 427function isObjectType(type) { 428 if(type == "Object" || type == "object") { 429 return true; 430 } 431 return false; 432} 433 434function returnGenerate(returnInfo, param, data) { 435 let type = returnInfo.type 436 let valueFillStr = getReturnFill(returnInfo, param) 437 param.valueFill += ("%s" + valueFillStr).format(param.valueFill.length > 0 ? ", " : "") 438 let outParam = returnInfo.optional ? "(*vio->out)" : "vio->out" 439 let modifiers = returnInfo.optional ? "*" : "&" 440 if (returnInfo.optional) { 441 param.optionalParamDestory += "C_DELETE(vio->out);\n " 442 } 443 444 if (!isEnum(type, data)) { 445 param.valuePackage = cToJs(outParam, type, "result") 446 } else if (type.indexOf("|") >= 0) { 447 returnGenerateUnion(param) 448 } 449 450 if (type == "string") { 451 param.valueOut = returnInfo.optional ? "std::string* out = nullptr;" : "std::string out;" 452 param.valueDefine += "%sstd::string%s out".format(param.valueDefine.length > 0 ? ", " : "", modifiers) 453 } 454 else if (type == "void") { 455 NapiLog.logInfo("The current void type don't need generate"); 456 } 457 else if (type == "boolean") { 458 param.valueOut = returnInfo.optional ? "bool* out = nullptr;" : "bool out;" 459 param.valueDefine += "%sbool%s out".format(param.valueDefine.length > 0 ? ", " : "", modifiers) 460 } 461 else if (isEnum(type, data)) { 462 returnGenerateEnum(data, returnInfo, param) 463 } 464 else if(generateType(type)){ 465 returnGenerate2(returnInfo, param, data) 466 } 467 else if (type.substring(0, 12) == "NUMBER_TYPE_") { 468 param.valueOut = type + (returnInfo.optional ? "* out = nullptr;" : " out;") 469 param.valueDefine += "%s%s%s out".format(param.valueDefine.length > 0 ? ", " : "", type, modifiers) 470 } 471 else if (isObjectType(type)) { 472 returnGenerateObject(returnInfo, param, data) 473 } 474 else { 475 NapiLog.logError("Do not support returning the type [%s].".format(type)); 476 } 477} 478 479function generateType(type){ 480 if (InterfaceList.getValue(type)) { 481 return true 482 } 483 else if (type.substring(0, 6) == "Array<") { 484 return true 485 } 486 else if (type.substring(type.length - 2) == "[]") { 487 return true 488 } 489 else if (type.substring(0, 4) == "Map<" || type.indexOf("{[key:") == 0) { 490 return true 491 } 492 else if (type == "any" || type == "Object" || type == "object") { 493 return true 494 } 495 else { 496 return false 497 } 498} 499function isMapType(type) { 500 if(type.substring(0, 4) == "Map<" || type.indexOf("{[key:") == 0) { 501 return true; 502 } 503 return false; 504} 505 506function returnGenerate2(returnInfo, param, data){ 507 let type = returnInfo.type 508 let modifiers = returnInfo.optional ? "*" : "&" 509 510 if (InterfaceList.getValue(type)) { 511 param.valueOut = type + (returnInfo.optional ? "* out = nullptr;" : " out;") 512 param.valueDefine += "%s%s%s out".format(param.valueDefine.length > 0 ? ", " : "", type, modifiers) 513 } 514 else if (type.substring(0, 6) == "Array<") { 515 let arrayType = getArrayType(type) 516 arrayType = jsType2CType(arrayType) 517 if (arrayType == "any") { 518 param.valueOut = `std::any out; 519 std::string out_type;` 520 param.valueDefine += "%sstd::any &out".format(param.valueDefine.length > 0 ? ", " : "") 521 } else { 522 param.valueOut = returnInfo.optional ? "std::vector<%s>* out = nullptr;".format(arrayType) 523 : "std::vector<%s> out;".format(arrayType) 524 param.valueDefine += "%sstd::vector<%s>%s out".format( 525 param.valueDefine.length > 0 ? ", ": "", arrayType, modifiers) 526 } 527 } 528 else if (type.substring(type.length - 2) == "[]") { 529 let arrayType = getArrayTypeTwo(type) 530 arrayType = jsType2CType(arrayType) 531 if (arrayType == "any") { 532 param.valueOut = `std::any out; 533 std::string out_type;` 534 param.valueDefine += "%sstd::any &out".format(param.valueDefine.length > 0 ? ", " : "") 535 } else { 536 param.valueOut = returnInfo.optional ? "std::vector<%s>* out = nullptr;".format(arrayType) 537 : "std::vector<%s> out;".format(arrayType) 538 param.valueDefine += "%sstd::vector<%s>%s out".format( 539 param.valueDefine.length > 0 ? ", " : "", arrayType, modifiers) 540 } 541 } 542 else if (isMapType(type)) { 543 returnGenerateMap(returnInfo, param) 544 } 545 else if (type == "any") { 546 param.valueOut = `std::any out; 547 std::string out_type;` 548 param.valueDefine += "%sstd::any &out".format(param.valueDefine.length > 0 ? ", " : "") 549 } 550 else if (isObjectType(type)) { 551 param.valueOut = `std::map<std::string, std::any> out;` 552 param.valueDefine += "%sstd::map<std::string, std::any> &out".format(param.valueDefine.length > 0 ? ", " : "") 553 } 554} 555 556function returnGenerateEnum(data, returnInfo, param) { 557 let type = returnInfo.type 558 let index = enumIndex(type, data) 559 let modifiers = returnInfo.optional ? "*" : "&" 560 if (data.enum[index].body.enumValueType == EnumValueType.ENUM_VALUE_TYPE_NUMBER) { 561 type = "NUMBER_TYPE_" + NumberIncrease.getAndIncrease() 562 } else if (data.enum[index].body.enumValueType == EnumValueType.ENUM_VALUE_TYPE_STRING) { 563 type = "string" 564 } else { 565 NapiLog.logError(`function returnGenerateEnum:this type is not support %s`.format(type)); 566 return 567 } 568 param.valuePackage = cToJs("vio->out", type, "result") 569 if (type == "string") { 570 param.valueOut = returnInfo.optional ? "std::string* out = nullptr;" : "std::string out;" 571 param.valueDefine += "%sstd::string%s out".format(param.valueDefine.length > 0 ? ", " : "", modifiers) 572 } 573 else if (type.substring(0, 12) == "NUMBER_TYPE_") { 574 param.valueOut = type + " out;" 575 param.valueDefine += "%s%s%s out".format(param.valueDefine.length > 0 ? ", " : "", type, modifiers) 576 } 577} 578 579module.exports = { 580 cToJs, 581 cToJsForInterface, 582 returnGenerate, 583 returnGenerateEnum 584} 585