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 re = require('./re'); 16let vscode = null; 17try { 18 vscode = require('vscode'); 19} 20catch (err) { 21 vscode = null; 22} 23 24const NUM_CONST_MAP = new Map([ 25 [0, 'XNapiTool::ZERO'], [1, 'XNapiTool::ONE'], [2, 'XNapiTool::TWO'], [3, 'XNapiTool::THREE'], 26 [4, 'XNapiTool::FOUE'], [5, 'XNapiTool::FIVE'], [6, 'XNapiTool::SIX'], [7, 'XNapiTool::SEVEN'], 27 [8, 'XNapiTool::EIGHT'], [9, 'XNapiTool::NINE'] 28]); 29 30function print(...args) { 31 if (vscode) { 32 vscode.window.showInformationMessage(...args); 33 } 34 console.log(...args); 35} 36 37String.prototype.format = function (...args) { 38 let result = this; 39 let reg = new RegExp('%[sd]{1}'); 40 for (let i = 0; i < args.length; i++) { 41 let p = result.search(reg); 42 if (p < 0) { 43 break; 44 } 45 result = result.substring(0, p) + args[i] + result.substring(p + 2, result.length); 46 } 47 return result; 48}; 49 50String.prototype.replaceAll = function (...args) { 51 let result = this; 52 while (result.indexOf(args[0]) >= 0) { 53 result = result.replace(args[0], args[1]); 54 } 55 return result; 56}; 57 58function checkOutBody(body, off, flag, binside) { 59 off = off || 0; 60 flag = flag || ['{', '}']; 61 binside = binside || false; 62 let idx = { 63 '(': ')', 64 '{': '}', 65 '<': '>', 66 }; 67 let csl = {}; 68 let csr = {}; 69 for (let f in idx) { 70 csl[f] = 0; 71 csr[idx[f]] = 0; 72 } 73 let cs1 = 0; 74 if (flag[0].length > 0 && body.substring(off, off + flag[0].length) !== flag[0]) { 75 return null; 76 } 77 78 for (let i = off + flag[0].length; i < body.length; i++) { 79 if (body[i] === '"') { 80 cs1 += 1; 81 } 82 if (cs1 % 2 === 0) { 83 let tb1 = true; 84 checkOutBodyFunc(csl, csr, idx, tb1, body, i, flag, binside, off); 85 } 86 } 87 return null; 88} 89 90function checkOutBodyFunc(csl, csr, idx, tb1, body, i, flag, binside, off) { 91 for (let k in csl) { 92 if (csl[k] !== csr[idx[k]]) { 93 tb1 = false; 94 break; 95 } 96 } 97 if (tb1 && body.substring(i, i + flag[1].length) === flag[1]) { 98 if (binside) { 99 return body.substring(off + flag[0].length, i); 100 } 101 return body.substring(off, i + flag[1].length); 102 } 103 104 if (body[i] in csl) { 105 csl[body[i]] += 1; 106 if (body[i] in csr) { 107 csr[body[i]] += 1; 108 } 109 } 110 if (body[i] in csr) { 111 if (!(body[i] === '>' && body[i - 1] === '=')) { // 尖括号匹配时忽略关键字 "=>" 112 csr[body[i]] += 1; 113 } 114 } 115 return ''; 116} 117 118function removeExplains(data) { 119 // 去除 /** */ 类型的注释 120 while (data.indexOf('/*') >= 0) { 121 let i1 = data.indexOf('/*'); 122 let i2 = data.indexOf('*/') + 2; 123 data = data.substring(0, i1) + data.substring(i2, data.length); 124 } 125 126 // 去除 namespace 域外 // 类型的注释 127 // 如果换行格式是\r\n, 去除\r, 统一成\n格式 128 while (data.indexOf('\r') >= 0) { 129 data = data.replace('\r', ''); 130 } 131 while (data.indexOf('//') >= 0) { 132 let i1 = data.indexOf('//'); 133 let i2 = data.indexOf('\n'); 134 let end = data.indexOf('declare namespace '); 135 while (i2 < end && i1 < end) { 136 while (i1 > i2) { 137 data = data.substring(0, i2) + data.substring(i2 + 2, data.length); 138 i2 = data.indexOf('\n'); 139 i1 = data.indexOf('//'); 140 } 141 data = data.substring(0, i1) + data.substring(i2 + 1, data.length); 142 i1 = data.indexOf('//'); 143 i2 = data.indexOf('\n'); 144 end = data.indexOf('declare namespace '); 145 } 146 if (i2 > end || i1 > end) { 147 break; 148 } 149 } 150 151 return data; 152} 153 154function getLicense(data) { 155 while (data.indexOf('/*') >= 0) { 156 let i1 = data.indexOf('/*'); 157 let i2 = data.indexOf('*/') + 2; 158 let licenseData = data.substring(i1, i2); 159 if (licenseData.search('Copyright') !== -1) { 160 return licenseData; 161 } else { 162 return ''; 163 } 164 } 165 return ''; 166} 167 168function removeEmptyLine(data) { 169 while (data.indexOf('\r') >= 0) { 170 data = data.replace('\r', ''); 171 } 172 while (data.indexOf('\t') >= 0) { 173 data = data.replace('\t', ''); 174 } 175 while (data.indexOf(' \n') >= 0) { 176 data = data.replace(' \n', '\n'); 177 } 178 while (data.indexOf('\n ') >= 0) { 179 data = data.replace('\n ', '\n'); 180 } 181 while (data.indexOf('\n\n') >= 0) { 182 data = data.replace('\n\n', '\n'); 183 } 184 while (data.indexOf('\n') === 0) { 185 data = data.substring(1, data.length); 186 } 187 while (data.indexOf(' ') === 0) { 188 data = data.substring(1, data.length); 189 } 190 return data; 191} 192 193function replaceTab(data) { 194 while (data.indexOf('\t') >= 0) { 195 data = data.replace('\t', ' '); 196 } 197 return data; 198} 199 200function removeEmptyLine2(data) { 201 while (data.indexOf(' \n')) { 202 data = data.replace(' \n', '\n'); 203 } 204 while (data.indexOf('\n\n\n')) { 205 data = data.replace('\n\n\n', '\n\n'); 206 } 207 return data; 208} 209 210function replaceAll(s, sfrom, sto) { 211 while (s.indexOf(sfrom) >= 0) { 212 s = s.replace(sfrom, sto); 213 } 214 return s; 215} 216 217/** 218 * 比较两个方法是否完全相同 219 * @param func1 方法1 220 * @param func2 方法2 221 * @returns 方法名称与形参是否完全相同 222 */ 223function isSameFunc(func1, func2) { 224 if (func1.name !== func2.name) { // 判断方法名称是否相同 225 return false; 226 } 227 228 let func1ParamCount = func1.value.length; 229 if (func1ParamCount !== func2.value.length) { // 判断方法形参个数是否一样 230 return false; 231 } 232 233 for (let i in func1.value) { // 判断方法每个形参数据类型是否相同 234 if (func1.value[i].type !== func2.value[i].type) { 235 if (!(func1.value[i].type.indexOf('NUMBER_TYPE_') >= 0 && 236 func2.value[i].type.indexOf('NUMBER_TYPE_') >= 0)) { 237 return false; 238 } 239 } 240 } 241 242 // 以上全部相同,判定为相同方法 243 return true; 244} 245 246/** 247 * 将方法对象插入列表(重复的方法对象不插入) 248 * @param obj 待插入的方法对象 249 * @param list 目标列表 250 * @returns 是否成功插入列表 251 */ 252function addUniqFunc2List(obj, list) { 253 for (let i in list) { 254 if (isSameFunc(obj, list[i])) { 255 return false; 256 } 257 } 258 list.push(obj); 259 return true; 260} 261 262/** 263 * 找到子类中重写父类的方法并将它设置为override 264 * @param parentFunc 父类被重写的方法名 265 * @param childFunclist 子类全部方法列表 266 * @returns void 267 */ 268function setOverrideFunc(parentFunc, childFunclist) { 269 for (let i in childFunclist) { 270 if (isSameFunc(parentFunc, childFunclist[i])) { 271 childFunclist[i].isOverride = true; 272 return; 273 } 274 } 275} 276 277/** 278 * 将对象插入列表(名称重复的属性对象不插入) 279 * @param obj 待插入的对象 280 * @param list 目标列表 281 * @returns void 282 */ 283function addUniqObj2List(obj, list) { 284 for (let i in list) { 285 if (list[i].name === obj.name) { 286 return; 287 } 288 } 289 list.push(obj); 290} 291 292/** 293 * 如果方法所在的类为基类,生成的c++函数定义为虚函数 294 * @param data 方法所在的类信息 295 * @param funcInfo 方法信息 296 * return tabStr 缩进,staticStr 静态函数关键词,virtualStr 虚函数关键词, overrideStr 重写关键词 297 */ 298function getPrefix(data, funcInfo) { 299 let isStatic = funcInfo.isStatic; 300 let tabStr = ''; 301 let virtualStr = ''; 302 let staticStr = isStatic ? 'static ' : ''; 303 if (data.childList) { 304 tabStr = ' '; // 类中的方法增加一个缩进 305 virtualStr = (data.childList.length > 0 && !isStatic) ? 'virtual ' : ''; //如果是基类中的非静态方法,定义为虚函数 306 } 307 let overrideStr = funcInfo.isOverride ? ' override' : ''; // 重写了父类方法,需要加上override关键字,否则触发c++门禁告警 308 return [tabStr, staticStr, virtualStr, overrideStr]; 309} 310 311function getConstNum(num) { 312 return NUM_CONST_MAP.get(parseInt(num)); 313} 314 315module.exports = { 316 checkOutBody, 317 removeExplains, 318 removeEmptyLine, 319 removeEmptyLine2, 320 replaceAll, 321 print, 322 getLicense, 323 replaceTab, 324 addUniqObj2List, 325 addUniqFunc2List, 326 getPrefix, 327 getConstNum, 328 setOverrideFunc, 329}; 330