• 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, isType, typeIndex } = 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
86    // type的处理
87    if (isType(parameter, data)) {
88      let index = typeIndex(parameter, data)
89      if (data.type[index].isEnum) {
90        v["type"] = v["type"].replace(parameter, "string")
91      }
92    }
93    return v
94}
95
96function analyzeFuncNoNameInterface(data, values) {
97    values = re.replaceAll(re.replaceAll(values, " ", ""), "\n", "")
98    let interfaceName = ""
99    let matchNoName = "([:{,;a-zA-Z_0-9]*)\\?*(:[A-Za-z0-9_,;]*)?:{([A-Za-z0-9_]+:"+
100    "[A-Za-z0-9_,;]+)([A-Za-z0-9_]+:[A-Za-z0-9_]+)}(}|,|;)?$"
101    let matchs = re.match(matchNoName, values)
102    if (matchs) {
103        let st = values.lastIndexOf("{")
104        let end = values.indexOf("}")
105        let number = NumberIncrease.getAndIncrease();
106        interfaceName = "AUTO_INTERFACE_%s".format(number)
107        let interfaceBody = values.substring(st+1, end)
108        let typeInterface = "{%s}".format(interfaceBody)
109        values = re.replaceAll(values, typeInterface, interfaceName)
110        interfaceBody = re.replaceAll(interfaceBody, ",", ";")
111        data.interface.push({
112            name: interfaceName,
113            body: analyzeSubInterface(interfaceBody)
114        })
115    }
116
117    matchs = re.match(matchNoName, values)
118    if(matchs) {
119        let resNoNameInter = analyzeFuncNoNameInterface(data, values)
120        values = resNoNameInter.values
121    }
122
123    let result = {
124        interfaceName: interfaceName,
125        values: values
126    }
127    return result
128}
129
130function analyseSubReturn(ret, data) {
131    // 匿名interface返回值 function fun4(input: string): { read: number; written: number };
132    ret = re.replaceAll(re.replaceAll(ret, " ", ""), "\n", "")
133    let tt = re.match("{([A-Za-z0-9_]+:[A-Za-z0-9_,;]+)([A-Za-z0-9_]+:[A-Za-z0-9_]+)}", ret)
134    if (tt) {
135        let len = tt.regs.length
136        let res = ""
137        let interfaceName = ""
138        for (let i=1; i<len; i++) {
139            let regs1 = re.getReg(ret, tt.regs[i])
140            if (regs1 != "}" && regs1 != ",") {
141                res += regs1
142            }
143        }
144
145        let number = NumberIncrease.getAndIncrease();
146        interfaceName = "AUTO_INTERFACE_%s".format(number)
147        let interfaceBody = res
148        ret = interfaceName
149
150        interfaceBody = re.replaceAll(interfaceBody, ",", ";")
151        data.interface.push({
152            name: interfaceName,
153            body: analyzeSubInterface(interfaceBody)
154        })
155    }
156    if (ret.indexOf("number") >= 0) {
157        ret = ret.replaceAll("number", "NUMBER_TYPE_" + NumberIncrease.getAndIncrease())
158    }
159    return ret
160}
161
162/**函数解析 */
163function analyzeFunction(data, isStatic, name, values, ret) {
164    let res = analyzeFuncNoNameInterface(data, values)
165    let tmp
166    let funcType
167    if (res) {
168        tmp = analyzeParams(name, res.values)
169        values = tmp[0]
170        funcType = tmp[1]
171    }
172
173    tmp = analyzeReturn(ret)
174    ret = tmp[0]
175    if (tmp[1]) { // 返回类型为 Promise, 解析成等价的AsyncCallback方法
176        funcType = FuncType.ASYNC
177        // 将返回值Promise<type>改为AsyncCallback<type>,作为方法的入参
178        let paramType = ret.replace("Promise", "AsyncCallback")
179        values.push({name: "promise", optional: false, type: paramType})
180        ret = "void" // 返回值由Promise改为void,与AsyncCallback接口保持一致
181    }
182    for (let j in values) {
183        let v = values[j]
184        v = getFuncParaType(v, res.interfaceName, data)
185        if (v == null) {
186            NapiLog.logError("analyzeFunction is not support this type %s".format(v));
187        }
188    }
189    ret = analyseSubReturn(ret, data)
190    let result = {
191        name: name,
192        type: funcType,
193        value: values,
194        ret: ret,
195        isStatic: isStatic
196    }
197    return result
198}
199
200module.exports = {
201    analyzeFunction,
202    analyzeSubInterface,
203    getFuncParaType
204}