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 { replaceAll, getPrefix } = require('../tools/tool'); 16const { paramGenerate } = require('./param_generate'); 17const { returnGenerate } = require('./return_generate'); 18const { jsonCfgList, InterfaceList, CallFunctionList } = require('../tools/common'); 19const { NapiLog } = require('../tools/NapiLog'); 20 21/** 22 * 结果直接返回 23 */ 24let funcDirectMiddleHTemplete = ` 25struct [funcName]_value_struct {[valueIn][valueOut] 26}; 27 28[static_define]napi_value [funcName]_middle(napi_env env, napi_callback_info info); 29`; 30 31let funcDirectTemplete = ` 32napi_value [middleClassName][funcName]_middle(napi_env env, napi_callback_info info) 33{ 34 XNapiTool *pxt = std::make_unique<XNapiTool>(env, info).release(); 35 if (pxt->IsFailed()) { 36 napi_value err = pxt->GetError(); 37 delete pxt; 38 return err; 39 } 40 [unwarp_instance] 41 struct [funcName]_value_struct *vio = new [funcName]_value_struct(); 42 [valueCheckout] 43 [addListener] 44 [callFunc] 45 napi_value result = nullptr; 46 [valuePackage][optionalParamDestory] 47 delete vio; 48 delete pxt; // release 49 return result; 50}`; 51 52let cppTemplate = ` 53%s 54bool %s%s(%s) 55{ 56 %s 57 return true; 58} 59`; 60 61function removeEndlineEnter(value) { 62 for (let i = value.length; i > 0; i--) { 63 let len = value.length; 64 if (value.substring(len - 1, len) === '\n' || value.substring(len - 1, len) === ' ') { 65 value = value.substring(0, len - 1); 66 } else { 67 value = ' ' + value; 68 break; 69 } 70 } 71 return value; 72} 73 74function isAddFunc(name) { 75 let regIndex = name.indexOf('add'); 76 let flag = false; 77 if (regIndex === 0) { 78 flag = true; 79 } 80 return flag; 81} 82 83function isRemoveFunc(name) { 84 let regIndex = name.indexOf('remove'); 85 let flag = false; 86 if (regIndex === 0) { 87 flag = true; 88 } 89 return flag; 90} 91 92function getaddListenerCont() { 93 let addListenerCont = `napi_value para = pxt->GetArgv(XNapiTool::ZERO); 94 napi_valuetype valueType = napi_undefined; 95 napi_status status = napi_typeof(env, para, &valueType); 96 if (status != napi_ok) { 97 return nullptr; 98 } 99 if (valueType != napi_object) { 100 printf("valueType is Err, not napi_object !"); 101 return nullptr; 102 } 103 104 std::vector<std::string> proNames; 105 std::string prefixName = "%s"; 106 std::string proNameReg = ""; 107 std::string proName = ""; 108 [getProNames] 109 for(size_t i=0; i<proNames.size(); i++) { 110 proName = proNames[i]; 111 printf("proName is: %s! ", proName.c_str()); 112 bool hasProperty = false; 113 napi_value cbFunc = nullptr; 114 napi_has_named_property(env, para, proName.c_str(), &hasProperty); 115 if (hasProperty) { 116 printf("hasProperty is true! "); 117 napi_value propKey = nullptr; 118 napi_create_string_utf8(env, proName.c_str(), proName.length(), &propKey); 119 napi_get_property(env, para, propKey, &cbFunc); 120 if (cbFunc != nullptr) { 121 proNameReg = prefixName + "_" + proName; 122 printf("proNameReg is %s ", proNameReg.c_str()); 123 [RegistOrUnregistFunc] 124 } 125 } 126 }`; 127 return addListenerCont; 128} 129 130//(InterfaceList.getValue(type)) 判断func value是否为interface 131//是的话,读callfunction 根据 interfaceName过滤得到所有回调的名称,填到Add处理中 132// add处理根据名称集检查当前实例对象是否存在此回调,存在则注册,否则不处理 133function getAddOrRemoveReg(func, isAddReg) { 134 let addListenerCont = ''; 135 const addParaSize = 1; 136 if (func.value.length !== addParaSize) { 137 NapiLog.logError(`AddReg param do not support param number not 1!`); 138 return ''; 139 } 140 141 let ValueType = func.value[0].type; 142 let funNames = []; 143 if (InterfaceList.getValue(ValueType)) { 144 let cbFuncTypePrefix = 'AUTO_CALLFUNCTION_' + ValueType; 145 funNames = CallFunctionList.getObjOnFuncName(cbFuncTypePrefix); 146 } 147 148 addListenerCont = getaddListenerCont(); 149 let proNamesValues = ''; 150 for (let i = 0; i < funNames.length; i++) { 151 proNamesValues += 'proNames.push_back("%s");\r\n'.format(funNames[i]); 152 } 153 addListenerCont = replaceAll(addListenerCont, '[getProNames]', proNamesValues); 154 addListenerCont = addListenerCont.format(ValueType); 155 156 let registOrUnregis = ''; 157 if (isAddReg) { 158 registOrUnregis = 'pxt->RegistOnOffFunc(proNameReg, cbFunc);'; 159 } else { 160 registOrUnregis = 'pxt->UnregistOnOffFunc(proNameReg);'; 161 } 162 addListenerCont = replaceAll(addListenerCont, '[RegistOrUnregistFunc]', registOrUnregis); 163 return addListenerCont; 164} 165 166function replaceOptionalParamDestory(middleFunc, param) { 167 if (param.optionalParamDestory === '') { 168 middleFunc = replaceAll(middleFunc, '[optionalParamDestory]', param.optionalParamDestory); // 可选参数内存释放 169 } else { 170 middleFunc = replaceAll(middleFunc, '[optionalParamDestory]', '\n ' + param.optionalParamDestory); // 可选参数内存释放 171 } 172 return middleFunc; 173} 174 175function generateFunctionDirect(func, data, className, implHVariable) { 176 let middleFunc = replaceAll(funcDirectTemplete, '[funcName]', func.name); 177 let middleH = ''; 178 if (func.name !== 'constructor') { 179 middleH = replaceAll(funcDirectMiddleHTemplete, '[funcName]', func.name); 180 } 181 182 let isAddReg = isAddFunc(func.name); 183 let isRemoveReg = isRemoveFunc(func.name); 184 let addListenerCont = ''; 185 if (isAddReg || isRemoveReg) { 186 addListenerCont = getAddOrRemoveReg(func, isAddReg); 187 } 188 middleFunc = replaceAll(middleFunc, '[addListener]', addListenerCont); 189 190 let isClassresult = isClassFunc(className, middleFunc, middleH); 191 middleFunc = isClassresult[0]; 192 middleH = isClassresult[1]; 193 // 定义输入,定义输出,解析,填充到函数内,输出参数打包,impl参数定义,可选参数内存释放 194 let param = { 195 valueIn: '', valueOut: '', valueCheckout: '', valueFill: '', 196 valuePackage: '', valueDefine: '', optionalParamDestory: '' 197 }; 198 199 for (let i in func.value) { 200 paramGenerate(i, func.value[i], param, data); 201 } 202 let returnInfo = { type: func.ret, optional: false }; 203 if (func.ret === 'void') { 204 param.valuePackage = 'result = pxt->UndefinedValue();'; 205 } else { 206 returnGenerate(returnInfo, param, data); 207 } 208 middleH = replaceValueOut(middleH, param); 209 210 param.valueCheckout = removeEndlineEnter(param.valueCheckout); 211 middleFunc = replaceAll(middleFunc, '[valueCheckout]', param.valueCheckout); // # 输入参数解析 212 let callFunc = '%s%s(%s);'.format(className === null || className === undefined ? '' : 'pInstance->', 213 func.name, param.valueFill); 214 middleFunc = replaceAll(middleFunc, '[callFunc]', callFunc); // 执行 215 middleFunc = replaceAll(middleFunc, '[valuePackage]', param.valuePackage); // 输出参数打包 216 middleFunc = replaceOptionalParamDestory(middleFunc, param); 217 let prefixArr = getPrefix(data, func); 218 let implH = ''; 219 let implCpp = ''; 220 221 if (!func.isParentMember) { 222 if (func.name === 'constructor') { 223 // 构造函数去掉&或* (在内部去掉较麻烦,生成后统一去除) 224 implH = constructorFunc(param, implHVariable, implH, prefixArr, className); 225 middleFunc = ''; 226 } else { 227 // 只有类/接口自己的成员方法需要在.h.cpp中生成,父类/父接口不需要 228 implH = getimplHForForComClassValue(isAddReg, param, prefixArr, func); 229 implCpp = getimplCppForComClassValue(isAddReg, param, className, func); 230 } 231 } 232 return [middleFunc, implH, implCpp, middleH]; 233} 234 235function getimplHForForComClassValue(isAddReg, param, prefixArr, func) { 236 let implH = '\n%s%s%sbool %s(%s)%s;'.format( 237 prefixArr[0], prefixArr[1], prefixArr[2], func.name, param.valueDefine, prefixArr[3]); 238 239 if (isAddReg) { 240 let ValueType = func.value[0].type; 241 implH += '\n static %s listener_;'.format(ValueType); 242 } 243 return implH; 244} 245 246function getimplCppForComClassValue(isAddReg, param, className, func) { 247 let implCpp = ''; 248 let initListener = ''; 249 let callStatement = jsonCfgList.getValue((className === null || className === undefined) ? 250 '' : className, func.name); 251 252 if (isAddReg) { 253 initListener = '%s %s::listener_ = {};'.format(func.value[0].type, className); 254 callStatement = '%s::listener_ = listener;'.format(className); 255 } 256 257 implCpp = cppTemplate.format(initListener, (className === null || className === undefined) ? 258 '' : className + '::', func.name, 259 param.valueDefine, (callStatement === null || callStatement === undefined) ? '' : callStatement); 260 return implCpp; 261} 262 263function replaceValueOut(middleH, param) { 264 middleH = replaceAll(middleH, '[valueIn]', param.valueIn); // # 输入参数定义 265 if (param.valueOut === '') { 266 middleH = replaceAll(middleH, '[valueOut]', param.valueOut); // # 输出参数定义 267 } else { 268 middleH = replaceAll(middleH, '[valueOut]', '\n ' + param.valueOut); // # 输出参数定义 269 } 270 return middleH; 271} 272 273function isClassFunc(className, middleFunc, middleH) { 274 if (className === null || className === undefined) { 275 middleH = middleH.replaceAll('[static_define]', ''); 276 middleFunc = middleFunc.replaceAll('[unwarp_instance]', ''); 277 middleFunc = middleFunc.replaceAll('[middleClassName]', ''); 278 } 279 else { 280 middleH = middleH.replaceAll('[static_define]', 'static '); 281 middleFunc = middleFunc.replaceAll('[unwarp_instance]', 282 `void *instPtr = pxt->UnWarpInstance(); 283 %s *pInstance = static_cast<%s *>(instPtr);`.format(className, className)); 284 middleFunc = middleFunc.replaceAll('[middleClassName]', className + '_middle' + '::'); 285 } 286 return [middleFunc, middleH]; 287} 288 289function constructorFunc(param, implHVariable, implH, prefixArr, className) { 290 let valueDef = param.valueDefine; 291 if (valueDef.indexOf('&') > 0 || valueDef.indexOf('*') > 0) { 292 let index = valueDef.indexOf('&'); 293 while (index > 0) { 294 valueDef = valueDef.substring(0, index) + valueDef.substring(index + 1, valueDef.length); 295 index = valueDef.indexOf('&'); 296 } 297 index = valueDef.indexOf('*'); 298 while (index > 0) { 299 valueDef = valueDef.substring(0, index) + valueDef.substring(index + 1, valueDef.length); 300 index = valueDef.indexOf('*'); 301 } 302 } 303 let body = valueDef.split(','); 304 let result = []; 305 let body2 = implHVariable.split(';'); 306 let result2 = []; 307 for (let i = 0; i < body.length; i++) { 308 let ii = body[i].lastIndexOf(' '); 309 result[i] = body[i].substring(ii + 1, body[i].length); 310 } 311 for (let k = 0; k < body2.length; k++) { 312 let kk = body2[k].lastIndexOf(' '); 313 result2[k] = body2[k].substring(kk + 1, body2[k].length); 314 } 315 let len = result.length; 316 let costructorStr = ''; 317 for (let m = 0; m < len - 1; m++) { 318 costructorStr += '%s(%s), '.format(result2[m], result[m]); 319 } 320 costructorStr += '%s(%s)'.format(result2[len - 1], result[len - 1]); 321 322 // 构造函数只在h文件中,cpp文件中不包含 323 if (len > 0) { 324 implH = '\n%s%s%s%s() {};'.format( 325 prefixArr[0], prefixArr[1], prefixArr[2], className); 326 implH += '\n%s%s%s%s(%s) : %s {};'.format( 327 prefixArr[0], prefixArr[1], prefixArr[2], className, valueDef, costructorStr); 328 } else { 329 implH = '\n%s%s%s%s() {};'.format( 330 prefixArr[0], prefixArr[1], prefixArr[2], className); 331 } 332 return implH; 333} 334 335module.exports = { 336 generateFunctionDirect 337};