• 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 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