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 fs = require('fs'); 17const path = require('path'); 18const ts = require('typescript'); 19const SECOND_PARAM = 2; 20const THIRD_PARAM = 3; 21const FOURTH_PARAM = 4; 22const FIFTH_PARAM = 5; 23const systemModules = []; 24 25function generateKitConfig(kitFilePath, output, apiFilePath, arktsFilePath) { 26 readSystemApis(apiFilePath, systemModules); 27 readSystemApis(arktsFilePath, systemModules); 28 const kitFiles = []; 29 readFile(kitFilePath, kitFiles); 30 if (fs.existsSync(output)) { 31 removeDir(output); 32 } 33 mkDir(output); 34 kitFiles.forEach((item) => { 35 let content = fs.readFileSync(item, 'utf8'); 36 const outputPath = path.resolve(output, path.basename(item).replace('.d.ts', '.json')); 37 const symbol = {}; 38 const kitSourceFile = ts.createSourceFile(item, content, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS); 39 if (kitSourceFile.statements && kitSourceFile.statements.length > 0) { 40 kitSourceFile.statements.forEach(statement => { 41 getImportDeclarationInfo(statement, symbol); 42 }); 43 } 44 const result = { 45 'symbols': symbol 46 }; 47 const STANDARD_INDENT = 2; 48 createKitConfigs(outputPath, JSON.stringify(result, null, STANDARD_INDENT)); 49 }); 50} 51 52function getImportDeclarationInfo(statement, symbol) { 53 if (!ts.isImportDeclaration(statement)) { 54 return; 55 } 56 let source = ''; 57 if (statement.moduleSpecifier && ts.isStringLiteral(statement.moduleSpecifier)) { 58 source = statement.moduleSpecifier.getText().replace(/('|")*/g, ''); 59 for (let i = 0; i < systemModules.length; i++) { 60 const moduleName = systemModules[i]; 61 if (moduleName.replace(/(\.d\.ts|\.d\.ets)$/, '') === source) { 62 source = moduleName; 63 break; 64 } 65 } 66 } 67 if (statement.importClause) { 68 const clause = statement.importClause; 69 if (clause.name) { 70 addSymbol(symbol, clause.name.getText(), source, 'default'); 71 } 72 if (clause.namedBindings) { 73 const binding = clause.namedBindings; 74 if (ts.isNamespaceImport(binding) && binding.name) { 75 addSymbol(symbol, binding.name.getText(), source, 'default'); 76 } else if (ts.isNamedImports(binding) && binding.elements && binding.elements.length > 0) { 77 processNamedImports(binding.elements, symbol, source); 78 } 79 } 80 } 81} 82 83function processNamedImports(elements, symbol, source) { 84 elements.forEach(element => { 85 if (ts.isImportSpecifier(element)) { 86 const name = element.name.getText(); 87 const bindingsName = element.propertyName ? element.propertyName.getText() : name; 88 addSymbol(symbol, name, source, bindingsName); 89 } 90 }); 91} 92 93function addSymbol(symbol, name, source, bindings) { 94 symbol[name] = { 95 source: source, 96 bindings: bindings 97 }; 98} 99 100function readFile(dir, fileDir) { 101 const files = fs.readdirSync(dir); 102 files.forEach((element) => { 103 const filePath = path.join(dir, element); 104 const status = fs.statSync(filePath); 105 if (status.isDirectory()) { 106 readFile(filePath, fileDir); 107 } else { 108 fileDir.push(filePath); 109 } 110 }); 111} 112 113function readSystemApis(dir, fileDir) { 114 const files = fs.readdirSync(dir); 115 files.forEach(file => { 116 const filePath = path.join(dir, file); 117 const status = fs.statSync(filePath); 118 if (!status.isDirectory()) { 119 fileDir.push(file); 120 } 121 }); 122} 123 124function mkDir(filePath) { 125 const parent = path.join(filePath, '..'); 126 if (!(fs.existsSync(parent) && !fs.statSync(parent).isFile())) { 127 mkDir(parent); 128 } 129 fs.mkdirSync(filePath); 130} 131 132function removeDir(path) { 133 if (fs.existsSync(path)) { 134 fs.rmdirSync(path, {recursive: true}); 135 } 136} 137 138function createKitConfigs(fileName, content) { 139 fs.writeFile(fileName, content, err => { 140 if (err) { 141 console.error(err); 142 return; 143 } 144 }); 145} 146 147generateKitConfig(process.argv[SECOND_PARAM], process.argv[THIRD_PARAM], process.argv[FOURTH_PARAM], process.argv[FIFTH_PARAM]); 148