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}