17c804472Sopenharmony_ci/* 27c804472Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 37c804472Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 47c804472Sopenharmony_ci * you may not use this file except in compliance with the License. 57c804472Sopenharmony_ci * You may obtain a copy of the License at 67c804472Sopenharmony_ci * 77c804472Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 87c804472Sopenharmony_ci * 97c804472Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 107c804472Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 117c804472Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 127c804472Sopenharmony_ci * See the License for the specific language governing permissions and 137c804472Sopenharmony_ci * limitations under the License. 147c804472Sopenharmony_ci */ 157c804472Sopenharmony_ci 167c804472Sopenharmony_ciimport fs from 'fs'; 177c804472Sopenharmony_ciimport path from 'path'; 187c804472Sopenharmony_ciimport ts from 'typescript'; 197c804472Sopenharmony_ciimport { ImportElementEntity } from '../declaration-node/importAndExportDeclaration'; 207c804472Sopenharmony_ci 217c804472Sopenharmony_ciexport interface KitImportInfo { 227c804472Sopenharmony_ci fromPath: string; 237c804472Sopenharmony_ci isExport: string[]; 247c804472Sopenharmony_ci isDefaultExport: string; 257c804472Sopenharmony_ci} 267c804472Sopenharmony_ci 277c804472Sopenharmony_ci// kit file map 287c804472Sopenharmony_ciexport const KIT_MAP = new Map<string, KitImportInfo[]>(); 297c804472Sopenharmony_ci 307c804472Sopenharmony_ci/** 317c804472Sopenharmony_ci * get all kit files 327c804472Sopenharmony_ci * @param kitDir root path 337c804472Sopenharmony_ci */ 347c804472Sopenharmony_ciexport function collectAllKitFiles(kitDir: string): void { 357c804472Sopenharmony_ci const arr = fs.readdirSync(kitDir); 367c804472Sopenharmony_ci arr.forEach(value => { 377c804472Sopenharmony_ci const fullPath = path.join(kitDir, value); 387c804472Sopenharmony_ci const stats = fs.statSync(fullPath); 397c804472Sopenharmony_ci if (stats.isDirectory()) { 407c804472Sopenharmony_ci collectAllKitFiles(fullPath); 417c804472Sopenharmony_ci } else { 427c804472Sopenharmony_ci let fileBaseName: string; 437c804472Sopenharmony_ci if (value.endsWith('.d.ts')) { 447c804472Sopenharmony_ci fileBaseName = path.basename(value, '.d.ts'); 457c804472Sopenharmony_ci } 467c804472Sopenharmony_ci if (fileBaseName) { 477c804472Sopenharmony_ci handleKitFile(fullPath, fileBaseName); 487c804472Sopenharmony_ci } 497c804472Sopenharmony_ci } 507c804472Sopenharmony_ci }); 517c804472Sopenharmony_ci} 527c804472Sopenharmony_ci 537c804472Sopenharmony_ci/** 547c804472Sopenharmony_ci * kit file convert to ast 557c804472Sopenharmony_ci * @param kitPath kit file path 567c804472Sopenharmony_ci * @param fileName kit file name 577c804472Sopenharmony_ci */ 587c804472Sopenharmony_cifunction handleKitFile(kitPath: string, fileName: string): void { 597c804472Sopenharmony_ci KIT_MAP.set(fileName, []); 607c804472Sopenharmony_ci 617c804472Sopenharmony_ci const code = fs.readFileSync(kitPath); 627c804472Sopenharmony_ci const sourceFile = ts.createSourceFile(kitPath, code.toString(), ts.ScriptTarget.Latest); 637c804472Sopenharmony_ci sourceFile.forEachChild(node => { 647c804472Sopenharmony_ci if (ts.isImportDeclaration(node)) { 657c804472Sopenharmony_ci KIT_MAP.get(fileName).push(getKitImportDeclaration(node)); 667c804472Sopenharmony_ci } 677c804472Sopenharmony_ci }); 687c804472Sopenharmony_ci} 697c804472Sopenharmony_ci 707c804472Sopenharmony_ci/** 717c804472Sopenharmony_ci * get kit file import declaration 727c804472Sopenharmony_ci * @param importNode kit file import node 737c804472Sopenharmony_ci * @returns KitImportInfo 747c804472Sopenharmony_ci */ 757c804472Sopenharmony_ciexport function getKitImportDeclaration(importNode: ts.ImportDeclaration): KitImportInfo { 767c804472Sopenharmony_ci let isDefaultExport = ''; 777c804472Sopenharmony_ci const isExport = []; 787c804472Sopenharmony_ci const moduleSpecifier = importNode.moduleSpecifier as ts.StringLiteral; 797c804472Sopenharmony_ci const fromPath = moduleSpecifier.text.trim(); 807c804472Sopenharmony_ci const importClause = importNode.importClause; 817c804472Sopenharmony_ci if (importClause !== undefined) { 827c804472Sopenharmony_ci if (importClause.name) { 837c804472Sopenharmony_ci isDefaultExport = importClause.name.text.trim(); 847c804472Sopenharmony_ci } 857c804472Sopenharmony_ci importClause.namedBindings?.forEachChild((node: ts.ImportSpecifier) => { 867c804472Sopenharmony_ci if (node.name) { 877c804472Sopenharmony_ci isExport.push(node.name.text.trim()); 887c804472Sopenharmony_ci } 897c804472Sopenharmony_ci }); 907c804472Sopenharmony_ci } 917c804472Sopenharmony_ci 927c804472Sopenharmony_ci return { 937c804472Sopenharmony_ci fromPath, 947c804472Sopenharmony_ci isDefaultExport, 957c804472Sopenharmony_ci isExport 967c804472Sopenharmony_ci }; 977c804472Sopenharmony_ci} 987c804472Sopenharmony_ci 997c804472Sopenharmony_ci/** 1007c804472Sopenharmony_ci * handle kit file import map info 1017c804472Sopenharmony_ci * @param importEntity import entity data 1027c804472Sopenharmony_ci * @returns ImportElementEntity[] 1037c804472Sopenharmony_ci */ 1047c804472Sopenharmony_ciexport function handleImportKit(importEntity: ImportElementEntity): ImportElementEntity[] { 1057c804472Sopenharmony_ci const importPath = importEntity.importPath.replace(/(\'|\")/g, ''); 1067c804472Sopenharmony_ci if (!importPath.startsWith('@kit.')) { 1077c804472Sopenharmony_ci return []; 1087c804472Sopenharmony_ci } 1097c804472Sopenharmony_ci const importEntities: ImportElementEntity[] = []; 1107c804472Sopenharmony_ci let importElements: string[]; 1117c804472Sopenharmony_ci if (importEntity.importElements.startsWith('{') && importEntity.importElements.endsWith('}')) { 1127c804472Sopenharmony_ci importElements = importEntity.importElements 1137c804472Sopenharmony_ci .substring(1, importEntity.importElements.length - 1) 1147c804472Sopenharmony_ci .split(',') 1157c804472Sopenharmony_ci .map(element => element.trim()); 1167c804472Sopenharmony_ci } 1177c804472Sopenharmony_ci 1187c804472Sopenharmony_ci const kitImportInfos: KitImportInfo[] = KIT_MAP.get(importPath); 1197c804472Sopenharmony_ci if (!kitImportInfos) { 1207c804472Sopenharmony_ci throw new Error(`Can't find kitFileInfos from ${importPath}`); 1217c804472Sopenharmony_ci } 1227c804472Sopenharmony_ci 1237c804472Sopenharmony_ci importElements.forEach(element => { 1247c804472Sopenharmony_ci importEntities.push(getKitImportInfo(kitImportInfos, element, importPath)); 1257c804472Sopenharmony_ci }); 1267c804472Sopenharmony_ci return importEntities; 1277c804472Sopenharmony_ci} 1287c804472Sopenharmony_ci 1297c804472Sopenharmony_ci/** 1307c804472Sopenharmony_ci * get Kit file import map info 1317c804472Sopenharmony_ci * @param kitImportInfos map infos 1327c804472Sopenharmony_ci * @param element import entity info 1337c804472Sopenharmony_ci * @param importPath import file path 1347c804472Sopenharmony_ci * @returns ImportElementEntity 1357c804472Sopenharmony_ci */ 1367c804472Sopenharmony_cifunction getKitImportInfo(kitImportInfos: KitImportInfo[], element: string, importPath: string): ImportElementEntity { 1377c804472Sopenharmony_ci let defaultImport: string; 1387c804472Sopenharmony_ci let commonImport: string; 1397c804472Sopenharmony_ci const kitImportInfo = kitImportInfos.find(kitInfo => { 1407c804472Sopenharmony_ci if (element === kitInfo.isDefaultExport) { 1417c804472Sopenharmony_ci defaultImport = kitInfo.isDefaultExport; 1427c804472Sopenharmony_ci return true; 1437c804472Sopenharmony_ci } else if (kitInfo.isExport.includes(element)) { 1447c804472Sopenharmony_ci commonImport = element; 1457c804472Sopenharmony_ci return true; 1467c804472Sopenharmony_ci } else { 1477c804472Sopenharmony_ci return false; 1487c804472Sopenharmony_ci } 1497c804472Sopenharmony_ci }); 1507c804472Sopenharmony_ci 1517c804472Sopenharmony_ci if (!kitImportInfo) { 1527c804472Sopenharmony_ci throw new Error(`Can't find ${element} from ${importPath}`); 1537c804472Sopenharmony_ci } 1547c804472Sopenharmony_ci 1557c804472Sopenharmony_ci const defaultImportStr = defaultImport ? `${defaultImport}${commonImport ? ',' : ''}` : ''; 1567c804472Sopenharmony_ci const commonImportsStr = commonImport ? `{ ${commonImport} }` : ''; 1577c804472Sopenharmony_ci return { 1587c804472Sopenharmony_ci importElements: `${defaultImportStr} ${commonImportsStr}`, 1597c804472Sopenharmony_ci importPath: kitImportInfo.fromPath 1607c804472Sopenharmony_ci }; 1617c804472Sopenharmony_ci} 162