1/* 2 * Copyright (c) 2023 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 16import type {Node, TransformerFactory} from 'typescript'; 17import {lstatSync, readdirSync} from 'fs'; 18import {join, resolve} from 'path'; 19 20import type {IOptions} from '../configs/IOptions'; 21import type {TransformPlugin} from './TransformPlugin'; 22import { Extension } from '../common/type'; 23 24export class TransformerManager { 25 private static readonly sLoadPath: string = join(__dirname, '../', 'transformers'); 26 27 private readonly mTransformers: TransformerFactory<Node>[]; 28 29 public constructor(options: IOptions) { 30 this.mTransformers = []; 31 this.loadTransformers(options); 32 } 33 34 public getTransformers(): TransformerFactory<Node>[] { 35 return this.mTransformers; 36 } 37 38 private loadTransformers(options: IOptions): void { 39 let subFiles: string[] = readdirSync(TransformerManager.sLoadPath); 40 let plugins: TransformPlugin[] = []; 41 for (const subFile of subFiles) { 42 let subPath: string = resolve(TransformerManager.sLoadPath + '/' + subFile); 43 let isDir: boolean = lstatSync(subPath)?.isDirectory(); 44 if (!isDir) { 45 continue; 46 } 47 48 let subDir: string[] = readdirSync(subPath); 49 for (const file of subDir) { 50 if (!file.endsWith(Extension.TS)) { 51 continue; 52 } 53 const fileNameNoSuffix = file.lastIndexOf(Extension.DTS) > -1 ? file.slice(0, file.lastIndexOf(Extension.DTS)) : 54 file.slice(0, file.lastIndexOf(Extension.TS)); 55 let path: string = join(subPath, fileNameNoSuffix); 56 let module = require(path); 57 let plugin: TransformPlugin = module?.transformerPlugin; 58 if (plugin) { 59 plugins.push(plugin as TransformPlugin); 60 } 61 } 62 } 63 64 plugins.sort((plugin1: TransformPlugin, plugin2: TransformPlugin) => { 65 return plugin1.order - plugin2.order; 66 }); 67 68 plugins.forEach((plugin: TransformPlugin) => { 69 let transformerFactory: TransformerFactory<Node> = plugin?.createTransformerFactory(options); 70 let name: string = plugin?.name; 71 if (transformerFactory && name) { 72 this.mTransformers.push(transformerFactory); 73 } 74 }); 75 } 76} 77