• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2022 Huawei Device 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 */
15
16const { readFile } = require('./util');
17const path = require('path');
18const fs = require('fs');
19const ts = require('typescript');
20const { visitEachChild } = require('typescript');
21
22let apiList = [];
23let importFiles = new Map();
24let moduleName = [];
25let applicationApis = [];
26let classNames = [];
27let finalClassName = [];
28
29function collectApi(url) {
30    const applicationUrl = path.resolve(__dirname, url);
31    const applicationFiles = [];
32    readFile(applicationUrl, applicationFiles);
33    tsTransform(applicationFiles, getImportFileName);
34}
35
36function tsTransform(applicationFiles, callback) {
37    applicationFiles.forEach(url => {
38        if (/\.ets/.test(path.basename(url)) || /\.ts/.test(path.basename(url))) {
39            const content = fs.readFileSync(url, 'utf-8');
40            const fileName = path.basename(url).replace(/\.d.ts$/g, 'ts');
41            ts.transpileModule(content, {
42                compilerOptions: {
43                    "target": ts.ScriptTarget.ES2017
44                },
45                fileName: fileName,
46                transformers: { before: [callback(url)] }
47            })
48        }
49    });
50}
51
52function getImportFileName(url) {
53    return (context) => {
54        return (sourcefile) => {
55            const statements = sourcefile.statements;
56            statements.forEach(item => {
57                if (ts.isImportDeclaration(item)) {
58                    judgeImportFile(item);
59                } else {
60                    collectApplicationApi(item, sourcefile);
61                }
62            })
63            return sourcefile;
64        }
65        function collectApplicationApi(node, sourcefile) {
66            if (ts.isPropertyAccessExpression(node) && node.expression && ts.isIdentifier(node.name)) {
67                if (ts.isCallExpression(node.expression) && ts.isPropertyAccessExpression(node.expression.expression)) {
68                    apiList.push({
69                        fileName: path.basename(url),
70                        moduleName: node.expression.expression.expression.escapedText,
71                        apiName: node.name.escapedText
72                    })
73                } else if (ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.expression)) {
74                    apiList.push({
75                        fileName: path.basename(url),
76                        moduleName: node.expression.expression.escapedText,
77                        apiName: node.expression.name.escapedText,
78                        value: node.name.escapedText
79                    })
80                } else if (ts.isIdentifier(node.expression) && ts.isCallExpression(node.parent)) {
81                    if (node.parent.arguments && node.name.escapedText.toString() == 'on' || node.name.escapedText.toString() == 'off') {
82                        node.parent.arguments.forEach(argument => {
83                            if (ts.isStringLiteral(argument)) {
84                                apiList.push({
85                                    fileName: path.basename(url),
86                                    moduleName: node.expression.escapedText,
87                                    apiName: node.name.escapedText + '_' + argument.text
88                                })
89                            }
90                        })
91                    } else {
92                        apiList.push({
93                            fileName: path.basename(url),
94                            moduleName: node.expression.escapedText,
95                            apiName: node.name.escapedText
96                        })
97                    }
98                }
99            } else if (ts.isQualifiedName(node) && ts.isTypeReferenceNode(node.parent)) {
100                apiList.push({
101                    fileName: path.basename(url),
102                    moduleName: node.left.escapedText,
103                    apiName: node.right.escapedText
104                })
105            }
106            node.getChildren().forEach(item => collectApplicationApi(item, sourcefile));
107        }
108    }
109}
110
111
112
113function judgeImportFile(node) {
114    if (ts.isStringLiteral(node.moduleSpecifier)) {
115        if ((node.moduleSpecifier.text).indexOf('@ohos.') != -1 || (node.moduleSpecifier.text).indexOf('@system.') != -1) {
116            let moduleNames = [];
117            if (importFiles.get(node.moduleSpecifier.text)) {
118                const moduleNameSet = new Set(importFiles.get(node.moduleSpecifier.text));
119                if (!moduleNameSet.has(node.importClause.name.escapedText)) {
120                    moduleNameSet.add(node.importClause.name.escapedText);
121                    moduleName.push(node.importClause.name.escapedText)
122                }
123                moduleNames = [...moduleNameSet];
124            } else {
125                moduleNames.push(node.importClause.name.escapedText);
126                moduleName.push(node.importClause.name.escapedText);
127            }
128            importFiles.set(node.moduleSpecifier.text, moduleNames);
129        }
130    }
131}
132
133function filterApi() {
134    moduleName.forEach(module => {
135        apiList.forEach(api => {
136            if (module == api.moduleName) {
137                applicationApis.push(api);
138            }
139        })
140    })
141
142    moduleName.forEach(module => {
143        classNames.forEach(className => {
144            if (module == className) {
145                finalClassName.push(className);
146            }
147        })
148    })
149}
150
151try {
152    collectApi("../application");
153    filterApi();
154    exports.importFiles = importFiles;
155    exports.applicationApis = applicationApis;
156} catch (error) {
157    console.error('COLLECT IMPORT NAME ERROR: ', error);
158}