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