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 { removeExplains, removeEmptyLine, replaceTab, checkOutBody, getLicense, print } = require("./tools/tool"); 17const { NumberIncrease } = require("./tools/common"); 18const { readFile } = require("./tools/FileRW"); 19 20const { analyzeNamespace } = require("./analyze/namespace"); 21const { NapiLog } = require("./tools/NapiLog"); 22 23function analyzeFile(fn) { 24 NumberIncrease.reset(); 25 let data = readFile(fn); 26 let licenseData = getLicense(data) 27 // 去除注释 28 data = removeExplains(data) 29 // 去除空行 30 data = removeEmptyLine(data) 31 // 去除Tab 32 data = replaceTab(data) 33 let result = { 34 exportDefault: [], 35 exports: [], 36 imports:[], 37 declareType: [], 38 declareFunction: [], 39 declareNamespace: [], 40 declareInterface: [], 41 declareLicense: [], 42 } 43 while (true) { 44 // import 45 let matchImport = re.search("import ([{}A-Za-z ,]+) from [\"']{1}([@_./a-zA-Z]+)[\"']{1};*", data); 46 if (matchImport != null) { 47 result.imports.push(re.getReg(data, matchImport.regs[0])) 48 data = re.removeReg(data, matchImport.regs[0]); 49 } 50 else break; 51 } 52 53 if (null != licenseData) { 54 result.declareLicense.push(licenseData) 55 } 56 return analyze(data, result) 57} 58 59function analyze(data, result) { 60 while (true) { 61 let oldData = data 62 data = removeEmptyLine(data) 63 let matchs = re.match(" *\n*", data) 64 //只剩下空格和回车时,解析完成 65 if (matchs && matchs.regs[0][1] == data.length) break 66 matchs = re.match("export default ([a-zA-Z_]+);", data); 67 if (matchs != null) { 68 let exportName = re.getReg(data, matchs.regs[1]) 69 data = re.removeReg(data, matchs.regs[0]); 70 result.exportDefault.push(exportName) 71 } 72 let matchType = analyzeMatchType(matchs, data, result) 73 if (matchType != null) { 74 data = matchType[0] 75 result = matchType[1] 76 } 77 let namespace = analyzeMatchNamespace(matchs, data, result) 78 if (namespace != null) { 79 data = namespace[0] 80 result = namespace[1] 81 } 82 let interface = analyzeMatchInterface(matchs, data, result) 83 if (interface != null) { 84 data = interface[0] 85 result = interface[1] 86 } 87 let functionMatch = analyzeMatchFunction(matchs, data, result) 88 if (functionMatch != null) { 89 data = functionMatch[0] 90 result = functionMatch[1] 91 } 92 if (oldData == data) { 93 NapiLog.logError("\nvvv 解析文件失败 vvv"); 94 NapiLog.logError("[", data.substring(0, data.length > 64 ? 64 : data.length), "]"); 95 break; 96 } 97 } 98 return result 99} 100 101function analyzeMatchNamespace(matchs, data, result) { 102 matchs = re.match("declare namespace ([a-zA-Z_0-9]+) *({)", data); 103 // 解析declare 104 if (matchs != null) { 105 let namespaceName = re.getReg(data, matchs.regs[1]) 106 let namespaceData = checkOutBody(data, matchs.regs[2][0], null, true) 107 data = data.substring(matchs.regs[2][1] + namespaceData.length + 1, data.length) 108 result.declareNamespace.push({ 109 name: namespaceName, 110 body: analyzeNamespace(namespaceData) 111 }) 112 } 113 return [data, result] 114} 115 116function analyzeMatchInterface(matchs, data, result) { 117 matchs = re.match("(export )*(declare )*interface ([A-Za-z_0-9<>= ]+) (extends [a-zA-Z]+ )*({)", data) 118 if (matchs) { 119 let interfaceName = re.getReg(data, matchs.regs[3]) 120 let interfaceData = checkOutBody(data, matchs.regs[5][0], null, true) 121 data = data.substring(matchs.regs[5][1] + interfaceData.length + 1, data.length) 122 result.declareInterface.push({ 123 name: interfaceName, 124 body: {} 125 }) 126 } 127 return [data, result] 128} 129 130function analyzeMatchFunction(matchs, data, result) { 131 matchs = re.match("declare function ([A-Za-z0-9_]+)\\(([\n a-zA-Z:;=,_0-9?<>{}|]*)\\) *:" 132 + "*([A-Za-z0-9_<>{}:, .]+);*", data) 133 if (matchs) { 134 let functionName = re.getReg(data, matchs.regs[1]) 135 let functionBody = re.getReg(data, matchs.regs[2]) 136 data = re.removeReg(data, matchs.regs[0]) 137 result.declareFunction.push({ 138 name: functionName, 139 body: functionBody 140 }) 141 } 142 return [data, result] 143} 144 145function analyzeMatchType(matchs, data, result) { 146 matchs = re.match("(export )*type ([a-zA-Z]+) = ([()a-zA-Z :=>,\"| ]+);", data) 147 if (matchs) { 148 let exportName = re.getReg(data, matchs.regs[2]) 149 let exportBody = re.getReg(data, matchs.regs[3]) 150 data = re.removeReg(data, matchs.regs[0]); 151 result.declareType.push({ 152 name: exportName, 153 body: exportBody 154 }) 155 if (matchs.regs[1][0] != -1) { 156 result.exports.push(exportName) 157 } 158 } 159 160 matchs = re.match("(export )*type ([a-zA-Z]+) = ({)", data) 161 if (matchs) { 162 let exportName = re.getReg(data, matchs.regs[2]) 163 let exportBody = checkOutBody(data, matchs.regs[3][0], null, true) 164 data = data.substring(matchs.regs[3][1] + exportBody.length + 2, data.length) 165 result.declareType.push({ 166 name: exportName, 167 body: exportBody 168 }) 169 if (matchs.regs[1][0] != -1) { 170 result.exports.push(exportName) 171 } 172 } 173 return [data, result] 174} 175 176module.exports = { 177 analyzeFile 178}