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 { checkOutBody, print } = require('../tools/tool'); 178c339a94Sopenharmony_ciconst { FuncType, NumberIncrease, isFuncType, isArrowFunc, isRegisterFunc } = require('../tools/common'); 188c339a94Sopenharmony_ciconst { NapiLog } = require('../tools/NapiLog'); 198c339a94Sopenharmony_ci 208c339a94Sopenharmony_cifunction isSyncFuncType(type, funcType) { 218c339a94Sopenharmony_ci let isSync = false; 228c339a94Sopenharmony_ci if (funcType === FuncType.DIRECT && type.indexOf('Callback') >= 0 && type.indexOf('AsyncCallback') < 0 || 238c339a94Sopenharmony_ci isFuncType(type) || isArrowFunc(type)) { 248c339a94Sopenharmony_ci isSync = true; 258c339a94Sopenharmony_ci } 268c339a94Sopenharmony_ci return isSync; 278c339a94Sopenharmony_ci} 288c339a94Sopenharmony_ci 298c339a94Sopenharmony_ci/** 308c339a94Sopenharmony_ci * on方法中回调方法的解析 318c339a94Sopenharmony_ci * @param {*} valueType 回调方法体 328c339a94Sopenharmony_ci * @param {*} valueName 参数名 338c339a94Sopenharmony_ci * @param {*} rsltCallFunction 解析结果 348c339a94Sopenharmony_ci */ 358c339a94Sopenharmony_cifunction analyzeCallbackFunction(valueType, valueName, rsltCallFunction) { 368c339a94Sopenharmony_ci 378c339a94Sopenharmony_ci if (valueType.indexOf('=>') > 0) { 388c339a94Sopenharmony_ci valueType = re.replaceAll(valueType, ' ', ''); 398c339a94Sopenharmony_ci } 408c339a94Sopenharmony_ci let matchs = re.match('\\(([a-zA-Z_0-9:,]+)*\\)=>([a-zA-Z_0-9]+)', valueType); 418c339a94Sopenharmony_ci 428c339a94Sopenharmony_ci if (matchs) { 438c339a94Sopenharmony_ci let number = NumberIncrease.getAndIncrease(); 448c339a94Sopenharmony_ci let functionTypeName = 'AUTO_CALLFUNCTION_%s_%s'.format(valueName, number); 458c339a94Sopenharmony_ci 468c339a94Sopenharmony_ci let functionRet = re.getReg(valueType, matchs.regs[2]); 478c339a94Sopenharmony_ci let functionBody = re.getReg(valueType, matchs.regs[1]); 488c339a94Sopenharmony_ci 498c339a94Sopenharmony_ci let tmp = analyzeParams(functionTypeName, functionBody); 508c339a94Sopenharmony_ci let bodyRes = tmp[0]; 518c339a94Sopenharmony_ci for (let i in bodyRes) { 528c339a94Sopenharmony_ci let hasProperty = Object.prototype.hasOwnProperty.call(bodyRes[i], 'type'); 538c339a94Sopenharmony_ci if (hasProperty && bodyRes[i].type === 'number') { 548c339a94Sopenharmony_ci bodyRes[i].type = 'NUMBER_TYPE_' + NumberIncrease.getAndIncrease(); 558c339a94Sopenharmony_ci } 568c339a94Sopenharmony_ci } 578c339a94Sopenharmony_ci 588c339a94Sopenharmony_ci rsltCallFunction.push({ 598c339a94Sopenharmony_ci 'name': functionTypeName, 608c339a94Sopenharmony_ci 'body': bodyRes, 618c339a94Sopenharmony_ci 'ret': functionRet, 628c339a94Sopenharmony_ci }); 638c339a94Sopenharmony_ci valueType = functionTypeName; 648c339a94Sopenharmony_ci } 658c339a94Sopenharmony_ci return valueType; 668c339a94Sopenharmony_ci} 678c339a94Sopenharmony_ci 688c339a94Sopenharmony_ci/**函数参数解析 */ 698c339a94Sopenharmony_cifunction analyzeParams(funcName, values) { 708c339a94Sopenharmony_ci let result = []; 718c339a94Sopenharmony_ci let rsltCallFunction = []; 728c339a94Sopenharmony_ci let funcType = FuncType.DIRECT; 738c339a94Sopenharmony_ci let optionalParamCount = 0; // 可选参数的个数 748c339a94Sopenharmony_ci while (values.length > 0) { 758c339a94Sopenharmony_ci let v = checkOutBody(values, 0, ['', ',']); 768c339a94Sopenharmony_ci if (v === null) { 778c339a94Sopenharmony_ci v = values; 788c339a94Sopenharmony_ci } 798c339a94Sopenharmony_ci 808c339a94Sopenharmony_ci values = values.substring(v.length, values.length); 818c339a94Sopenharmony_ci let matchs = re.match('([a-zA-Z_0-9\\.]+)(\\?*): *([a-zA-Z<,>|_0-9\\[\\]\\(\\):=\'{}]+)', v); 828c339a94Sopenharmony_ci if (matchs === null && (funcName === 'on' || funcName === 'off')) { 838c339a94Sopenharmony_ci // on和off的第一个参数的类型可以是一串字符 848c339a94Sopenharmony_ci matchs = re.match('([a-zA-Z_0-9\\.]+)(\\?*): *\"([a-zA-Z|_0-9\\[\\]\\(\\):=\'{}]+)\"', v); 858c339a94Sopenharmony_ci } 868c339a94Sopenharmony_ci if (matchs !== null) { 878c339a94Sopenharmony_ci let type = re.getReg(v, matchs.regs[3]); 888c339a94Sopenharmony_ci if (type.indexOf('Map') < 0 && !isArrowFunc(type)) { 898c339a94Sopenharmony_ci type = type.replace(/,/g, ''); 908c339a94Sopenharmony_ci } 918c339a94Sopenharmony_ci 928c339a94Sopenharmony_ci let valueName = re.getReg(v, matchs.regs[1]); 938c339a94Sopenharmony_ci type = analyzeCallbackFunction(type, valueName, rsltCallFunction); 948c339a94Sopenharmony_ci 958c339a94Sopenharmony_ci let optionalFlag = re.getReg(v, matchs.regs[2]) === '?' ? true : false; 968c339a94Sopenharmony_ci let checkParamOk = true; 978c339a94Sopenharmony_ci let retVal = analyzaParamsFunc(optionalFlag, optionalParamCount, v, funcName, checkParamOk, 988c339a94Sopenharmony_ci result, matchs, type, funcType); 998c339a94Sopenharmony_ci result = retVal[0]; 1008c339a94Sopenharmony_ci funcType = retVal[1]; 1018c339a94Sopenharmony_ci } 1028c339a94Sopenharmony_ci else { 1038c339a94Sopenharmony_ci NapiLog.logError('Failed to analyse parameter [%s] of function [%s].'.format(v, funcName)); 1048c339a94Sopenharmony_ci } 1058c339a94Sopenharmony_ci } 1068c339a94Sopenharmony_ci return [result, funcType, rsltCallFunction]; 1078c339a94Sopenharmony_ci} 1088c339a94Sopenharmony_ci 1098c339a94Sopenharmony_cifunction analyzaParamsFunc(optionalFlag, optionalParamCount, v, funcName, checkParamOk, 1108c339a94Sopenharmony_ci result, matchs, type, funcType) { 1118c339a94Sopenharmony_ci if (optionalFlag) { 1128c339a94Sopenharmony_ci optionalParamCount++; 1138c339a94Sopenharmony_ci } else if (optionalParamCount > 0) { 1148c339a94Sopenharmony_ci // 可选参数之后不能再有必选参数,须是可选参数。 1158c339a94Sopenharmony_ci NapiLog.logError('Invalid parameter [%s] of function [%s],'.format(v, funcName) + 1168c339a94Sopenharmony_ci ' the required parameter cannot follow an optional parameter.'); 1178c339a94Sopenharmony_ci checkParamOk = false; 1188c339a94Sopenharmony_ci } 1198c339a94Sopenharmony_ci if (checkParamOk) { 1208c339a94Sopenharmony_ci result.push({ 'name': re.getReg(v, matchs.regs[1]), 'type': type, 'optional': optionalFlag, 'realType': type }); 1218c339a94Sopenharmony_ci if (type.indexOf('AsyncCallback') >= 0) { 1228c339a94Sopenharmony_ci funcType = FuncType.ASYNC; 1238c339a94Sopenharmony_ci } 1248c339a94Sopenharmony_ci 1258c339a94Sopenharmony_ci if (isSyncFuncType(type, funcType)) { 1268c339a94Sopenharmony_ci funcType = FuncType.SYNC; 1278c339a94Sopenharmony_ci } 1288c339a94Sopenharmony_ci } 1298c339a94Sopenharmony_ci return [result, funcType]; 1308c339a94Sopenharmony_ci} 1318c339a94Sopenharmony_ci 1328c339a94Sopenharmony_cimodule.exports = { 1338c339a94Sopenharmony_ci analyzeParams, 1348c339a94Sopenharmony_ci}; 135