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}