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