18c339a94Sopenharmony_ci/* 28c339a94Sopenharmony_ci* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. 38c339a94Sopenharmony_ci* Licensed under the Apache License, Version 2.0 (the "License"); 48c339a94Sopenharmony_ci* you may not use this file except in compliance with the License. 58c339a94Sopenharmony_ci* You may obtain a copy of the License at 68c339a94Sopenharmony_ci* 78c339a94Sopenharmony_ci* http://www.apache.org/licenses/LICENSE-2.0 88c339a94Sopenharmony_ci* 98c339a94Sopenharmony_ci* Unless required by applicable law or agreed to in writing, software 108c339a94Sopenharmony_ci* distributed under the License is distributed on an "AS IS" BASIS, 118c339a94Sopenharmony_ci* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128c339a94Sopenharmony_ci* See the License for the specific language governing permissions and 138c339a94Sopenharmony_ci* limitations under the License. 148c339a94Sopenharmony_ci*/ 158c339a94Sopenharmony_ciconst re = require('../tools/re'); 168c339a94Sopenharmony_ciconst { FuncType, NumberIncrease, isEnum, EnumValueType, enumIndex, isType, typeIndex, isOnObjCallback, 178c339a94Sopenharmony_ci getOnObjCallbackType, getLogErrInfo } = require('../tools/common'); 188c339a94Sopenharmony_ciconst { analyzeParams } = require('./params'); 198c339a94Sopenharmony_ciconst { analyzeReturn } = require('./return'); 208c339a94Sopenharmony_ciconst { NapiLog } = require('../tools/NapiLog'); 218c339a94Sopenharmony_ciconst { randomInt } = require('crypto'); 228c339a94Sopenharmony_ciconst { print } = require('../tools/tool'); 238c339a94Sopenharmony_ci 248c339a94Sopenharmony_cifunction analyzeSubInterface(data) { 258c339a94Sopenharmony_ci let body = re.replaceAll(data, '\n', '').split(';'); // # replace(' ', ''). 268c339a94Sopenharmony_ci let result = { 278c339a94Sopenharmony_ci value: [], 288c339a94Sopenharmony_ci function: [], 298c339a94Sopenharmony_ci parentNameList: [], 308c339a94Sopenharmony_ci childList: [], 318c339a94Sopenharmony_ci parentList: [], 328c339a94Sopenharmony_ci }; 338c339a94Sopenharmony_ci for (let i in body) { 348c339a94Sopenharmony_ci let t = body[i]; 358c339a94Sopenharmony_ci while (t.length > 0 && t[0] === ' ') { 368c339a94Sopenharmony_ci t = t.substring(1, t.length); 378c339a94Sopenharmony_ci } 388c339a94Sopenharmony_ci while (t.length > 0 && t[-1] === ' ') { 398c339a94Sopenharmony_ci t = t.substring(0, t.length - 1); 408c339a94Sopenharmony_ci } 418c339a94Sopenharmony_ci if (t === '') { 428c339a94Sopenharmony_ci break; 438c339a94Sopenharmony_ci } 448c339a94Sopenharmony_ci let tt = re.match(' *([a-zA-Z0-9_]+) *: *([a-zA-Z_0-9<>,:{}[\\] ]+)', t); 458c339a94Sopenharmony_ci if (tt) { // 变量 468c339a94Sopenharmony_ci analyzeSubInterfaceVariable(t, tt, result); 478c339a94Sopenharmony_ci } 488c339a94Sopenharmony_ci } 498c339a94Sopenharmony_ci return result; 508c339a94Sopenharmony_ci} 518c339a94Sopenharmony_ci 528c339a94Sopenharmony_cifunction analyzeSubInterfaceVariable(t, tt, result) { 538c339a94Sopenharmony_ci let valueName = re.getReg(t, tt.regs[1]); 548c339a94Sopenharmony_ci let valueType = re.getReg(t, tt.regs[2]); 558c339a94Sopenharmony_ci let index = valueType.indexOf('number'); 568c339a94Sopenharmony_ci while (index !== -1) { 578c339a94Sopenharmony_ci valueType = valueType.replace('number', 'NUMBER_TYPE_' + NumberIncrease.getAndIncrease()); 588c339a94Sopenharmony_ci index = valueType.indexOf('number'); 598c339a94Sopenharmony_ci } 608c339a94Sopenharmony_ci result.value.push({ 618c339a94Sopenharmony_ci name: valueName, 628c339a94Sopenharmony_ci type: valueType, 638c339a94Sopenharmony_ci }); 648c339a94Sopenharmony_ci} 658c339a94Sopenharmony_ci 668c339a94Sopenharmony_cifunction getFuncParaType(v, interfaceName, data, results) { 678c339a94Sopenharmony_ci let arrayType = re.match('(Async)*Callback<(Array<([a-zA-Z_0-9]+)>)>', v.type); 688c339a94Sopenharmony_ci let parameter = v.type; 698c339a94Sopenharmony_ci if (arrayType) { 708c339a94Sopenharmony_ci parameter = re.getReg(v.type, arrayType.regs[2]); 718c339a94Sopenharmony_ci } 728c339a94Sopenharmony_ci if (isEnum(parameter, data)) { 738c339a94Sopenharmony_ci let index = enumIndex(parameter, data); 748c339a94Sopenharmony_ci if (data.enum[index].body.enumValueType === EnumValueType.ENUM_VALUE_TYPE_NUMBER) { 758c339a94Sopenharmony_ci v.type = v.type.replace(parameter, 'NUMBER_TYPE_' + NumberIncrease.getAndIncrease()); 768c339a94Sopenharmony_ci } else if (data.enum[index].body.enumValueType === EnumValueType.ENUM_VALUE_TYPE_STRING) { 778c339a94Sopenharmony_ci v.type = v.type.replace(parameter, 'string'); 788c339a94Sopenharmony_ci } else { 798c339a94Sopenharmony_ci NapiLog.logError('analyzeFunction getFuncParaType is not support this type %s.' 808c339a94Sopenharmony_ci .format(data.enum[index].body.enumValueType), getLogErrInfo); 818c339a94Sopenharmony_ci return null; 828c339a94Sopenharmony_ci } 838c339a94Sopenharmony_ci } 848c339a94Sopenharmony_ci // interface & class中的方法参数类型是enum的情况 858c339a94Sopenharmony_ci else if (isEnum(parameter, results)) { 868c339a94Sopenharmony_ci let index = enumIndex(parameter, results); 878c339a94Sopenharmony_ci if (results.enum[index].body.enumValueType === EnumValueType.ENUM_VALUE_TYPE_NUMBER) { 888c339a94Sopenharmony_ci v.type = v.type.replace(parameter, 'NUMBER_TYPE_' + NumberIncrease.getAndIncrease()); 898c339a94Sopenharmony_ci } else if (results.enum[index].body.enumValueType === EnumValueType.ENUM_VALUE_TYPE_STRING) { 908c339a94Sopenharmony_ci v.type = v.type.replace(parameter, 'string'); 918c339a94Sopenharmony_ci } else { 928c339a94Sopenharmony_ci NapiLog.logError('analyzeFunction getFuncParaType is not support this type %s.' 938c339a94Sopenharmony_ci .format(results.enum[index].body.enumValueType), getLogErrInfo()); 948c339a94Sopenharmony_ci return null; 958c339a94Sopenharmony_ci } 968c339a94Sopenharmony_ci } 978c339a94Sopenharmony_ci 988c339a94Sopenharmony_ci let interfaceType = re.match('{([A-Za-z0-9_]+:[A-Za-z0-9_,]+)([A-Za-z0-9_]+:[A-Za-z0-9_]+)}$', v.type); 998c339a94Sopenharmony_ci if (interfaceType) { 1008c339a94Sopenharmony_ci v.type = interfaceName; 1018c339a94Sopenharmony_ci } 1028c339a94Sopenharmony_ci 1038c339a94Sopenharmony_ci if (parameter.indexOf('number') >= 0) { 1048c339a94Sopenharmony_ci v.type = v.type.replace('number', 'NUMBER_TYPE_' + NumberIncrease.getAndIncrease()); 1058c339a94Sopenharmony_ci } 1068c339a94Sopenharmony_ci 1078c339a94Sopenharmony_ci // type的处理 1088c339a94Sopenharmony_ci if (isType(parameter, data)) { 1098c339a94Sopenharmony_ci let index = typeIndex(parameter, data); 1108c339a94Sopenharmony_ci if (data.type[index].isEnum) { 1118c339a94Sopenharmony_ci v.type = v.type.replace(parameter, 'string'); 1128c339a94Sopenharmony_ci } 1138c339a94Sopenharmony_ci } 1148c339a94Sopenharmony_ci return v; 1158c339a94Sopenharmony_ci} 1168c339a94Sopenharmony_ci 1178c339a94Sopenharmony_cifunction analyzeFuncNoNameInterface(data, values, results) { 1188c339a94Sopenharmony_ci values = re.replaceAll(re.replaceAll(values, ' ', ''), '\n', ''); 1198c339a94Sopenharmony_ci let interfaceName = ''; 1208c339a94Sopenharmony_ci let matchNoName = '([:{<}>,;a-zA-Z_0-9]*)\\?*(:[A-Za-z0-9_,;]*)?:((Async)*Callback<)?{(([A-Za-z0-9_]+:' + 1218c339a94Sopenharmony_ci '[A-Za-z0-9_,;]+)*)([A-Za-z0-9_]+:[A-Za-z0-9_]+)}(}|,|;|>)?$'; 1228c339a94Sopenharmony_ci let matchs = re.match(matchNoName, values); 1238c339a94Sopenharmony_ci if (matchs) { 1248c339a94Sopenharmony_ci let st = values.lastIndexOf('{'); 1258c339a94Sopenharmony_ci let end = values.indexOf('}'); 1268c339a94Sopenharmony_ci let number = NumberIncrease.getAndIncrease(); 1278c339a94Sopenharmony_ci interfaceName = 'AUTO_INTERFACE_%s'.format(number); 1288c339a94Sopenharmony_ci let interfaceBody = values.substring(st + 1, end); 1298c339a94Sopenharmony_ci let typeInterface = '{%s}'.format(interfaceBody); 1308c339a94Sopenharmony_ci values = re.replaceAll(values, typeInterface, interfaceName); 1318c339a94Sopenharmony_ci interfaceBody = re.replaceAll(interfaceBody, ',', ';'); 1328c339a94Sopenharmony_ci if (Object.prototype.hasOwnProperty.call(data, 'interface')) { 1338c339a94Sopenharmony_ci data.interface.push({ 1348c339a94Sopenharmony_ci name: interfaceName, 1358c339a94Sopenharmony_ci body: analyzeSubInterface(interfaceBody), 1368c339a94Sopenharmony_ci }); 1378c339a94Sopenharmony_ci } else if (Object.prototype.hasOwnProperty.call(results, 'interface')) { 1388c339a94Sopenharmony_ci results.interface.push({ 1398c339a94Sopenharmony_ci name: interfaceName, 1408c339a94Sopenharmony_ci body: analyzeSubInterface(interfaceBody), 1418c339a94Sopenharmony_ci }); 1428c339a94Sopenharmony_ci } 1438c339a94Sopenharmony_ci } 1448c339a94Sopenharmony_ci 1458c339a94Sopenharmony_ci matchs = re.match(matchNoName, values); 1468c339a94Sopenharmony_ci if (matchs) { 1478c339a94Sopenharmony_ci let resNoNameInter = analyzeFuncNoNameInterface(data, values); 1488c339a94Sopenharmony_ci values = resNoNameInter.values; 1498c339a94Sopenharmony_ci } 1508c339a94Sopenharmony_ci 1518c339a94Sopenharmony_ci let result = { 1528c339a94Sopenharmony_ci interfaceName: interfaceName, 1538c339a94Sopenharmony_ci values: values, 1548c339a94Sopenharmony_ci }; 1558c339a94Sopenharmony_ci return result; 1568c339a94Sopenharmony_ci} 1578c339a94Sopenharmony_ci 1588c339a94Sopenharmony_cifunction analyseSubReturn(ret, data, results) { 1598c339a94Sopenharmony_ci // 匿名interface返回值 function fun4(input: string): { read: number; written: number }; 1608c339a94Sopenharmony_ci let tt = null; 1618c339a94Sopenharmony_ci if (ret.indexOf(':') > 0) { 1628c339a94Sopenharmony_ci ret = re.replaceAll(re.replaceAll(ret, ' ', ''), '\n', ''); 1638c339a94Sopenharmony_ci ret = re.replaceAll(ret, ',', ';'); 1648c339a94Sopenharmony_ci ret = ret.substring(1, ret.length - 1); 1658c339a94Sopenharmony_ci tt = ret.split(';'); 1668c339a94Sopenharmony_ci } 1678c339a94Sopenharmony_ci if (tt) { 1688c339a94Sopenharmony_ci let len = tt.length; 1698c339a94Sopenharmony_ci let res = ''; 1708c339a94Sopenharmony_ci let interfaceName = ''; 1718c339a94Sopenharmony_ci for (let i = 0; i < len; i++) { 1728c339a94Sopenharmony_ci let regs1 = tt[i] + ';'; 1738c339a94Sopenharmony_ci res += regs1; 1748c339a94Sopenharmony_ci } 1758c339a94Sopenharmony_ci 1768c339a94Sopenharmony_ci let number = NumberIncrease.getAndIncrease(); 1778c339a94Sopenharmony_ci interfaceName = 'AUTO_INTERFACE_%s'.format(number); 1788c339a94Sopenharmony_ci let interfaceBody = res; 1798c339a94Sopenharmony_ci ret = interfaceName; 1808c339a94Sopenharmony_ci 1818c339a94Sopenharmony_ci interfaceBody = re.replaceAll(interfaceBody, ',', ';'); 1828c339a94Sopenharmony_ci if (Object.prototype.hasOwnProperty.call(data, 'interface')) { 1838c339a94Sopenharmony_ci data.interface.push({ 1848c339a94Sopenharmony_ci name: interfaceName, 1858c339a94Sopenharmony_ci body: analyzeSubInterface(interfaceBody), 1868c339a94Sopenharmony_ci }); 1878c339a94Sopenharmony_ci } else if (Object.prototype.hasOwnProperty.call(results, 'interface')) { 1888c339a94Sopenharmony_ci results.interface.push({ 1898c339a94Sopenharmony_ci name: interfaceName, 1908c339a94Sopenharmony_ci body: analyzeSubInterface(interfaceBody), 1918c339a94Sopenharmony_ci }); 1928c339a94Sopenharmony_ci } 1938c339a94Sopenharmony_ci } 1948c339a94Sopenharmony_ci if (ret.indexOf('number') >= 0) { 1958c339a94Sopenharmony_ci ret = ret.replaceAll('number', 'NUMBER_TYPE_' + NumberIncrease.getAndIncrease()); 1968c339a94Sopenharmony_ci } 1978c339a94Sopenharmony_ci return ret; 1988c339a94Sopenharmony_ci} 1998c339a94Sopenharmony_ci 2008c339a94Sopenharmony_cifunction getObjCallFunc(results, onObjCbType, values, ret) { 2018c339a94Sopenharmony_ci if (results !== undefined) { 2028c339a94Sopenharmony_ci results.callFunction.push({ 2038c339a94Sopenharmony_ci 'name': onObjCbType, 2048c339a94Sopenharmony_ci 'body': values, 2058c339a94Sopenharmony_ci 'ret': ret, 2068c339a94Sopenharmony_ci }); 2078c339a94Sopenharmony_ci } 2088c339a94Sopenharmony_ci} 2098c339a94Sopenharmony_cifunction getFuncResult(name, funcType, values, ret, isStatic) { 2108c339a94Sopenharmony_ci let result = { 2118c339a94Sopenharmony_ci name: name, 2128c339a94Sopenharmony_ci type: funcType, 2138c339a94Sopenharmony_ci value: values, 2148c339a94Sopenharmony_ci ret: ret, 2158c339a94Sopenharmony_ci isStatic: isStatic, 2168c339a94Sopenharmony_ci }; 2178c339a94Sopenharmony_ci return result; 2188c339a94Sopenharmony_ci} 2198c339a94Sopenharmony_ci 2208c339a94Sopenharmony_cifunction getArrowCallFunc(tmp, results) { 2218c339a94Sopenharmony_ci let callbackFunc = null; 2228c339a94Sopenharmony_ci 2238c339a94Sopenharmony_ci if (tmp[2][0] !== undefined) { 2248c339a94Sopenharmony_ci callbackFunc = tmp[2][0]; // 当方法的参数是回调方法,并且回调方法写法为=>函数 2258c339a94Sopenharmony_ci } 2268c339a94Sopenharmony_ci if (results !== undefined && callbackFunc !== null) { 2278c339a94Sopenharmony_ci results.callFunction.push(callbackFunc); 2288c339a94Sopenharmony_ci } 2298c339a94Sopenharmony_ci} 2308c339a94Sopenharmony_ci 2318c339a94Sopenharmony_ci/**函数解析 */ 2328c339a94Sopenharmony_cifunction analyzeFunction(data, isStatic, name, values, ret, results, interfaceName = '') { 2338c339a94Sopenharmony_ci let res = analyzeFuncNoNameInterface(data, values, results); 2348c339a94Sopenharmony_ci let tmp; 2358c339a94Sopenharmony_ci let funcType; 2368c339a94Sopenharmony_ci 2378c339a94Sopenharmony_ci if (res) { 2388c339a94Sopenharmony_ci tmp = analyzeParams(name, res.values); 2398c339a94Sopenharmony_ci if (tmp !== null) { 2408c339a94Sopenharmony_ci values = tmp[0]; 2418c339a94Sopenharmony_ci funcType = tmp[1]; 2428c339a94Sopenharmony_ci getArrowCallFunc(tmp, results); 2438c339a94Sopenharmony_ci } 2448c339a94Sopenharmony_ci } 2458c339a94Sopenharmony_ci 2468c339a94Sopenharmony_ci tmp = analyzeReturn(ret); 2478c339a94Sopenharmony_ci ret = tmp[0]; 2488c339a94Sopenharmony_ci if (tmp[1]) { // 返回类型为 Promise, 解析成等价的AsyncCallback方法 2498c339a94Sopenharmony_ci funcType = FuncType.ASYNC; 2508c339a94Sopenharmony_ci // 返回值是Promise的匿名interface 2518c339a94Sopenharmony_ci let paramTypeVal = analyseSubReturn(ret.substring(8, ret.length - 1), data, results); 2528c339a94Sopenharmony_ci // 将返回值Promise<type>改为AsyncCallback<type>,作为方法的入参 2538c339a94Sopenharmony_ci let paramType = ret.replace('Promise', 'AsyncCallback'); 2548c339a94Sopenharmony_ci if (paramTypeVal) { 2558c339a94Sopenharmony_ci // 匿名interface处理 2568c339a94Sopenharmony_ci let paramAsync = paramType.substring(14, paramType.length - 1); 2578c339a94Sopenharmony_ci paramType = paramType.replace(paramAsync, paramTypeVal); 2588c339a94Sopenharmony_ci } 2598c339a94Sopenharmony_ci values.push({ name: 'promise', optional: false, type: paramType }); 2608c339a94Sopenharmony_ci ret = 'void'; // 返回值由Promise改为void,与AsyncCallback接口保持一致 2618c339a94Sopenharmony_ci } 2628c339a94Sopenharmony_ci for (let j in values) { 2638c339a94Sopenharmony_ci let v = values[j]; 2648c339a94Sopenharmony_ci v = getFuncParaType(v, res.interfaceName, data, results); 2658c339a94Sopenharmony_ci if (v === null) { 2668c339a94Sopenharmony_ci NapiLog.logError('analyzeFunction is not support this type %s.'.format(v), getLogErrInfo()); 2678c339a94Sopenharmony_ci } 2688c339a94Sopenharmony_ci } 2698c339a94Sopenharmony_ci ret = analyseSubReturn(ret, data, results); 2708c339a94Sopenharmony_ci let result = getFuncResult(name, funcType, values, ret, isStatic); 2718c339a94Sopenharmony_ci if (isOnObjCallback(name)) { 2728c339a94Sopenharmony_ci let onObjCbType = getOnObjCallbackType(name, interfaceName); 2738c339a94Sopenharmony_ci getObjCallFunc(results, onObjCbType, values, ret); 2748c339a94Sopenharmony_ci } 2758c339a94Sopenharmony_ci return result; 2768c339a94Sopenharmony_ci} 2778c339a94Sopenharmony_ci 2788c339a94Sopenharmony_cimodule.exports = { 2798c339a94Sopenharmony_ci analyzeFunction, 2808c339a94Sopenharmony_ci analyzeSubInterface, 2818c339a94Sopenharmony_ci getFuncParaType, 2828c339a94Sopenharmony_ci analyzeFuncNoNameInterface, 2838c339a94Sopenharmony_ci analyseSubReturn, 2848c339a94Sopenharmony_ci};