• 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("../tools/re");
16const { FuncType, NumberIncrease, isEnum, EnumValueType, enumIndex } = require("../tools/common");
17const { analyzeParams } = require("./params");
18const { analyzeReturn } = require("./return");
19const { NapiLog } = require("../tools/NapiLog");
20const { randomInt } = require("crypto");
21const { print } = require("../tools/tool");
22
23function analyzeSubInterface(data) {
24    let body = re.replaceAll(data, "\n", "").split(";")//  # replace(" ", "").
25    let result = {
26        value: [],
27        function: [],
28        parentNameList: [],
29        childList: [],
30        parentList: []
31    }
32    for (let i in body) {
33        let t = body[i]
34        while (t.length > 0 && t[0] == ' ')//去除前面的空格
35            t = t.substring(1, t.length)
36        while (t.length > 0 && t[-1] == ' ')//去除后面的空格
37            t = t.substring(0, t.length - 1)
38        if (t == "") break//如果t为空直接返回
39        let tt = re.match(" *([a-zA-Z0-9_]+) *: *([a-zA-Z_0-9<>,:{}[\\] ]+)", t)
40        if (tt) {//变量
41
42            let valueName = re.getReg(t, tt.regs[1])
43            let valueType = re.getReg(t, tt.regs[2])
44            let index = valueType.indexOf("number")
45            while (index !== -1) {
46                valueType = valueType.replace("number", "NUMBER_TYPE_" + NumberIncrease.getAndIncrease())
47                index = valueType.indexOf("number")
48            }
49            result.value.push({
50                name: valueName,
51                type: valueType
52            })
53        }
54    }
55    return result
56}
57
58function getFuncParaType(v, interfaceName, data) {
59    let arrayType = re.match("(Async)*Callback<(Array<([a-zA-Z_0-9]+)>)>", v["type"])
60    let parameter = v["type"]
61    if (arrayType) {
62        parameter = re.getReg(v["type"], arrayType.regs[2])
63    }
64    if (isEnum(parameter, data)) {
65        let index = enumIndex(parameter, data)
66        if (data.enum[index].body.enumValueType == EnumValueType.ENUM_VALUE_TYPE_NUMBER) {
67            v["type"] = v["type"].replace(parameter, "NUMBER_TYPE_" + NumberIncrease.getAndIncrease())
68        } else if (data.enum[index].body.enumValueType == EnumValueType.ENUM_VALUE_TYPE_STRING) {
69            v["type"] = v["type"].replace(parameter, "string")
70        } else {
71            NapiLog.logError("analyzeFunction getFuncParaType is not support this type %s"
72                .format(data.enum[index].body.enumValueType));
73            return null
74        }
75    }
76
77    let interfaceType = re.match("{([A-Za-z0-9_]+:[A-Za-z0-9_,]+)([A-Za-z0-9_]+:[A-Za-z0-9_]+)}$", v["type"])
78    if (interfaceType) {
79        v["type"] = interfaceName
80    }
81
82    if (parameter.indexOf("number") >= 0) {
83        v["type"] = v["type"].replace("number", "NUMBER_TYPE_" + NumberIncrease.getAndIncrease())
84    }
85    return v
86}
87
88function analyzeFuncNoNameInterface(data, values) {
89    values = re.replaceAll(re.replaceAll(values, " ", ""), "\n", "")
90    let interfaceName = ""
91    let matchNoName = "([:{,;a-zA-Z_0-9]*)\\?*(:[A-Za-z0-9_,;]*)?:{([A-Za-z0-9_]+:"+
92    "[A-Za-z0-9_,;]+)([A-Za-z0-9_]+:[A-Za-z0-9_]+)}(}|,|;)?$"
93    let matchs = re.match(matchNoName, values)
94    if (matchs) {
95        let st = values.lastIndexOf("{")
96        let end = values.indexOf("}")
97        let number = NumberIncrease.getAndIncrease();
98        interfaceName = "AUTO_INTERFACE_%s".format(number)
99        let interfaceBody = values.substring(st+1, end)
100        let typeInterface = "{%s}".format(interfaceBody)
101        values = re.replaceAll(values, typeInterface, interfaceName)
102        interfaceBody = re.replaceAll(interfaceBody, ",", ";")
103        data.interface.push({
104            name: interfaceName,
105            body: analyzeSubInterface(interfaceBody)
106        })
107    }
108
109    matchs = re.match(matchNoName, values)
110    if(matchs) {
111        let resNoNameInter = analyzeFuncNoNameInterface(data, values)
112        values = resNoNameInter.values
113    }
114
115    let result = {
116        interfaceName: interfaceName,
117        values: values
118    }
119    return result
120}
121
122function analyseSubReturn(ret, data) {
123    //匿名interface返回值 function fun4(input: string): { read: number; written: number };
124    ret = re.replaceAll(re.replaceAll(ret, " ", ""), "\n", "")
125    let tt = re.match("{([A-Za-z0-9_]+:[A-Za-z0-9_,;]+)([A-Za-z0-9_]+:[A-Za-z0-9_]+)}", ret)
126    if (tt) {
127        let len = tt.regs.length
128        let res = ""
129        let interfaceName = ""
130        for (let i=1; i<len; i++) {
131            let regs1 = re.getReg(ret, tt.regs[i])
132            if (regs1 != "}" && regs1 != ",") {
133                res += regs1
134            }
135        }
136
137        let number = NumberIncrease.getAndIncrease();
138        interfaceName = "AUTO_INTERFACE_%s".format(number)
139        let interfaceBody = res
140        ret = interfaceName
141
142        interfaceBody = re.replaceAll(interfaceBody, ",", ";")
143        data.interface.push({
144            name: interfaceName,
145            body: analyzeSubInterface(interfaceBody)
146        })
147    }
148    if (ret.indexOf("number") >= 0) {
149        ret = ret.replaceAll("number", "NUMBER_TYPE_" + NumberIncrease.getAndIncrease())
150    }
151    return ret
152}
153
154/**函数解析 */
155function analyzeFunction(data, isStatic, name, values, ret) {
156    let res = analyzeFuncNoNameInterface(data, values)
157    let tmp
158    let funcType
159    if (res) {
160        tmp = analyzeParams(name, res.values)
161        values = tmp[0]
162        funcType = tmp[1]
163    }
164
165    tmp = analyzeReturn(ret)
166    ret = tmp[0]
167    if (tmp[1]) { // 返回类型为 Promise, 解析成等价的AsyncCallback方法
168        funcType = FuncType.ASYNC
169        // 将返回值Promise<type>改为AsyncCallback<type>,作为方法的入参
170        let paramType = ret.replace("Promise", "AsyncCallback")
171        values.push({name: "promise", optional: false, type: paramType})
172        ret = "void" // 返回值由Promise改为void,与AsyncCallback接口保持一致
173    }
174    for (let j in values) {
175        let v = values[j]
176        v = getFuncParaType(v, res.interfaceName, data)
177        if (v == null) {
178            NapiLog.logError("analyzeFunction is not support this type %s".format(v));
179        }
180    }
181    ret = analyseSubReturn(ret, data)
182    let result = {
183        name: name,
184        type: funcType,
185        value: values,
186        ret: ret,
187        isStatic: isStatic
188    }
189    return result
190}
191
192module.exports = {
193    analyzeFunction,
194    analyzeSubInterface,
195    getFuncParaType
196}