• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 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 { ImportInfo } from '../../core/model/ArkImport';
17import { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata';
18import { BasePrinter, Dump } from './BasePrinter';
19
20export class ImportPrinter extends BasePrinter {
21    infos: ImportInfo[];
22
23    public constructor(infos: ImportInfo[], indent: string = '') {
24        super(indent);
25        this.infos = infos;
26    }
27
28    public getLine(): number {
29        return this.infos[0].getOriginTsPosition().getLineNo();
30    }
31
32    public dump(): string {
33        const commentsMetadata = this.infos[0].getMetadata(ArkMetadataKind.LEADING_COMMENTS);
34        if (commentsMetadata instanceof CommentsMetadata) {
35            this.printComments(commentsMetadata);
36        }
37        let clauseNames: string[] = [];
38        let namedImports: string[] = [];
39
40        for (const info of this.infos) {
41            if (info.getImportType() === 'Identifier') {
42                // sample: import fs from 'fs'
43                clauseNames.push(info.getImportClauseName());
44            } else if (info.getImportType() === 'NamedImports') {
45                // sample: import {xxx} from './yyy'
46                if (info.getNameBeforeAs()) {
47                    namedImports.push(`${info.getNameBeforeAs()} as ${info.getImportClauseName()}`);
48                } else {
49                    namedImports.push(info.getImportClauseName());
50                }
51            } else if (info.getImportType() === 'NamespaceImport') {
52                // sample: import * as ts from 'ohos-typescript'
53                clauseNames.push(`* as ${info.getImportClauseName()}`);
54            } else if (info.getImportType() === 'EqualsImport') {
55                // sample: import mmmm = require('./xxx')
56                this.printer.writeIndent().writeLine(`import ${info.getImportClauseName()} =  require('${info.getFrom() as string}');`);
57            } else {
58                // sample: import '../xxx'
59                this.printer.writeIndent().writeLine(`import '${info.getFrom() as string}';`);
60            }
61        }
62
63        if (namedImports.length > 0) {
64            clauseNames.push(`{${namedImports.join(', ')}}`);
65        }
66
67        this.printer.writeIndent().writeLine(`import ${clauseNames.join(', ')} from '${this.infos[0].getFrom() as string}';`);
68
69        return this.printer.toString();
70    }
71}
72
73function mergeImportInfos(infos: ImportInfo[]): Map<string, ImportInfo[]> {
74    let map = new Map<string, ImportInfo[]>();
75
76    for (let info of infos) {
77        let key = `${info.getOriginTsPosition().getLineNo()}-${info.getFrom()}`;
78        let merge = map.get(key) || [];
79        merge.push(info);
80        map.set(key, merge);
81    }
82
83    return map;
84}
85
86export function printImports(imports: ImportInfo[], indent: string): Dump[] {
87    let mergeImports = mergeImportInfos(imports);
88    let items: Dump[] = [];
89
90    for (const [_, importInfos] of mergeImports) {
91        items.push(new ImportPrinter(importInfos, indent));
92    }
93    return items;
94}
95