• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 { InterfaceList, getArrayType, getArrayTypeTwo, NumberIncrease,
16    enumIndex, isEnum, EnumValueType, getMapType,
17    EnumList, getUnionType, TypeList } = require("../tools/common");
18const re = require("../tools/re");
19const { NapiLog } = require("../tools/NapiLog");
20const { getConstNum } = require("../tools/tool");
21
22class LenIncrease { }
23LenIncrease.LEN_TO = 1;
24LenIncrease.Reset = function () {
25    LenIncrease.LEN_TO = 1;
26}
27LenIncrease.getAndIncrease = function () {
28    return LenIncrease.LEN_TO++;
29}
30
31function getValueProperty(napiVn, name) {
32    return 'pxt->GetValueProperty(%s, "%s")'.format(napiVn, name)
33}
34
35function jsToC(dest, napiVn, type, enumType = 0) {
36    if (type.indexOf("|") >= 0) {
37        return unionTempleteFunc(dest, napiVn, type)
38    } else if (type == "string") {
39        if (napiVn.indexOf("GetValueProperty") >= 0) {
40            let lt = LenIncrease.getAndIncrease()
41            return `napi_value tnv%d = %s;\n    if (tnv%d != nullptr) {pxt->SwapJs2CUtf8(tnv%d, %s);}\n`
42                .format(lt, napiVn, lt, lt, dest)
43        } else {
44            return "pxt->SwapJs2CUtf8(%s, %s);".format(napiVn, dest)
45        }
46    } else if (type.substring(type.length - 2) == "[]") {
47        return arrTemplete(dest, napiVn, type);
48    } else if (type.substring(0, 12) == "NUMBER_TYPE_") {
49        return numTempleteFunc (enumType, napiVn, type, dest);
50    } else if (InterfaceList.getValue(type)) {
51        let tt = ""
52        let ifl = InterfaceList.getValue(type)
53        for (let i in ifl) {
54            let name2 = ifl[i].name
55            let type2 = ifl[i].type
56            tt += jsToC("%s.%s".format(dest, name2), getValueProperty(napiVn, name2), type2)
57        }
58        return tt
59    } else if (TypeList.getValue(type)) {
60        return typeTempleteFunc(type, dest, napiVn);
61    } else if (EnumList.getValue(type)) {
62        return jsToCEnum(type, dest, napiVn)
63    } else if (type.indexOf("Array<") == 0) {
64        return arrTemplete(dest, napiVn, type);
65    } else if (type == "boolean") {
66        return `BOOLEAN_JS_2_C(%s, %s, %s);\n`.format(napiVn, "bool", dest)
67    } else if (type.substring(0, 4) == "Map<" || type.substring(0, 6) == "{[key:") {
68        return mapTempleteFunc(dest, napiVn, type);
69    } else if (type == "any") {
70        return anyTempleteFunc(dest, napiVn, type);
71    } else if (type == "Object" || type == "object") {
72        return objectTempleteFunc(dest, napiVn);
73    }else {
74        NapiLog.logError(`do not support to generate jsToC %s,%s,%s`.format(dest, napiVn, type));
75    }
76}
77
78function typeTempleteFunc(type, dest, napiVn) {
79  let tt = "";
80  let ifl = TypeList.getValue(type);
81  if (typeof (ifl) == 'object') {
82    for (let i in ifl) {
83      let name2 = ifl[i].name;
84      let type2 = ifl[i].type;
85      tt += jsToC("%s.%s".format(dest, name2), getValueProperty(napiVn, name2), type2);
86    }
87  } else {
88    tt += jsToC(dest, napiVn, ifl);
89  }
90  return tt;
91}
92
93function unionTempleteFunc(dest, napiVn, type) {
94    let unionType = getUnionType(type)
95    let unionTypeString = ''
96    unionTypeString += '%s_type = pxt->GetUnionType(%s);\n'.format(dest, napiVn)
97    for (let i = 0; i < unionType.length; i++) {
98        if (unionType[i] == "string") {
99            unionTypeString += `if (%s_type == "string") {
100                std::string union_string;
101                %s
102                %s
103            }\n`.format(dest, jsToC("union_string", napiVn, unionType[i]), dest+" = union_string;")
104        } else if (unionType[i].substring(0, 12) == "NUMBER_TYPE_") {
105            unionTypeString += `if (%s_type == "number") {
106                std::uint32_t union_number;
107                %s
108                %s
109            }\n`.format(dest, jsToC("union_number", napiVn, unionType[i]), dest+" = union_number;")
110        } else if (unionType[i] == "boolean") {
111            unionTypeString += `if (%s_type == "boolean") {
112                bool union_boolean;
113                %s
114                %s
115            }\n`.format(dest, jsToC("union_boolean", napiVn, unionType[i]), dest+" = union_boolean;")
116        }
117    }
118    return unionTypeString
119}
120
121function jsToCEnum(type, dest, napiVn) {
122    let tt = ""
123    let ifl = EnumList.getValue(type)
124    for (let i in ifl) {
125        let type2 = ifl[i].type
126        tt += jsToC("%s".format(dest), getValueProperty(napiVn, dest), type2, type)
127    }
128    return tt
129}
130
131function getArrayTypeTemplete(type) {
132    let arrayType
133    if (type.substring(type.length - 2) == "[]") {
134        arrayType = getArrayTypeTwo(type)
135    } else {
136        arrayType = getArrayType(type)
137    }
138    if (arrayType == "string") {
139        arrayType = "std::string"
140    } else if (arrayType == "boolean") {
141        arrayType = "bool"
142    } else if (arrayType == "any") {
143        arrayType = "any"
144    } else if (arrayType == "[key:string]:string" || arrayType == "Map<string,string>") {
145        arrayType = "std::map<std::string, std::string>"
146    } else if (arrayType.substring(0, arrayType.lastIndexOf("_") + 1) == "[key:string]:NUMBER_TYPE_" ||
147        arrayType.substring(0, arrayType.lastIndexOf("_") + 1) == "Map<string,NUMBER_TYPE_>") {
148        let len = arrayType.length
149        let num = arrayType.substring(arrayType.lastIndexOf("_") + 1, len)
150        arrayType = "std::map<std::string, NUMBER_TYPE_%s>".format(num)
151    } else if (arrayType == "[key:string]:boolean" || arrayType == "Map<string,boolean>") {
152        arrayType = "std::map<std::string, bool>"
153    } else if (arrayType.substring(0, 14) == "[key:string]:") {
154        let valueType = arrayType.substring(14, arrayType.length)
155        arrayType = "std::map<std::string, %s>".format(valueType)
156    } else if (arrayType.substring(0, 11) == "Map<string,") {
157        let valueType = arrayType.substring(11, arrayType.length-1)
158        arrayType = "std::map<std::string, %s>".format(valueType)
159    }
160    return arrayType
161}
162
163function arrTemplete(dest, napiVn, type) {
164    let lt = LenIncrease.getAndIncrease()
165    let arrayType = getArrayTypeTemplete(type)
166    if (arrayType == "any") {
167        return anyArrayTempleteFunc(dest, napiVn);
168    }
169    let arrTemplete = `\
170    uint32_t len[replace_lt] = pxt->GetArrayLength(%s);
171    for (uint32_t i[replace_lt] = 0; i[replace_lt] < len[replace_lt]; i[replace_lt]++) {
172        %s tt[replace_lt];
173        [replace_swap]
174        %s.push_back(tt[replace_lt]);
175    }\n`.format(napiVn, arrayType == "boolean" ? "bool" : arrayType, dest)
176
177    let arrMapTemplete = `\
178    uint32_t len[replace_lt] = pxt->GetArrayLength(%s);
179    for (uint32_t i[replace_lt] = 0; i[replace_lt] < len[replace_lt]; i[replace_lt]++) {
180        %s tt[replace_lt];
181        napi_value mapPara = pxt->GetArrayElement(pxt->GetArgv(XNapiTool::ZERO), i[replace_lt]);
182        uint32_t len2 = pxt->GetMapLength(mapPara);
183        for (uint32_t i2 = 0; i2 < len2; i2++) {
184            std::string ttName;
185            pxt->SwapJs2CUtf8(pxt->GetMapElementName(mapPara, i2), ttName);
186            napi_value mapValue = pxt->GetMapElementValue(mapPara, ttName.c_str());
187            [code_gen]
188            tt[replace_lt].insert(std::make_pair(ttName, ttValue));
189        }
190        %s.push_back(tt[replace_lt]);
191    }\n`.format(napiVn, arrayType, dest)
192    arrTemplete = arrTemplete.replaceAll("[replace_lt]", lt)
193
194    let str = "std::map<std::string,"
195    let strLen = str.length
196    if (arrayType.substring(0, strLen) == "std::map<std::string,") {
197        let codegen = getMapValueCode(arrayType)
198        if (codegen == null) {
199            return arrMapTemplete
200        }
201        arrMapTemplete = arrMapTemplete.replaceAll("[replace_lt]", lt)
202        arrMapTemplete = arrMapTemplete.replaceAll("[code_gen]", codegen)
203        return arrMapTemplete
204    } else {
205        arrTemplete = getArrTempletereplaceSwap(arrTemplete, arrayType, napiVn, lt)
206    }
207    return arrTemplete
208}
209
210function numTempleteFunc(enumType, napiVn, type, dest) {
211    if (enumType) {
212        if (napiVn.indexOf("GetValueProperty") >= 0) {
213            let lt = LenIncrease.getAndIncrease()
214            return `napi_value tnv%d = %s;\n    if (tnv%d != nullptr) {NUMBER_JS_2_C_ENUM(tnv%d, %s, %s, %s);}\n`
215            .format(lt, napiVn, lt, lt, type, dest, enumType)
216        } else {
217            return `NUMBER_JS_2_C_ENUM(%s, %s, %s, %s);`.format(napiVn, type, dest, enumType)
218        }
219    } else {
220        if (napiVn.indexOf("GetValueProperty") >= 0) {
221            let lt = LenIncrease.getAndIncrease()
222            return `napi_value tnv%d = %s;\n    if (tnv%d != nullptr) {NUMBER_JS_2_C(tnv%d, %s, %s);}\n`
223            .format(lt, napiVn, lt, lt, type, dest)
224        } else {
225            return `NUMBER_JS_2_C(%s, %s, %s);`.format(napiVn, type, dest)
226        }
227   }
228}
229
230function getMapValueCode(arrayType) {
231    let valueTypeOut = arrayType.substring(22, arrayType.length-1)
232    let strTypeOut = "%s".format(valueTypeOut)
233    let codegen
234    if (strTypeOut == "std::string") {
235        codegen = '\
236        std::string ttValue;\n\
237        pxt->SwapJs2CUtf8(mapValue, ttValue);'
238    } else if (strTypeOut == "bool") {
239        codegen = '\
240        bool ttValue;\n\
241        ttValue = pxt->SwapJs2CBool(mapValue);'
242    } else if (strTypeOut.substr(0, 12) == "NUMBER_TYPE_") {
243        codegen = '\
244        %s ttValue;\n\
245        NUMBER_JS_2_C(mapValue, %s, ttValue);'.format(strTypeOut, strTypeOut)
246    }
247    return codegen
248}
249
250function getArrTempletereplaceSwap(arrTemplete, arrayType, napiVn, lt) {
251    if (arrayType.substring(0, 12) == "NUMBER_TYPE_") {
252        arrTemplete = arrTemplete.replaceAll("[replace_swap]",
253            "NUMBER_JS_2_C(pxt->GetArrayElement(%s, i%d), %s, tt%d);".format(napiVn, lt, arrayType, lt))
254    } else if (arrayType == "std::string") {
255        arrTemplete = arrTemplete.replaceAll("[replace_swap]",
256            "pxt->SwapJs2CUtf8(pxt->GetArrayElement(%s, i%d), tt%d);".format(napiVn, lt, lt))
257    } else if (InterfaceList.getValue(arrayType)) {
258        arrTemplete = arrTemplete.replaceAll("[replace_swap]",
259            jsToC("tt" + lt, "pxt->GetArrayElement(%s, i%d)".format(napiVn, lt), arrayType))
260    } else if (arrayType == "bool") {
261        arrTemplete = arrTemplete.replaceAll("[replace_swap]",
262            "tt%d = pxt->SwapJs2CBool(pxt->GetArrayElement(%s, i%d));".format(lt, napiVn, lt))
263    }
264    return arrTemplete
265}
266function getMapValueType(strLen, keyType, arrayType){
267    let valueTypeIn
268    if (keyType == "[key:string]:"){
269        valueTypeIn = arrayType.substring(strLen, arrayType.length)
270    } else if (keyType == "Map<string,"){
271        valueTypeIn = arrayType.substring(strLen, arrayType.length - 1)
272    }
273
274    let mapValueType
275    if (valueTypeIn == "string") {
276        mapValueType = "std::string"
277    } else if (valueTypeIn == "boolean") {
278        mapValueType = "bool"
279    } else {
280        mapValueType = valueTypeIn
281    }
282    return mapValueType
283}
284
285function getMapKeyLen(arrayType) {
286    let strLen
287    if (arrayType.substring(0,13) == "[key:string]:") {
288        strLen = "[key:string]:".length
289    }else if (arrayType.substring(0,10) == "Map<string") {
290        strLen = "Map<string,".length
291    }
292    return strLen
293}
294
295function paramGenerateArray(p, funcValue, param) {
296    let type = funcValue.type
297    let name = funcValue.name
298    let inParamName = funcValue.optional ? "(*vio->in" + p + ")" : "vio->in" + p
299    let modifiers = funcValue.optional ? "* " : "&"
300    if (type.substring(type.length - 2) == "[]") {
301        let arrayType = getArrayTypeTwo(type)
302        if (arrayType == "string") arrayType = "std::string"
303        if (arrayType == "boolean") arrayType = "bool"
304        if (arrayType == "any") {
305            return paramGenerateAnyArray(p, name, type, param)
306        }
307        param.valueIn += funcValue.optional ? "\n    std::vector<%s>* in%d = nullptr;".format(arrayType, p)
308                                            : "\n    std::vector<%s> in%d;".format(arrayType, p)
309        param.valueCheckout += jsToC(inParamName, "pxt->GetArgv(%d)".format(getConstNum(p)), type)
310        param.valueFill += "%svio->in%d".format(param.valueFill.length > 0 ? ", " : "", p)
311        param.valueDefine += "%sstd::vector<%s>%s%s".format(param.valueDefine.length > 0 ? ", "
312                            : "", arrayType, modifiers, name)
313    } else if (type.substring(0, 6) == "Array<") {
314        let arrayType = getArrayType(type)
315        let strLen =  getMapKeyLen(arrayType)
316        let keyType = arrayType.substring(0, strLen)
317        let suType = arrayType.substring(0,12)
318        if (arrayType == "string") {
319            arrayType = "std::string"
320        } else if (arrayType == "boolean") {
321            arrayType = "bool"
322        } else if (arrayType == "any") {
323            return paramGenerateAnyArray(p, name, type, param)
324        }
325        else if (keyType == "[key:string]:"|| keyType == "Map<string,") {
326            let mapValueType = getMapValueType(strLen, keyType, arrayType);
327            arrayType = "std::map<std::string, %s>".format(mapValueType)
328        }
329        param.valueIn += funcValue.optional ? "\n    std::vector<%s>* in%d = nullptr;".format(arrayType, p)
330                                            : "\n    std::vector<%s> in%d;".format(arrayType, p)
331        let arrValueCheckout = jsToC(inParamName, "pxt->GetArgv(%d)".format(getConstNum(p)), type)
332        if (funcValue.optional) {
333            arrValueCheckout = "if (pxt->GetArgc() > %s) {\n        vio->in%d = new std::vector<%s>;\n"
334                .format(getConstNum(p), p, arrayType) + arrValueCheckout + "    }\n"
335            param.optionalParamDestory += "C_DELETE(vio->in%d);\n    ".format(p)
336        }
337        param.valueCheckout += arrValueCheckout
338        param.valueFill += "%svio->in%d".format(param.valueFill.length > 0 ? ", " : "", p)
339        param.valueDefine += "%sstd::vector<%s>%s%s".format(param.valueDefine.length > 0 ? ", "
340            : "", arrayType, modifiers, name)
341    } else {
342        NapiLog.logError("The current version do not support to this param to generate :", name, "type :", type);
343    }
344}
345
346function paramGenerateAny(p, name, type, param) {
347    param.valueIn += `\n    std::any in%d;
348        std::string in%d_type;`.format(p, p)
349    param.valueCheckout += jsToC("vio->in" + p, "pxt->GetArgv(%d)".format(getConstNum(p)), type)
350    param.valueFill += "%svio->in%d".format(param.valueFill.length > 0 ? ", " : "", p)
351    param.valueDefine += "%sstd::any &%s".format(param.valueDefine.length > 0 ? ", " : "", name)
352}
353
354function paramGenerateAnyArray(p, name, type, param) {
355    param.valueIn += `\n    std::any in%d;
356        std::string in%d_type;`.format(p, p)
357    param.valueCheckout += jsToC("vio->in" + p, "pxt->GetArgv(%d)".format(getConstNum(p)), type)
358    param.valueFill += "%svio->in%d".format(param.valueFill.length > 0 ? ", " : "", p)
359    param.valueDefine += "%sstd::any &%s".format(param.valueDefine.length > 0 ? ", " : "", name)
360}
361
362function paramGenerateEnum(data, funcValue, param, p) {
363    let index = enumIndex(funcValue.type, data)
364    if (data.enum[index].body.enumValueType == EnumValueType.ENUM_VALUE_TYPE_NUMBER) {
365        funcValue.type = "NUMBER_TYPE_" + NumberIncrease.getAndIncrease()
366    } else if (data.enum[index].body.enumValueType == EnumValueType.ENUM_VALUE_TYPE_STRING) {
367        funcValue.type = "string"
368    } else {
369        NapiLog.logError(`paramGenerate is not support`);
370        return
371    }
372    paramGenerate(p, funcValue, param, data)
373}
374
375function paramGenerateMap(funcValue, param, p) {
376    let type = funcValue.type
377    let name = funcValue.name
378    let mapType = getMapType(type)
379    let mapTypeString
380    if (mapType[1] != undefined && mapType[2] == undefined) {
381        if (mapType[1] == "string") { mapTypeString = "std::string" }
382        else if (mapType[1].substring(0, 12) == "NUMBER_TYPE_") { mapTypeString = mapType[1] }
383        else if (mapType[1] == "boolean") { mapTypeString = "bool" }
384        else if (mapType[1] == "any") { mapTypeString = "std::any" }
385        else { mapTypeString = mapType[1] }
386    }
387    else if (mapType[2] != undefined) {
388        if (mapType[2] == "string") { mapTypeString = "std::map<std::string, std::string>" }
389        else if (mapType[2].substring(0, 12) == "NUMBER_TYPE_") { "std::map<std::string, "+mapType[2]+">" }
390        else if (mapType[2] == "boolean") { mapTypeString = "std::map<std::string, bool>" }
391    }
392    else if (mapType[3] != undefined) {
393        if (mapType[3] == "string") { mapTypeString = "std::vector<std::string>" }
394        else if (mapType[3].substring(0, 12) == "NUMBER_TYPE_") { mapTypeString = "std::vector<"+mapType[3]+">" }
395        else if (mapType[3] == "boolean") { mapTypeString = "std::vector<bool>" }
396    }
397    paramGenerateMap2(funcValue, param, p, mapType, mapTypeString, name)
398}
399
400function paramGenerateMap2(funcValue, param, p, mapType, mapTypeString, name) {
401    let inParamName = funcValue.optional ? "(*vio->in" + p + ")" : "vio->in" + p
402    let modifiers = funcValue.optional ? "*" : "&"
403    if (mapType[1] == "any") {
404        param.valueIn += funcValue.optional ? `\n    std::map<std::string, %s>* in%d = nullptr;
405                                                std::string in%d_type;`.format(mapTypeString, p, p)
406                                            : `\n    std::map<std::string, %s> in%d;
407                                                std::string in%d_type;`.format(mapTypeString, p, p)
408    } else {
409        param.valueIn += funcValue.optional ? "\n    std::map<std::string, %s>* in%d = nullptr;"
410                                            .format(mapTypeString, p)
411                                        : "\n    std::map<std::string, %s> in%d;".format(mapTypeString, p)
412    }
413    param.valueCheckout += getValueCheckout(funcValue, param, inParamName, p,
414        "std::map<std::string, %s>".format(mapTypeString))
415    param.valueFill += "%svio->in%d".format(param.valueFill.length > 0 ? ", " : "", p)
416    param.valueDefine += "%sstd::map<std::string, %s>%s %s"
417            .format(param.valueDefine.length > 0 ? ", " : "", mapTypeString, modifiers, name)
418}
419
420function mapTempleteFunc(dest, napiVn, type) {
421    let mapType = getMapType(type)
422    let lt = LenIncrease.getAndIncrease()
423    let mapTemplete = ""
424    if (mapType[1] != undefined && mapType[2] == undefined) {
425        mapTemplete = mapValue(mapType, napiVn, dest, lt)
426    }
427    else if (mapType[2] != undefined) {
428        mapTemplete = mapMap(mapType, napiVn, dest, lt)
429    }
430    else if (mapType[3] != undefined) {
431        mapTemplete = mapArray(mapType, napiVn, dest, lt)
432    }
433    return mapTemplete
434}
435
436function anyTempleteFunc(dest) {
437    let anyTemplete = `%s_type = pxt->GetAnyType(pxt->GetArgv(XNapiTool::ZERO));
438    pxt->SetAnyValue(%s_type, pxt->GetArgv(XNapiTool::ZERO), %s);\n`
439    .format(dest, dest, dest)
440
441    return anyTemplete
442}
443
444function anyArrayTempleteFunc(dest, napiVn) {
445    let anyArrayTemplete = `%s_type = pxt->GetAnyArrayType(%s);
446    pxt->SetAnyValue(%s_type, %s, %s);\n`
447    .format(dest, napiVn, dest, napiVn, dest)
448
449    return anyArrayTemplete
450}
451
452let mapValueTemplete = `\
453uint32_t len[replace_lt] = pxt->GetMapLength(%s);
454for (uint32_t i[replace_lt] = 0; i[replace_lt] < len[replace_lt]; i[replace_lt]++) {
455    std::string tt[replace_lt];
456    %s tt[replace_lt+1];
457    [replace_swap]
458    %s.insert(std::make_pair(tt[replace_lt], tt[replace_lt+1]));
459}`
460
461function mapInterface(mapTypeString, mapTemplete, napiVn, lt) {
462    let interfaceValue = InterfaceList.getValue(mapTypeString)
463    let interfaceVarName = ""
464    let interfaceFun = ""
465    for (let i = 0; i < interfaceValue.length; i++) {
466        if (interfaceValue[i].type == 'string') {
467            interfaceVarName += `std::string %dName = "%d";\n`.format(interfaceValue[i].name, interfaceValue[i].name)
468            interfaceFun +=
469                `pxt->%s(pxt->%s(pxt->GetMapElementValue(pxt->GetArgv(XNapiTool::ZERO),
470            tt%d.c_str()), %sName.c_str()), tt%d.%s);\n`
471                    .format("SwapJs2CUtf8", "GetMapElementValue",
472                        lt, interfaceValue[i].name, lt+1, interfaceValue[i].name)
473        }
474        else if (interfaceValue[i].type.substring(0, 12) == "NUMBER_TYPE_") {
475            interfaceVarName += `std::string %dName = "%d";\n`.format(interfaceValue[i].name, interfaceValue[i].name)
476            interfaceFun +=
477                `%s(pxt->%s(pxt->GetMapElementValue(pxt->GetArgv(XNapiTool::ZERO),
478            tt%d.c_str()), %sName.c_str()), %s, tt%d.%s);\n`
479                    .format("NUMBER_JS_2_C", "GetMapElementValue", lt, interfaceValue[i].name,
480                        interfaceValue[i].type, lt + 1, interfaceValue[i].name)
481        }
482        else if (interfaceValue[i].type == 'boolean') {
483            interfaceVarName += `std::string %dName = "%d";\n`.format(interfaceValue[i].name, interfaceValue[i].name)
484            interfaceFun +=
485                `tt%d.%s = pxt->%s(pxt->%s(pxt->GetMapElementValue(pxt->GetArgv(XNapiTool::ZERO),
486            tt%d.c_str()), %sName.c_str()));\n`
487                    .format(lt + 1, interfaceValue[i].name, "SwapJs2CBool", "GetMapElementValue",
488                        lt, interfaceValue[i].name)
489        }
490    }
491    mapTemplete = mapTemplete.replaceAll("[replace_swap]",
492        `pxt->SwapJs2CUtf8(pxt->GetMapElementName(%s, i%d), tt%d);
493        %d
494        %d`.format(napiVn, lt, lt, interfaceVarName, interfaceFun))
495    return mapTemplete
496}
497
498function mapValue(mapType, napiVn, dest, lt) {
499    let mapTypeString
500    if (mapType[1] == "string") { mapTypeString = "std::string" }
501    else if (mapType[1].substring(0, 12) == "NUMBER_TYPE_") { mapTypeString = mapType[1] }
502    else if (mapType[1] == "boolean") { mapTypeString = "bool" }
503    else if (mapType[1] == "any") { mapTypeString = "std::any" }
504    else if (mapType[1] != null) { mapTypeString = mapType[1] }
505    let mapTemplete = mapValueTemplete.format(napiVn, mapTypeString, dest)
506    mapTemplete = mapTemplete.replaceAll("[replace_lt]", lt)
507    mapTemplete = mapTemplete.replaceAll("[replace_lt+1]", lt + 1)
508    if (mapTypeString == "std::string") {
509        mapTemplete = mapTemplete.replaceAll("[replace_swap]",
510            `pxt->SwapJs2CUtf8(pxt->GetMapElementName(%s, i%d), tt%d);
511        pxt->SwapJs2CUtf8(pxt->GetMapElementValue(%s, tt%d.c_str()), tt%d);\n`
512                .format(napiVn, lt, lt, napiVn, lt, lt + 1))
513    }
514    else if (mapTypeString.substring(0, 12) == "NUMBER_TYPE_") {
515        mapTemplete = mapTemplete.replaceAll("[replace_swap]",
516            `pxt->SwapJs2CUtf8(pxt->GetMapElementName(%s, i%d), tt%d);
517        NUMBER_JS_2_C(pxt->GetMapElementValue(%s, tt%d.c_str()), %s, tt%d);\n`
518                .format(napiVn, lt, lt, napiVn, lt, mapTypeString, lt + 1))
519    }
520    else if (mapTypeString == "bool") {
521        mapTemplete = mapTemplete.replaceAll("[replace_swap]",
522            `pxt->SwapJs2CUtf8(pxt->GetMapElementName(%s, i%d), tt%d);
523        tt%d = pxt->SwapJs2CBool(pxt->GetMapElementValue(%s, tt%d.c_str()));\n`
524                .format(napiVn, lt, lt, lt + 1, napiVn, lt))
525    }
526    if (mapTypeString == "std::any") {
527        mapTemplete = mapTemplete.replaceAll("[replace_swap]",
528            `pxt->SwapJs2CUtf8(pxt->GetMapElementName(%s, i%d), tt%d);
529            if (i%d == 0) {
530                %s_type = pxt->GetAnyType(pxt->GetMapElementValue(%s, tt%d.c_str()));
531            }
532            pxt->SetAnyValue(%s_type, pxt->GetMapElementValue(%s, tt%d.c_str()), tt%d);\n`
533                .format(napiVn, lt, lt, lt, dest, napiVn, lt, dest, napiVn, lt, lt + 1))
534    }
535    else if (InterfaceList.getValue(mapTypeString)) {
536        mapTemplete = mapInterface(mapTypeString, mapTemplete, napiVn, lt)
537    }
538    return mapTemplete
539}
540
541let mapMapTemplete = `\
542uint32_t len[replace_lt] = pxt->GetMapLength(%s);
543for (uint32_t i[replace_lt] = 0; i[replace_lt] < len[replace_lt]; i[replace_lt]++) {
544    std::string tt[replace_lt];
545    std::map<std::string, %s> tt[replace_lt+1];
546    [replace_swap]
547    %s.insert(std::make_pair(tt[replace_lt], tt[replace_lt+1]));
548}`
549
550function mapMapString(mapTemplete, napiVn, lt) {
551    return mapTemplete.replaceAll("[replace_swap]",
552    `pxt->SwapJs2CUtf8(pxt->GetMapElementName(%s, i%d), tt%d);
553    uint32_t len%d = pxt->GetMapLength(pxt->GetMapElementValue(%s, tt%d.c_str()));
554    for (uint32_t i%d = 0; i%d < len%d; i%d++) {
555        std::string tt%d;
556        std::string tt%d;
557        pxt->SwapJs2CUtf8(pxt->GetMapElementName(pxt->GetMapElementValue(%s,
558            tt%d.c_str()), i%d), tt%d);
559        pxt->SwapJs2CUtf8(pxt->GetMapElementValue(pxt->GetMapElementValue(%s,
560            tt%d.c_str()), tt%d.c_str()), tt%d);
561        tt%d.insert(std::make_pair(tt%d, tt%d));
562    }`.format(napiVn, lt, lt, lt + 1, napiVn, lt, lt + 1, lt + 1, lt + 1, lt + 1,
563        lt + 2, lt + 3, napiVn, lt, lt + 1, lt + 2, napiVn, lt, lt + 2, lt + 3, lt + 1, lt + 2, lt + 3))
564}
565
566function mapMapBoolean(mapTemplete, napiVn, lt) {
567    return mapTemplete.replaceAll("[replace_swap]",
568    `pxt->SwapJs2CUtf8(pxt->GetMapElementName(%s, i%d), tt%d);
569    uint32_t len%d = pxt->GetMapLength(pxt->GetMapElementValue(%s, tt%d.c_str()));
570    for (uint32_t i%d = 0; i%d < len%d; i%d++) {
571        std::string tt%d;
572        bool tt%d;
573        pxt->SwapJs2CUtf8(pxt->GetMapElementName(pxt->GetMapElementValue(%s,
574            tt%d.c_str()), i%d), tt%d);
575        tt%d = pxt->%s(pxt->GetMapElementValue(pxt->GetMapElementValue(%s,
576            tt%d.c_str()), tt%d.c_str()));
577        tt%d.insert(std::make_pair(tt%d, tt%d));
578    }\n`.format(napiVn, lt, lt, lt + 1, napiVn, lt, lt + 1, lt + 1, lt + 1, lt + 1,
579        lt + 2, lt + 3, napiVn, lt, lt + 1, lt + 2, lt + 3, "SwapJs2CBool"
580        ,napiVn, lt, lt + 2, lt + 1, lt + 2, lt + 3))
581}
582
583function mapMapNumber(mapTemplete, napiVn, lt, mapTypeString) {
584    return mapTemplete.replaceAll("[replace_swap]",
585    `pxt->SwapJs2CUtf8(pxt->GetMapElementName(%s, i%d), tt%d);
586    uint32_t len%d = pxt->GetMapLength(pxt->GetMapElementValue(%s, tt%d.c_str()));
587    for (uint32_t i%d = 0; i%d < len%d; i%d++) {
588        std::string tt%d;
589        %s tt%d;
590        pxt->SwapJs2CUtf8(pxt->GetMapElementName(pxt->GetMapElementValue(%s,
591            tt%d.c_str()), i%d), tt%d);
592        NUMBER_JS_2_C(pxt->GetMapElementValue(pxt->GetMapElementValue(%s,
593            tt%d.c_str()), tt%d.c_str()), %s, tt%d);
594        tt%d.insert(std::make_pair(tt%d, tt%d));
595    }`.format(napiVn, lt, lt, lt + 1, napiVn, lt, lt + 1, lt + 1, lt + 1, lt + 1,
596        lt + 2, mapTypeString, lt + 3, napiVn, lt, lt + 1, lt + 2, napiVn, lt, lt + 2,
597        mapTypeString, lt + 3, lt + 1, lt + 2, lt + 3))
598}
599
600function mapMap(mapType, napiVn, dest, lt) {
601    let mapTypeString
602    if (mapType[2] == "string") { mapTypeString = "std::string" }
603    else if (mapType[2].substring(0, 12) == "NUMBER_TYPE_") { mapTypeString = mapType[2] }
604    else if (mapType[2] == "boolean") { mapTypeString = "bool" }
605    let mapTemplete = mapMapTemplete.format(napiVn, mapTypeString, dest)
606    mapTemplete = mapTemplete.replaceAll("[replace_lt]", lt)
607    mapTemplete = mapTemplete.replaceAll("[replace_lt+1]", lt + 1)
608    if (mapType[2] == "string") {
609        mapTemplete = mapMapString (mapTemplete, napiVn, lt)
610    }
611    else if (mapType[2] == "boolean") {
612        mapTemplete = mapMapBoolean (mapTemplete, napiVn, lt)
613    }
614    else if (mapType[2].substring(0, 12) == "NUMBER_TYPE_") {
615        mapTemplete = mapMapNumber (mapTemplete, napiVn, lt, mapTypeString)
616    }
617    return mapTemplete
618}
619
620let mapArrayTemplete = `\
621uint32_t len[replace_lt] = pxt->GetMapLength(%s);
622for (uint32_t i[replace_lt] = 0; i[replace_lt] < len[replace_lt]; i[replace_lt]++) {
623    std::string tt[replace_lt];
624    std::vector<%s> tt[replace_lt+1];
625    [replace_swap]
626    %s.insert(std::make_pair(tt[replace_lt], tt[replace_lt+1]));
627}`
628
629function mapArray(mapType, napiVn, dest, lt) {
630    let mapTypeString
631    if (mapType[3] == "string") { mapTypeString = "std::string" }
632    else if (mapType[3].substring(0, 12) == "NUMBER_TYPE_") { mapTypeString = mapType[3] }
633    else if (mapType[3] == "boolean") { mapTypeString = "bool" }
634    let mapTemplete = mapArrayTemplete.format(napiVn, mapTypeString, dest)
635    mapTemplete = mapTemplete.replaceAll("[replace_lt]", lt)
636    mapTemplete = mapTemplete.replaceAll("[replace_lt+1]", lt + 1)
637    if (mapType[3] == "string") {
638        mapTemplete = mapTemplete.replaceAll("[replace_swap]",
639            `pxt->SwapJs2CUtf8(pxt->GetMapElementName(%s, i%s), tt%d);
640            uint32_t len%s = pxt->GetArrayLength(pxt->GetMapElementValue(%s, tt%d.c_str()));
641            for (uint32_t i%d = 0; i%d < len%d; i%d++) {
642                std::string tt%d;
643                pxt->SwapJs2CUtf8(pxt->GetArrayElement(pxt->GetMapElementValue(%s,
644                    tt%d.c_str()), i%d), tt%d);
645                tt%d.push_back(tt%d);
646            }`.format(napiVn, lt, lt, lt + 1, napiVn, lt, lt + 1, lt + 1, lt + 1,
647                lt + 1, lt + 2, napiVn, lt, lt + 1, lt + 2, lt + 1, lt + 2))
648    }
649    else if (mapType[3] == "boolean") {
650        mapTemplete = mapTemplete.replaceAll("[replace_swap]",
651            `pxt->SwapJs2CUtf8(pxt->GetMapElementName(%s, i%s), tt%d);
652            uint32_t len%s = pxt->GetArrayLength(pxt->GetMapElementValue(%s, tt%d.c_str()));
653            for (uint32_t i%d = 0; i%d < len%d; i%d++) {
654                bool tt%d;
655                tt%d = pxt->SwapJs2CBool(pxt->GetArrayElement(pxt->GetMapElementValue(%s,
656                    tt%d.c_str()), i%d));
657                tt%d.push_back(tt%d);
658            }`.format(napiVn, lt, lt, lt + 1, napiVn, lt, lt + 1, lt + 1, lt + 1,
659                lt + 1, lt + 2, lt + 2, napiVn, lt, lt, lt + 1, lt + 2))
660    }
661    else if (mapType[3].substring(0, 12) == "NUMBER_TYPE_") {
662        mapTemplete = mapTemplete.replaceAll("[replace_swap]",
663            `pxt->SwapJs2CUtf8(pxt->GetMapElementName(%s, i%s), tt%d);
664            uint32_t len%s = pxt->GetArrayLength(pxt->GetMapElementValue(%s, tt%d.c_str()));
665            for (uint32_t i%d = 0; i%d < len%d; i%d++) {
666                %s tt%d;
667                NUMBER_JS_2_C(pxt->GetArrayElement(pxt->GetMapElementValue(%s,
668                    tt%d.c_str()), i%d), %s, tt%d);
669                tt%d.push_back(tt%d);
670            }`.format(napiVn, lt, lt, lt + 1, napiVn, lt, lt + 1, lt + 1, lt + 1,
671                lt + 1, mapTypeString, lt + 2, napiVn, lt, lt + 1, mapTypeString, lt + 2, lt + 1, lt + 2))
672    }
673    return mapTemplete
674}
675
676function paramGenerateCallBack(data, funcValue, param, p) {
677    let type = funcValue.type
678    let arrayType = re.match("(Async)*Callback<(Array<([a-zA-Z_0-9]+)>)>", type)
679    let regType
680    if (arrayType) {
681        regType = re.getReg(type, arrayType.regs[2])
682    }
683
684    let arrayType2 = re.match("(Async)*Callback<(([a-zA-Z_0-9]+)\\[\\])>", type)
685    if (arrayType2) {
686        regType = re.getReg(type, arrayType2.regs[2])
687    }
688
689    let tt = re.match("(Async)*Callback<([a-zA-Z_0-9]+)>", type)
690    if (tt) {
691        regType = re.getReg(type, tt.regs[2])
692    }
693    if (isEnum(regType, data)) {
694        let index = enumIndex(regType, data)
695        if (data.enum[index].body.enumValueType == EnumValueType.ENUM_VALUE_TYPE_NUMBER) {
696            regType = "NUMBER_TYPE_" + NumberIncrease.getAndIncrease()
697        } else if (data.enum[index].body.enumValueType == EnumValueType.ENUM_VALUE_TYPE_STRING) {
698            regType = "string"
699        } else {
700            NapiLog.logError(`paramGenerate is not support`);
701            return
702        }
703    }
704    param.callback = {
705        type: regType,
706        offset: p,
707        optional: funcValue.optional,
708        isAsync: type.indexOf("AsyncCallback") >= 0
709    }
710}
711
712function isArrayType(type) {
713    if (type.substring(type.length - 2) == "[]" || type.substring(0, 6) == "Array<") {
714        return true;
715    }
716    return false;
717}
718
719function getValueCheckout(funcValue, param, inParamName, p, cType) {
720    let valueCheckout = jsToC(inParamName, "pxt->GetArgv(%d)".format(getConstNum(p)), funcValue.type) + "\n    "
721    if (funcValue.optional) {
722        valueCheckout = "if (pxt->GetArgc() > %d) {\n        vio->in%d = new %s;\n        "
723            .format(getConstNum(p), p, cType) + valueCheckout + "}\n    "
724        param.optionalParamDestory += "C_DELETE(vio->in%d);\n    ".format(p)
725    }
726    return valueCheckout;
727}
728
729function paramGenerateUnion(type, param, p, name) {
730    param.valueIn += `\n    std::any in%d;
731        std::string in%d_type;`.format(p, p)
732    param.valueCheckout += jsToC("vio->in" + p, "pxt->GetArgv(%d)".format(getConstNum(p)), type)
733    param.valueFill += "%svio->in%d".format(param.valueFill.length > 0 ? ", " : "", p)
734    param.valueDefine += "%sstd::any &%s".format(param.valueDefine.length > 0 ? ", " : "", name)
735}
736
737function paramGenerateCommon(p, cType, funcValue, param, modifiers, inParamName) {
738    param.valueIn += funcValue.optional ? "\n    %s* in%d = nullptr;".format(cType, p)
739                                            : "\n    %s in%d;".format(cType, p)
740    if (TypeList.getValue(cType)) {
741      let realType = TypeList.getValue(cType)
742      if (realType.indexOf('|') > 0) {
743        param.valueIn += `\n    std::string in%d_type;`.format(p, p)
744      }
745    }
746    param.valueCheckout += getValueCheckout(funcValue, param, inParamName, p, cType)
747    param.valueFill += "%svio->in%d".format(param.valueFill.length > 0 ? ", " : "", p)
748    param.valueDefine += "%s%s%s %s".format(
749        param.valueDefine.length > 0 ? ", " : "", cType, modifiers, funcValue.name)
750}
751
752let objectTemplete = `\
753    uint32_t len[replace_lt] = pxt->GetMapLength(%s);
754    for (uint32_t i[replace_lt] = 0; i[replace_lt] < len[replace_lt]; i[replace_lt]++) {
755        std::string tt[replace_lt];
756        std::any tt[replace_lt+1];
757        pxt->SwapJs2CUtf8(pxt->GetMapElementName(%s, i[replace_lt]), tt[replace_lt]);
758        napi_value valueObj = pxt->GetMapElementValue(%s, tt[replace_lt].c_str());
759        std::string valueObjType = pxt->GetAnyType(valueObj);
760        [replace_swap]
761        %s.insert(std::make_pair(tt[replace_lt], tt[replace_lt+1]));
762    }\n`
763
764// To avoid function that exceed 50 lines
765let objectTempleteArrnum = `\
766            uint32_t len[replace_lt+1] = pxt->GetArrayLength(valueObj);
767            std::vector<NUMBER_TYPE_%d> arr;
768            for(uint32_t i[replace_lt+1] = 0; i[replace_lt+1] < len[replace_lt+1]; i[replace_lt+1]++) {
769                napi_value arr_value_result;
770                NUMBER_TYPE_%d tt[replace_lt+2];
771                napi_get_element(env, valueObj, i[replace_lt+1], &arr_value_result);
772                NUMBER_JS_2_C(arr_value_result, NUMBER_TYPE_%d, tt[replace_lt+2]);
773                arr.push_back(tt[replace_lt+2]);
774            }
775            tt[replace_lt+1] = arr;
776`
777
778let objectTempleteMap = `\
779            napi_value obj_name_value;
780            napi_value obj_name_result;
781            napi_valuetype obj_name_type;
782            napi_get_property_names (env, valueObj, &obj_name_value);
783            uint32_t ret;
784            napi_get_array_length(env, obj_name_value, &ret);
785            std::vector<std::any> anyValue;
786            for(uint32_t i[replace_lt+1] = 0; i[replace_lt+1] < ret; i[replace_lt+1]++) {
787                napi_get_element (env, obj_name_value, i[replace_lt+1], &obj_name_result);
788                napi_typeof(env, obj_name_result, &obj_name_type);
789                if (obj_name_type == napi_string) {
790                    napi_value obj_value;
791                    napi_valuetype obj_value_type;
792                    std::string obj_name_string;
793                    pxt->SwapJs2CUtf8(obj_name_result, obj_name_string);
794                    napi_get_named_property (env, valueObj, obj_name_string.c_str(), &obj_value);
795                    napi_typeof(env, obj_value, &obj_value_type);
796                    std::map<std::string, std::any> anyValueMap;
797                    if (obj_value_type == napi_string) {
798                        std::string tt[replace_lt+2];
799                        pxt->SwapJs2CUtf8(obj_value, tt[replace_lt+2]);
800                        anyValueMap.insert(std::make_pair(obj_name_string, tt[replace_lt+2]));
801                        anyValue.push_back(anyValueMap);
802                    } else if (obj_value_type == napi_number) {
803                        NUMBER_TYPE_%d tt[replace_lt+2];
804                        NUMBER_JS_2_C(obj_value, NUMBER_TYPE_%d, tt[replace_lt+2] );
805                        anyValueMap.insert(std::make_pair(obj_name_string, tt[replace_lt+2]));
806                        anyValue.push_back(anyValueMap);
807                    } else if (obj_value_type == napi_boolean) {
808                        bool tt[replace_lt+2];
809                        tt[replace_lt+2] = pxt->SwapJs2CBool(obj_value);
810                        anyValueMap.insert(std::make_pair(obj_name_string, tt[replace_lt+2]));
811                        anyValue.push_back(anyValueMap);
812                    }
813                }
814            }
815            tt[replace_lt+1] = anyValue;
816`
817
818function objectTempleteFunc(dest, napiVn) {
819    let lt = LenIncrease.getAndIncrease()
820    let objTemplete = objectTemplete.format(napiVn, napiVn, napiVn, dest)
821
822    objTemplete = objTemplete.replaceAll("[replace_swap]",
823        `if (valueObjType == "string") {
824            std::string tt[replace_lt+2];
825            pxt->SwapJs2CUtf8(valueObj, tt[replace_lt+2]);
826            tt[replace_lt+1] = tt[replace_lt+2];
827        } else if (valueObjType == "boolean") {
828            bool tt[replace_lt+2];
829            tt[replace_lt+2] = pxt->SwapJs2CBool(valueObj);
830            tt[replace_lt+1] = tt[replace_lt+2];
831        } else if (valueObjType == "number") {
832            NUMBER_JS_2_C(valueObj, NUMBER_TYPE_%d, tt[replace_lt+1]);
833        } else if (valueObjType == "arr_string") {
834            uint32_t len[replace_lt+1] = pxt->GetArrayLength(valueObj);
835            std::vector<std::string> arr;
836            for(uint32_t i[replace_lt+1] = 0; i[replace_lt+1] < len[replace_lt+1]; i[replace_lt+1]++) {
837                napi_value arr_value_result;
838                napi_get_element(env, valueObj, i[replace_lt+1], &arr_value_result);
839                std::string tt[replace_lt+2];
840                pxt->SwapJs2CUtf8(arr_value_result, tt[replace_lt+2]);
841                arr.push_back(tt[replace_lt+2]);
842            }
843            tt[replace_lt+1] = arr;
844        } else if (valueObjType == "arr_boolean") {
845            uint32_t len[replace_lt+1] = pxt->GetArrayLength(valueObj);
846            std::vector<bool> arr;
847            for(uint32_t i[replace_lt+1] = 0; i[replace_lt+1] < len[replace_lt+1]; i[replace_lt+1]++) {
848                napi_value arr_value_result;
849                napi_get_element(env, valueObj, i[replace_lt+1], &arr_value_result);
850                bool tt[replace_lt+2];
851                tt[replace_lt+2] = pxt->SwapJs2CBool(arr_value_result);
852                arr.push_back(tt[replace_lt+2]);
853            }
854            tt[replace_lt+1] = arr;
855        } else if (valueObjType == "arr_number") {
856            [replace_objectTemplete_arrnum]
857        } else if (valueObjType == "map_string" || valueObjType == "map_number" || valueObjType == "map_boolean") {
858            [replace_objectTemplete_map]
859        }
860        `).format(lt)
861    objTemplete = objTemplete.replaceAll("[replace_objectTemplete_arrnum]", objectTempleteArrnum.format(lt, lt, lt))
862    objTemplete = objTemplete.replaceAll("[replace_objectTemplete_map]", objectTempleteMap.format(lt, lt))
863    objTemplete = objTemplete.replaceAll("[replace_lt]", lt)
864    objTemplete = objTemplete.replaceAll("[replace_lt+1]", lt + 1)
865    objTemplete = objTemplete.replaceAll("[replace_lt+2]", lt + 2)
866    return objTemplete
867}
868
869function paramGenerateObject(p, funcValue, param) {
870    let type = funcValue.type
871    let name = funcValue.name
872    let inParamName = funcValue.optional ? "(*vio->in" + p + ")" : "vio->in" + p
873    let modifiers = funcValue.optional ? "* " : "&"
874
875        let arrayType = "std::map<std::string, std::any>"
876        param.valueIn += funcValue.optional ? "\n    %s* in%d = nullptr;".format(arrayType, p)
877                                            : "\n    %s in%d;".format(arrayType, p)
878
879        let arrValueCheckout = jsToC(inParamName, "pxt->GetArgv(%d)".format(getConstNum(p)), type)
880        param.valueCheckout += arrValueCheckout
881        param.valueFill += "%svio->in%d".format(param.valueFill.length > 0 ? ", " : "", p)
882        param.valueDefine += "%s%s %s%s".format(param.valueDefine.length > 0 ? ", "
883            : "", arrayType, modifiers, name)
884}
885
886// 函数的参数处理
887function paramGenerate(p, funcValue, param, data) {
888    let type = funcValue.type
889    let name = funcValue.name
890    let inParamName = funcValue.optional ? "(*vio->in" + p + ")" : "vio->in" + p
891    let modifiers = funcValue.optional ? "*" : "&"
892    if (type.indexOf("|") >= 0) {
893        return paramGenerateUnion(type, param, p, name)
894    }
895    else if (type == "string") {
896        paramGenerateCommon(p, "std::string", funcValue, param, modifiers, inParamName)
897    }
898    else if (type.substring(0, 12) == "NUMBER_TYPE_" && type.indexOf("[]") < 0) {
899        paramGenerateCommon(p, funcValue.type, funcValue, param, modifiers, inParamName)
900    }
901    else if (InterfaceList.getValue(type)) {
902        paramGenerateCommon(p, funcValue.type, funcValue, param, modifiers, inParamName)
903    }
904    else if (TypeList.getValue(type)) {
905        paramGenerateCommon(p, funcValue.type, funcValue, param, modifiers, inParamName)
906    }
907    else if (type.substring(0, 9) == "Callback<" || type.substring(0, 14) == "AsyncCallback<") {
908        paramGenerateCallBack(data, funcValue, param, p)
909    }
910    else if (type == "boolean") {
911        paramGenerateCommon(p, "bool", funcValue, param, modifiers, inParamName)
912    }
913    else if (isEnum(type, data)) {
914        paramGenerateEnum(data, funcValue, param, p)
915    }
916    else if (type.substring(0, 4) == "Map<" || type.substring(0, 6) == "{[key:") {
917        paramGenerateMap(funcValue, param, p)
918    } else if (isArrayType(type)) {
919        paramGenerateArray(p, funcValue, param);
920    } else if (type == "any") {
921        paramGenerateAny(p, name, type, param);
922    }  else if (type == "object" || type == "Object") {
923        paramGenerateObject(p, funcValue, param);
924    } else {
925        NapiLog.logError(
926            "The current version does not support generating parameter [%s] with type [%s]".format(name, type));
927    }
928}
929
930// on/off 接口的参数处理
931function eventParamGenerate(p, funcValue, param, data) {
932    let name = funcValue.name;
933    let type = funcValue.type;
934    let regName = re.match("([a-zA-Z_0-9]+)", type)
935    if (type.substring(0, 9) == "Callback<" || type.substring(0, 14) == "AsyncCallback<") {
936        // callback参数处理
937        paramGenerateCallBack(data, funcValue, param, p)
938    } else if (regName) {
939        // event type参数处理
940        param.eventName = re.getReg(type, regName.regs[1])
941        param.valueDefine += "%sstd::string &%s".format(param.valueDefine.length > 0 ? ", " : "", name)
942    } else {
943        NapiLog.logError("function eventParamGenerate:The current version do not support to this param to generate :"
944        , name, "type :", type);
945    }
946}
947
948module.exports = {
949    jsToC,
950    jsToCEnum,
951    arrTemplete,
952    paramGenerate,
953    paramGenerateArray,
954    paramGenerateMap,
955    mapTempleteFunc,
956    eventParamGenerate
957}