-
Notifications
You must be signed in to change notification settings - Fork 683
Expand file tree
/
Copy pathAstImport.ts
More file actions
179 lines (158 loc) · 5.17 KB
/
AstImport.ts
File metadata and controls
179 lines (158 loc) · 5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
import { InternalError } from '@rushstack/node-core-library';
import type { AstSymbol } from './AstSymbol';
import { AstSyntheticEntity } from './AstEntity';
/**
* Indicates the import kind for an `AstImport`.
*/
export enum AstImportKind {
/**
* An import statement such as `import X from "y";`.
*/
DefaultImport,
/**
* An import statement such as `import { X } from "y";`.
*/
NamedImport,
/**
* An import statement such as `import * as x from "y";`.
*/
StarImport,
/**
* An import statement such as `import x = require("y");`.
*/
EqualsImport,
/**
* An import statement such as `interface foo { foo: import("bar").a.b.c }`.
*/
ImportType
}
/**
* Constructor parameters for AstImport
*
* @privateRemarks
* Our naming convention is to use I____Parameters for constructor options and
* I____Options for general function options. However the word "parameters" is
* confusingly similar to the terminology for function parameters modeled by API Extractor,
* so we use I____Options for both cases in this code base.
*/
export interface IAstImportOptions {
readonly importKind: AstImportKind;
readonly modulePath: string;
readonly exportName: string;
readonly isTypeOnly: boolean;
}
/**
* For a symbol that was imported from an external package, this tracks the import
* statement that was used to reach it.
*/
export class AstImport extends AstSyntheticEntity {
public readonly importKind: AstImportKind;
/**
* The name of the external package (and possibly module path) that this definition
* was imported from.
*
* Example: "@rushstack/node-core-library/lib/FileSystem"
*/
public readonly modulePath: string;
/**
* The name of the symbol being imported.
*
* @remarks
*
* The name depends on the type of import:
*
* ```ts
* // For AstImportKind.DefaultImport style, exportName would be "X" in this example:
* import X from "y";
*
* // For AstImportKind.NamedImport style, exportName would be "X" in this example:
* import { X } from "y";
*
* // For AstImportKind.StarImport style, exportName would be "x" in this example:
* import * as x from "y";
*
* // For AstImportKind.EqualsImport style, exportName would be "x" in this example:
* import x = require("y");
*
* // For AstImportKind.ImportType style, exportName would be "a.b.c" in this example:
* interface foo { foo: import('bar').a.b.c };
* ```
*/
public readonly exportName: string;
/**
* Whether it is a type-only import, for example:
*
* ```ts
* import type { X } from "y";
* ```
*
* This is set to true ONLY if the type-only form is used in *every* reference to this AstImport.
*/
public isTypeOnlyEverywhere: boolean;
/**
* Whether type errors on the import should be ignored, for example:
*
* ```ts
* /** \@ts-ignore *\/
* import type { X } from "y";
* ```
*
* This is set to true if the ignored form is used in *any* reference to this AstImport.
*/
public isTsIgnored: boolean;
/**
* If this import statement refers to an API from an external package that is tracked by API Extractor
* (according to `PackageMetadataManager.isAedocSupportedFor()`), then this property will return the
* corresponding AstSymbol. Otherwise, it is undefined.
*/
public astSymbol: AstSymbol | undefined;
/**
* If modulePath and exportName are defined, then this is a dictionary key
* that combines them with a colon (":").
*
* Example: "@rushstack/node-core-library/lib/FileSystem:FileSystem"
*/
public readonly key: string;
public constructor(options: IAstImportOptions) {
super();
this.importKind = options.importKind;
this.modulePath = options.modulePath;
this.exportName = options.exportName;
this.isTsIgnored = false;
// We start with this assumption, but it may get changed later if non-type-only import is encountered.
this.isTypeOnlyEverywhere = options.isTypeOnly;
this.key = AstImport.getKey(options);
}
/** {@inheritdoc} */
public get localName(): string {
// abstract
return this.exportName;
}
/**
* Calculates the lookup key used with `AstImport.key`
*/
public static getKey(options: IAstImportOptions): string {
switch (options.importKind) {
case AstImportKind.DefaultImport:
return `${options.modulePath}:${options.exportName}`;
case AstImportKind.NamedImport:
return `${options.modulePath}:${options.exportName}`;
case AstImportKind.StarImport:
return `${options.modulePath}:*`;
case AstImportKind.EqualsImport:
return `${options.modulePath}:=`;
case AstImportKind.ImportType: {
const subKey: string = !options.exportName
? '*' // Equivalent to StarImport
: options.exportName.includes('.') // Equivalent to a named export
? options.exportName.split('.')[0]
: options.exportName;
return `${options.modulePath}:${subKey}`;
}
default:
throw new InternalError('Unknown AstImportKind');
}
}
}