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