• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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';
22
23export class TransformerManager {
24  private static sInstance: TransformerManager | null = null;
25
26  private static readonly sLoadPath: string = join(__dirname, '../', 'transformers');
27
28  private readonly mTransformers: TransformerFactory<Node>[];
29
30  public static getInstance(): TransformerManager {
31    if (!this.sInstance) {
32      this.sInstance = new TransformerManager();
33    }
34
35    return this.sInstance as TransformerManager;
36  }
37
38  private constructor() {
39    this.mTransformers = [];
40  }
41
42  public loadTransformers(options: IOptions): TransformerFactory<Node>[] {
43    let subFiles: string[] = readdirSync(TransformerManager.sLoadPath);
44    let plugins: TransformPlugin[] = [];
45    for (const subFile of subFiles) {
46      let subPath: string = resolve(TransformerManager.sLoadPath + '/' + subFile);
47      let isDir: boolean = lstatSync(subPath)?.isDirectory();
48      if (!isDir) {
49        continue;
50      }
51
52      let subDir: string[] = readdirSync(subPath);
53      for (const file of subDir) {
54        if (!file.endsWith('.ts')) {
55          continue;
56        }
57        const fileNameNoSuffix = file.lastIndexOf('.d.ts') > -1 ? file.slice(0, file.lastIndexOf('.d.ts')) : file.slice(0, file.lastIndexOf('.ts'));
58        let path: string = join(subPath, fileNameNoSuffix);
59        let module = require(path);
60        let plugin: TransformPlugin = module?.transformerPlugin;
61        if (plugin) {
62          plugins.push(plugin as TransformPlugin);
63        }
64      }
65    }
66
67    plugins.sort((plugin1: TransformPlugin, plugin2: TransformPlugin) => {
68      return plugin1.order - plugin2.order;
69    });
70
71    plugins.forEach((plugin: TransformPlugin) => {
72      let transformerFactory: TransformerFactory<Node> = plugin?.createTransformerFactory(options);
73      let name: string = plugin?.name;
74      if (transformerFactory && name) {
75        this.mTransformers.push(transformerFactory);
76      }
77    });
78
79    return this.mTransformers;
80  }
81}
82