Skip to content

Commit 7a28ba2

Browse files
soryy708ljharb
authored andcommittedMar 18, 2024··
[Refactor] ExportMap: separate ExportMap instance from its builder logic
1 parent c77c1a6 commit 7a28ba2

14 files changed

+242
-236
lines changed
 

‎.eslintrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@
229229
{
230230
"files": [
231231
"utils/**", // TODO
232-
"src/ExportMap.js", // TODO
232+
"src/exportMapBuilder.js", // TODO
233233
],
234234
"rules": {
235235
"no-use-before-define": "off",

‎CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1313
- [Docs] `no-extraneous-dependencies`: Make glob pattern description more explicit ([#2944], thanks [@mulztob])
1414
- [`no-unused-modules`]: add console message to help debug [#2866]
1515
- [Refactor] `ExportMap`: make procedures static instead of monkeypatching exportmap ([#2982], thanks [@soryy708])
16+
- [Refactor] `ExportMap`: separate ExportMap instance from its builder logic ([#2985], thanks [@soryy708])
1617

1718
## [2.29.1] - 2023-12-14
1819

@@ -1109,6 +1110,7 @@ for info on changes for earlier releases.
11091110

11101111
[`memo-parser`]: ./memo-parser/README.md
11111112

1113+
[#2985]: https://github.com/import-js/eslint-plugin-import/pull/2985
11121114
[#2982]: https://github.com/import-js/eslint-plugin-import/pull/2982
11131115
[#2944]: https://github.com/import-js/eslint-plugin-import/pull/2944
11141116
[#2942]: https://github.com/import-js/eslint-plugin-import/pull/2942

‎src/exportMap.js

+178
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
export default class ExportMap {
2+
constructor(path) {
3+
this.path = path;
4+
this.namespace = new Map();
5+
// todo: restructure to key on path, value is resolver + map of names
6+
this.reexports = new Map();
7+
/**
8+
* star-exports
9+
* @type {Set<() => ExportMap>}
10+
*/
11+
this.dependencies = new Set();
12+
/**
13+
* dependencies of this module that are not explicitly re-exported
14+
* @type {Map<string, () => ExportMap>}
15+
*/
16+
this.imports = new Map();
17+
this.errors = [];
18+
/**
19+
* type {'ambiguous' | 'Module' | 'Script'}
20+
*/
21+
this.parseGoal = 'ambiguous';
22+
}
23+
24+
get hasDefault() { return this.get('default') != null; } // stronger than this.has
25+
26+
get size() {
27+
let size = this.namespace.size + this.reexports.size;
28+
this.dependencies.forEach((dep) => {
29+
const d = dep();
30+
// CJS / ignored dependencies won't exist (#717)
31+
if (d == null) { return; }
32+
size += d.size;
33+
});
34+
return size;
35+
}
36+
37+
/**
38+
* Note that this does not check explicitly re-exported names for existence
39+
* in the base namespace, but it will expand all `export * from '...'` exports
40+
* if not found in the explicit namespace.
41+
* @param {string} name
42+
* @return {boolean} true if `name` is exported by this module.
43+
*/
44+
has(name) {
45+
if (this.namespace.has(name)) { return true; }
46+
if (this.reexports.has(name)) { return true; }
47+
48+
// default exports must be explicitly re-exported (#328)
49+
if (name !== 'default') {
50+
for (const dep of this.dependencies) {
51+
const innerMap = dep();
52+
53+
// todo: report as unresolved?
54+
if (!innerMap) { continue; }
55+
56+
if (innerMap.has(name)) { return true; }
57+
}
58+
}
59+
60+
return false;
61+
}
62+
63+
/**
64+
* ensure that imported name fully resolves.
65+
* @param {string} name
66+
* @return {{ found: boolean, path: ExportMap[] }}
67+
*/
68+
hasDeep(name) {
69+
if (this.namespace.has(name)) { return { found: true, path: [this] }; }
70+
71+
if (this.reexports.has(name)) {
72+
const reexports = this.reexports.get(name);
73+
const imported = reexports.getImport();
74+
75+
// if import is ignored, return explicit 'null'
76+
if (imported == null) { return { found: true, path: [this] }; }
77+
78+
// safeguard against cycles, only if name matches
79+
if (imported.path === this.path && reexports.local === name) {
80+
return { found: false, path: [this] };
81+
}
82+
83+
const deep = imported.hasDeep(reexports.local);
84+
deep.path.unshift(this);
85+
86+
return deep;
87+
}
88+
89+
// default exports must be explicitly re-exported (#328)
90+
if (name !== 'default') {
91+
for (const dep of this.dependencies) {
92+
const innerMap = dep();
93+
if (innerMap == null) { return { found: true, path: [this] }; }
94+
// todo: report as unresolved?
95+
if (!innerMap) { continue; }
96+
97+
// safeguard against cycles
98+
if (innerMap.path === this.path) { continue; }
99+
100+
const innerValue = innerMap.hasDeep(name);
101+
if (innerValue.found) {
102+
innerValue.path.unshift(this);
103+
return innerValue;
104+
}
105+
}
106+
}
107+
108+
return { found: false, path: [this] };
109+
}
110+
111+
get(name) {
112+
if (this.namespace.has(name)) { return this.namespace.get(name); }
113+
114+
if (this.reexports.has(name)) {
115+
const reexports = this.reexports.get(name);
116+
const imported = reexports.getImport();
117+
118+
// if import is ignored, return explicit 'null'
119+
if (imported == null) { return null; }
120+
121+
// safeguard against cycles, only if name matches
122+
if (imported.path === this.path && reexports.local === name) { return undefined; }
123+
124+
return imported.get(reexports.local);
125+
}
126+
127+
// default exports must be explicitly re-exported (#328)
128+
if (name !== 'default') {
129+
for (const dep of this.dependencies) {
130+
const innerMap = dep();
131+
// todo: report as unresolved?
132+
if (!innerMap) { continue; }
133+
134+
// safeguard against cycles
135+
if (innerMap.path === this.path) { continue; }
136+
137+
const innerValue = innerMap.get(name);
138+
if (innerValue !== undefined) { return innerValue; }
139+
}
140+
}
141+
142+
return undefined;
143+
}
144+
145+
forEach(callback, thisArg) {
146+
this.namespace.forEach((v, n) => { callback.call(thisArg, v, n, this); });
147+
148+
this.reexports.forEach((reexports, name) => {
149+
const reexported = reexports.getImport();
150+
// can't look up meta for ignored re-exports (#348)
151+
callback.call(thisArg, reexported && reexported.get(reexports.local), name, this);
152+
});
153+
154+
this.dependencies.forEach((dep) => {
155+
const d = dep();
156+
// CJS / ignored dependencies won't exist (#717)
157+
if (d == null) { return; }
158+
159+
d.forEach((v, n) => {
160+
if (n !== 'default') {
161+
callback.call(thisArg, v, n, this);
162+
}
163+
});
164+
});
165+
}
166+
167+
// todo: keys, values, entries?
168+
169+
reportErrors(context, declaration) {
170+
const msg = this.errors
171+
.map((e) => `${e.message} (${e.lineNumber}:${e.column})`)
172+
.join(', ');
173+
context.report({
174+
node: declaration.source,
175+
message: `Parse errors in imported module '${declaration.source.value}': ${msg}`,
176+
});
177+
}
178+
}

‎src/ExportMap.js ‎src/exportMapBuilder.js

+6-182
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import * as unambiguous from 'eslint-module-utils/unambiguous';
1818
import { tsConfigLoader } from 'tsconfig-paths/lib/tsconfig-loader';
1919

2020
import includes from 'array-includes';
21+
import ExportMap from './exportMap';
2122

2223
let ts;
2324

@@ -117,189 +118,12 @@ const availableDocStyleParsers = {
117118

118119
const supportedImportTypes = new Set(['ImportDefaultSpecifier', 'ImportNamespaceSpecifier']);
119120

120-
export default class ExportMap {
121-
constructor(path) {
122-
this.path = path;
123-
this.namespace = new Map();
124-
// todo: restructure to key on path, value is resolver + map of names
125-
this.reexports = new Map();
126-
/**
127-
* star-exports
128-
* @type {Set} of () => ExportMap
129-
*/
130-
this.dependencies = new Set();
131-
/**
132-
* dependencies of this module that are not explicitly re-exported
133-
* @type {Map} from path = () => ExportMap
134-
*/
135-
this.imports = new Map();
136-
this.errors = [];
137-
/**
138-
* type {'ambiguous' | 'Module' | 'Script'}
139-
*/
140-
this.parseGoal = 'ambiguous';
141-
}
142-
143-
get hasDefault() { return this.get('default') != null; } // stronger than this.has
144-
145-
get size() {
146-
let size = this.namespace.size + this.reexports.size;
147-
this.dependencies.forEach((dep) => {
148-
const d = dep();
149-
// CJS / ignored dependencies won't exist (#717)
150-
if (d == null) { return; }
151-
size += d.size;
152-
});
153-
return size;
154-
}
155-
156-
/**
157-
* Note that this does not check explicitly re-exported names for existence
158-
* in the base namespace, but it will expand all `export * from '...'` exports
159-
* if not found in the explicit namespace.
160-
* @param {string} name
161-
* @return {Boolean} true if `name` is exported by this module.
162-
*/
163-
has(name) {
164-
if (this.namespace.has(name)) { return true; }
165-
if (this.reexports.has(name)) { return true; }
166-
167-
// default exports must be explicitly re-exported (#328)
168-
if (name !== 'default') {
169-
for (const dep of this.dependencies) {
170-
const innerMap = dep();
171-
172-
// todo: report as unresolved?
173-
if (!innerMap) { continue; }
174-
175-
if (innerMap.has(name)) { return true; }
176-
}
177-
}
178-
179-
return false;
180-
}
181-
182-
/**
183-
* ensure that imported name fully resolves.
184-
* @param {string} name
185-
* @return {{ found: boolean, path: ExportMap[] }}
186-
*/
187-
hasDeep(name) {
188-
if (this.namespace.has(name)) { return { found: true, path: [this] }; }
189-
190-
if (this.reexports.has(name)) {
191-
const reexports = this.reexports.get(name);
192-
const imported = reexports.getImport();
193-
194-
// if import is ignored, return explicit 'null'
195-
if (imported == null) { return { found: true, path: [this] }; }
196-
197-
// safeguard against cycles, only if name matches
198-
if (imported.path === this.path && reexports.local === name) {
199-
return { found: false, path: [this] };
200-
}
201-
202-
const deep = imported.hasDeep(reexports.local);
203-
deep.path.unshift(this);
204-
205-
return deep;
206-
}
207-
208-
// default exports must be explicitly re-exported (#328)
209-
if (name !== 'default') {
210-
for (const dep of this.dependencies) {
211-
const innerMap = dep();
212-
if (innerMap == null) { return { found: true, path: [this] }; }
213-
// todo: report as unresolved?
214-
if (!innerMap) { continue; }
215-
216-
// safeguard against cycles
217-
if (innerMap.path === this.path) { continue; }
218-
219-
const innerValue = innerMap.hasDeep(name);
220-
if (innerValue.found) {
221-
innerValue.path.unshift(this);
222-
return innerValue;
223-
}
224-
}
225-
}
226-
227-
return { found: false, path: [this] };
228-
}
229-
230-
get(name) {
231-
if (this.namespace.has(name)) { return this.namespace.get(name); }
232-
233-
if (this.reexports.has(name)) {
234-
const reexports = this.reexports.get(name);
235-
const imported = reexports.getImport();
236-
237-
// if import is ignored, return explicit 'null'
238-
if (imported == null) { return null; }
239-
240-
// safeguard against cycles, only if name matches
241-
if (imported.path === this.path && reexports.local === name) { return undefined; }
242-
243-
return imported.get(reexports.local);
244-
}
245-
246-
// default exports must be explicitly re-exported (#328)
247-
if (name !== 'default') {
248-
for (const dep of this.dependencies) {
249-
const innerMap = dep();
250-
// todo: report as unresolved?
251-
if (!innerMap) { continue; }
252-
253-
// safeguard against cycles
254-
if (innerMap.path === this.path) { continue; }
255-
256-
const innerValue = innerMap.get(name);
257-
if (innerValue !== undefined) { return innerValue; }
258-
}
259-
}
260-
261-
return undefined;
262-
}
263-
264-
forEach(callback, thisArg) {
265-
this.namespace.forEach((v, n) => { callback.call(thisArg, v, n, this); });
266-
267-
this.reexports.forEach((reexports, name) => {
268-
const reexported = reexports.getImport();
269-
// can't look up meta for ignored re-exports (#348)
270-
callback.call(thisArg, reexported && reexported.get(reexports.local), name, this);
271-
});
272-
273-
this.dependencies.forEach((dep) => {
274-
const d = dep();
275-
// CJS / ignored dependencies won't exist (#717)
276-
if (d == null) { return; }
277-
278-
d.forEach((v, n) => {
279-
if (n !== 'default') {
280-
callback.call(thisArg, v, n, this);
281-
}
282-
});
283-
});
284-
}
285-
286-
// todo: keys, values, entries?
287-
288-
reportErrors(context, declaration) {
289-
const msg = this.errors
290-
.map((e) => `${e.message} (${e.lineNumber}:${e.column})`)
291-
.join(', ');
292-
context.report({
293-
node: declaration.source,
294-
message: `Parse errors in imported module '${declaration.source.value}': ${msg}`,
295-
});
296-
}
297-
121+
export default class ExportMapBuilder {
298122
static get(source, context) {
299123
const path = resolve(source, context);
300124
if (path == null) { return null; }
301125

302-
return ExportMap.for(childContext(path, context));
126+
return ExportMapBuilder.for(childContext(path, context));
303127
}
304128

305129
static for(context) {
@@ -343,7 +167,7 @@ export default class ExportMap {
343167
}
344168

345169
log('cache miss', cacheKey, 'for path', path);
346-
exportMap = ExportMap.parse(path, content, context);
170+
exportMap = ExportMapBuilder.parse(path, content, context);
347171

348172
// ambiguous modules return null
349173
if (exportMap == null) {
@@ -447,7 +271,7 @@ export default class ExportMap {
447271
function resolveImport(value) {
448272
const rp = remotePath(value);
449273
if (rp == null) { return null; }
450-
return ExportMap.for(childContext(rp, context));
274+
return ExportMapBuilder.for(childContext(rp, context));
451275
}
452276

453277
function getNamespace(identifier) {
@@ -738,7 +562,7 @@ export default class ExportMap {
738562
* caused memory leaks. See #1266.
739563
*/
740564
function thunkFor(p, context) {
741-
return () => ExportMap.for(childContext(p, context));
565+
return () => ExportMapBuilder.for(childContext(p, context));
742566
}
743567

744568
/**

‎src/rules/default.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Exports from '../ExportMap';
1+
import ExportMapBuilder from '../exportMapBuilder';
22
import docsUrl from '../docsUrl';
33

44
module.exports = {
@@ -19,7 +19,7 @@ module.exports = {
1919
);
2020

2121
if (!defaultSpecifier) { return; }
22-
const imports = Exports.get(node.source.value, context);
22+
const imports = ExportMapBuilder.get(node.source.value, context);
2323
if (imports == null) { return; }
2424

2525
if (imports.errors.length) {

‎src/rules/export.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import ExportMap, { recursivePatternCapture } from '../ExportMap';
1+
import ExportMapBuilder, { recursivePatternCapture } from '../exportMapBuilder';
22
import docsUrl from '../docsUrl';
33
import includes from 'array-includes';
44
import flatMap from 'array.prototype.flatmap';
@@ -197,7 +197,7 @@ module.exports = {
197197
// `export * as X from 'path'` does not conflict
198198
if (node.exported && node.exported.name) { return; }
199199

200-
const remoteExports = ExportMap.get(node.source.value, context);
200+
const remoteExports = ExportMapBuilder.get(node.source.value, context);
201201
if (remoteExports == null) { return; }
202202

203203
if (remoteExports.errors.length) {

‎src/rules/named.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as path from 'path';
2-
import Exports from '../ExportMap';
2+
import ExportMapBuilder from '../exportMapBuilder';
33
import docsUrl from '../docsUrl';
44

55
module.exports = {
@@ -41,7 +41,7 @@ module.exports = {
4141
return; // no named imports/exports
4242
}
4343

44-
const imports = Exports.get(node.source.value, context);
44+
const imports = ExportMapBuilder.get(node.source.value, context);
4545
if (imports == null || imports.parseGoal === 'ambiguous') {
4646
return;
4747
}
@@ -93,7 +93,7 @@ module.exports = {
9393
const call = node.init;
9494
const [source] = call.arguments;
9595
const variableImports = node.id.properties;
96-
const variableExports = Exports.get(source.value, context);
96+
const variableExports = ExportMapBuilder.get(source.value, context);
9797

9898
if (
9999
// return if it's not a commonjs require statement

‎src/rules/namespace.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import declaredScope from 'eslint-module-utils/declaredScope';
2-
import Exports from '../ExportMap';
2+
import ExportMapBuilder from '../exportMapBuilder';
3+
import ExportMap from '../exportMap';
34
import importDeclaration from '../importDeclaration';
45
import docsUrl from '../docsUrl';
56

@@ -8,7 +9,7 @@ function processBodyStatement(context, namespaces, declaration) {
89

910
if (declaration.specifiers.length === 0) { return; }
1011

11-
const imports = Exports.get(declaration.source.value, context);
12+
const imports = ExportMapBuilder.get(declaration.source.value, context);
1213
if (imports == null) { return null; }
1314

1415
if (imports.errors.length > 0) {
@@ -88,7 +89,7 @@ module.exports = {
8889
ExportNamespaceSpecifier(namespace) {
8990
const declaration = importDeclaration(context);
9091

91-
const imports = Exports.get(declaration.source.value, context);
92+
const imports = ExportMapBuilder.get(declaration.source.value, context);
9293
if (imports == null) { return null; }
9394

9495
if (imports.errors.length) {
@@ -122,7 +123,7 @@ module.exports = {
122123
let namespace = namespaces.get(dereference.object.name);
123124
const namepath = [dereference.object.name];
124125
// while property is namespace and parent is member expression, keep validating
125-
while (namespace instanceof Exports && dereference.type === 'MemberExpression') {
126+
while (namespace instanceof ExportMap && dereference.type === 'MemberExpression') {
126127
if (dereference.computed) {
127128
if (!allowComputed) {
128129
context.report(
@@ -161,7 +162,7 @@ module.exports = {
161162

162163
// DFS traverse child namespaces
163164
function testKey(pattern, namespace, path = [init.name]) {
164-
if (!(namespace instanceof Exports)) { return; }
165+
if (!(namespace instanceof ExportMap)) { return; }
165166

166167
if (pattern.type !== 'ObjectPattern') { return; }
167168

‎src/rules/no-cycle.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import resolve from 'eslint-module-utils/resolve';
7-
import Exports from '../ExportMap';
7+
import ExportMapBuilder from '../exportMapBuilder';
88
import { isExternalModule } from '../core/importType';
99
import moduleVisitor, { makeOptionsSchema } from 'eslint-module-utils/moduleVisitor';
1010
import docsUrl from '../docsUrl';
@@ -88,7 +88,7 @@ module.exports = {
8888
return; // ignore type imports
8989
}
9090

91-
const imported = Exports.get(sourceNode.value, context);
91+
const imported = ExportMapBuilder.get(sourceNode.value, context);
9292

9393
if (imported == null) {
9494
return; // no-unresolved territory

‎src/rules/no-deprecated.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import declaredScope from 'eslint-module-utils/declaredScope';
2-
import Exports from '../ExportMap';
2+
import ExportMapBuilder from '../exportMapBuilder';
3+
import ExportMap from '../exportMap';
34
import docsUrl from '../docsUrl';
45

56
function message(deprecation) {
@@ -31,7 +32,7 @@ module.exports = {
3132
if (node.type !== 'ImportDeclaration') { return; }
3233
if (node.source == null) { return; } // local export, ignore
3334

34-
const imports = Exports.get(node.source.value, context);
35+
const imports = ExportMapBuilder.get(node.source.value, context);
3536
if (imports == null) { return; }
3637

3738
const moduleDeprecation = imports.doc && imports.doc.tags.find((t) => t.title === 'deprecated');
@@ -114,7 +115,7 @@ module.exports = {
114115
let namespace = namespaces.get(dereference.object.name);
115116
const namepath = [dereference.object.name];
116117
// while property is namespace and parent is member expression, keep validating
117-
while (namespace instanceof Exports && dereference.type === 'MemberExpression') {
118+
while (namespace instanceof ExportMap && dereference.type === 'MemberExpression') {
118119
// ignore computed parts for now
119120
if (dereference.computed) { return; }
120121

‎src/rules/no-named-as-default-member.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @copyright 2016 Desmond Brand. All rights reserved.
55
* See LICENSE in root directory for full license.
66
*/
7-
import Exports from '../ExportMap';
7+
import ExportMapBuilder from '../exportMapBuilder';
88
import importDeclaration from '../importDeclaration';
99
import docsUrl from '../docsUrl';
1010

@@ -36,7 +36,7 @@ module.exports = {
3636
return {
3737
ImportDefaultSpecifier(node) {
3838
const declaration = importDeclaration(context);
39-
const exportMap = Exports.get(declaration.source.value, context);
39+
const exportMap = ExportMapBuilder.get(declaration.source.value, context);
4040
if (exportMap == null) { return; }
4141

4242
if (exportMap.errors.length) {

‎src/rules/no-named-as-default.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Exports from '../ExportMap';
1+
import ExportMapBuilder from '../exportMapBuilder';
22
import importDeclaration from '../importDeclaration';
33
import docsUrl from '../docsUrl';
44

@@ -20,7 +20,7 @@ module.exports = {
2020

2121
const declaration = importDeclaration(context);
2222

23-
const imports = Exports.get(declaration.source.value, context);
23+
const imports = ExportMapBuilder.get(declaration.source.value, context);
2424
if (imports == null) { return; }
2525

2626
if (imports.errors.length) {

‎src/rules/no-unused-modules.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import values from 'object.values';
1313
import includes from 'array-includes';
1414
import flatMap from 'array.prototype.flatmap';
1515

16-
import Exports, { recursivePatternCapture } from '../ExportMap';
16+
import ExportMapBuilder, { recursivePatternCapture } from '../exportMapBuilder';
1717
import docsUrl from '../docsUrl';
1818

1919
let FileEnumerator;
@@ -194,7 +194,7 @@ const prepareImportsAndExports = (srcFiles, context) => {
194194
srcFiles.forEach((file) => {
195195
const exports = new Map();
196196
const imports = new Map();
197-
const currentExports = Exports.get(file, context);
197+
const currentExports = ExportMapBuilder.get(file, context);
198198
if (currentExports) {
199199
const {
200200
dependencies,

‎tests/src/core/getExports.js

+30-30
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import sinon from 'sinon';
44
import eslintPkg from 'eslint/package.json';
55
import typescriptPkg from 'typescript/package.json';
66
import * as tsConfigLoader from 'tsconfig-paths/lib/tsconfig-loader';
7-
import ExportMap from '../../../src/ExportMap';
7+
import ExportMapBuilder from '../../../src/exportMapBuilder';
88

99
import * as fs from 'fs';
1010

@@ -28,7 +28,7 @@ describe('ExportMap', function () {
2828
it('handles ExportAllDeclaration', function () {
2929
let imports;
3030
expect(function () {
31-
imports = ExportMap.get('./export-all', fakeContext);
31+
imports = ExportMapBuilder.get('./export-all', fakeContext);
3232
}).not.to.throw(Error);
3333

3434
expect(imports).to.exist;
@@ -37,41 +37,41 @@ describe('ExportMap', function () {
3737
});
3838

3939
it('returns a cached copy on subsequent requests', function () {
40-
expect(ExportMap.get('./named-exports', fakeContext))
41-
.to.exist.and.equal(ExportMap.get('./named-exports', fakeContext));
40+
expect(ExportMapBuilder.get('./named-exports', fakeContext))
41+
.to.exist.and.equal(ExportMapBuilder.get('./named-exports', fakeContext));
4242
});
4343

4444
it('does not return a cached copy after modification', (done) => {
45-
const firstAccess = ExportMap.get('./mutator', fakeContext);
45+
const firstAccess = ExportMapBuilder.get('./mutator', fakeContext);
4646
expect(firstAccess).to.exist;
4747

4848
// mutate (update modified time)
4949
const newDate = new Date();
5050
fs.utimes(getFilename('mutator.js'), newDate, newDate, (error) => {
5151
expect(error).not.to.exist;
52-
expect(ExportMap.get('./mutator', fakeContext)).not.to.equal(firstAccess);
52+
expect(ExportMapBuilder.get('./mutator', fakeContext)).not.to.equal(firstAccess);
5353
done();
5454
});
5555
});
5656

5757
it('does not return a cached copy with different settings', () => {
58-
const firstAccess = ExportMap.get('./named-exports', fakeContext);
58+
const firstAccess = ExportMapBuilder.get('./named-exports', fakeContext);
5959
expect(firstAccess).to.exist;
6060

6161
const differentSettings = {
6262
...fakeContext,
6363
parserPath: 'espree',
6464
};
6565

66-
expect(ExportMap.get('./named-exports', differentSettings))
66+
expect(ExportMapBuilder.get('./named-exports', differentSettings))
6767
.to.exist.and
6868
.not.to.equal(firstAccess);
6969
});
7070

7171
it('does not throw for a missing file', function () {
7272
let imports;
7373
expect(function () {
74-
imports = ExportMap.get('./does-not-exist', fakeContext);
74+
imports = ExportMapBuilder.get('./does-not-exist', fakeContext);
7575
}).not.to.throw(Error);
7676

7777
expect(imports).not.to.exist;
@@ -81,7 +81,7 @@ describe('ExportMap', function () {
8181
it('exports explicit names for a missing file in exports', function () {
8282
let imports;
8383
expect(function () {
84-
imports = ExportMap.get('./exports-missing', fakeContext);
84+
imports = ExportMapBuilder.get('./exports-missing', fakeContext);
8585
}).not.to.throw(Error);
8686

8787
expect(imports).to.exist;
@@ -92,7 +92,7 @@ describe('ExportMap', function () {
9292
it('finds exports for an ES7 module with babel-eslint', function () {
9393
const path = getFilename('jsx/FooES7.js');
9494
const contents = fs.readFileSync(path, { encoding: 'utf8' });
95-
const imports = ExportMap.parse(
95+
const imports = ExportMapBuilder.parse(
9696
path,
9797
contents,
9898
{ parserPath: 'babel-eslint', settings: {} },
@@ -112,7 +112,7 @@ describe('ExportMap', function () {
112112
before('parse file', function () {
113113
const path = getFilename('deprecated.js');
114114
const contents = fs.readFileSync(path, { encoding: 'utf8' }).replace(/[\r]\n/g, lineEnding);
115-
imports = ExportMap.parse(path, contents, parseContext);
115+
imports = ExportMapBuilder.parse(path, contents, parseContext);
116116

117117
// sanity checks
118118
expect(imports.errors).to.be.empty;
@@ -181,7 +181,7 @@ describe('ExportMap', function () {
181181
before('parse file', function () {
182182
const path = getFilename('deprecated-file.js');
183183
const contents = fs.readFileSync(path, { encoding: 'utf8' });
184-
imports = ExportMap.parse(path, contents, parseContext);
184+
imports = ExportMapBuilder.parse(path, contents, parseContext);
185185

186186
// sanity checks
187187
expect(imports.errors).to.be.empty;
@@ -243,7 +243,7 @@ describe('ExportMap', function () {
243243
it('works with espree & traditional namespace exports', function () {
244244
const path = getFilename('deep/a.js');
245245
const contents = fs.readFileSync(path, { encoding: 'utf8' });
246-
const a = ExportMap.parse(path, contents, espreeContext);
246+
const a = ExportMapBuilder.parse(path, contents, espreeContext);
247247
expect(a.errors).to.be.empty;
248248
expect(a.get('b').namespace).to.exist;
249249
expect(a.get('b').namespace.has('c')).to.be.true;
@@ -252,7 +252,7 @@ describe('ExportMap', function () {
252252
it('captures namespace exported as default', function () {
253253
const path = getFilename('deep/default.js');
254254
const contents = fs.readFileSync(path, { encoding: 'utf8' });
255-
const def = ExportMap.parse(path, contents, espreeContext);
255+
const def = ExportMapBuilder.parse(path, contents, espreeContext);
256256
expect(def.errors).to.be.empty;
257257
expect(def.get('default').namespace).to.exist;
258258
expect(def.get('default').namespace.has('c')).to.be.true;
@@ -261,7 +261,7 @@ describe('ExportMap', function () {
261261
it('works with babel-eslint & ES7 namespace exports', function () {
262262
const path = getFilename('deep-es7/a.js');
263263
const contents = fs.readFileSync(path, { encoding: 'utf8' });
264-
const a = ExportMap.parse(path, contents, babelContext);
264+
const a = ExportMapBuilder.parse(path, contents, babelContext);
265265
expect(a.errors).to.be.empty;
266266
expect(a.get('b').namespace).to.exist;
267267
expect(a.get('b').namespace.has('c')).to.be.true;
@@ -278,7 +278,7 @@ describe('ExportMap', function () {
278278

279279
const path = getFilename('deep/cache-1.js');
280280
const contents = fs.readFileSync(path, { encoding: 'utf8' });
281-
a = ExportMap.parse(path, contents, espreeContext);
281+
a = ExportMapBuilder.parse(path, contents, espreeContext);
282282
expect(a.errors).to.be.empty;
283283

284284
expect(a.get('b').namespace).to.exist;
@@ -304,25 +304,25 @@ describe('ExportMap', function () {
304304
context('Map API', function () {
305305
context('#size', function () {
306306

307-
it('counts the names', () => expect(ExportMap.get('./named-exports', fakeContext))
307+
it('counts the names', () => expect(ExportMapBuilder.get('./named-exports', fakeContext))
308308
.to.have.property('size', 12));
309309

310-
it('includes exported namespace size', () => expect(ExportMap.get('./export-all', fakeContext))
310+
it('includes exported namespace size', () => expect(ExportMapBuilder.get('./export-all', fakeContext))
311311
.to.have.property('size', 1));
312312

313313
});
314314
});
315315

316316
context('issue #210: self-reference', function () {
317317
it(`doesn't crash`, function () {
318-
expect(() => ExportMap.get('./narcissist', fakeContext)).not.to.throw(Error);
318+
expect(() => ExportMapBuilder.get('./narcissist', fakeContext)).not.to.throw(Error);
319319
});
320320
it(`'has' circular reference`, function () {
321-
expect(ExportMap.get('./narcissist', fakeContext))
321+
expect(ExportMapBuilder.get('./narcissist', fakeContext))
322322
.to.exist.and.satisfy((m) => m.has('soGreat'));
323323
});
324324
it(`can 'get' circular reference`, function () {
325-
expect(ExportMap.get('./narcissist', fakeContext))
325+
expect(ExportMapBuilder.get('./narcissist', fakeContext))
326326
.to.exist.and.satisfy((m) => m.get('soGreat') != null);
327327
});
328328
});
@@ -335,7 +335,7 @@ describe('ExportMap', function () {
335335

336336
let imports;
337337
before('load imports', function () {
338-
imports = ExportMap.get('./typescript.ts', context);
338+
imports = ExportMapBuilder.get('./typescript.ts', context);
339339
});
340340

341341
it('returns nothing for a TypeScript file', function () {
@@ -372,7 +372,7 @@ describe('ExportMap', function () {
372372
before('load imports', function () {
373373
this.timeout(20e3); // takes a long time :shrug:
374374
sinon.spy(tsConfigLoader, 'tsConfigLoader');
375-
imports = ExportMap.get('./typescript.ts', context);
375+
imports = ExportMapBuilder.get('./typescript.ts', context);
376376
});
377377
after('clear spies', function () {
378378
tsConfigLoader.tsConfigLoader.restore();
@@ -414,9 +414,9 @@ describe('ExportMap', function () {
414414
},
415415
};
416416
expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(0);
417-
ExportMap.parse('./baz.ts', 'export const baz = 5', customContext);
417+
ExportMapBuilder.parse('./baz.ts', 'export const baz = 5', customContext);
418418
expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(1);
419-
ExportMap.parse('./baz.ts', 'export const baz = 5', customContext);
419+
ExportMapBuilder.parse('./baz.ts', 'export const baz = 5', customContext);
420420
expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(1);
421421

422422
const differentContext = {
@@ -426,17 +426,17 @@ describe('ExportMap', function () {
426426
},
427427
};
428428

429-
ExportMap.parse('./baz.ts', 'export const baz = 5', differentContext);
429+
ExportMapBuilder.parse('./baz.ts', 'export const baz = 5', differentContext);
430430
expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(2);
431431
});
432432

433433
it('should cache after parsing for an ambiguous module', function () {
434434
const source = './typescript-declare-module.ts';
435-
const parseSpy = sinon.spy(ExportMap, 'parse');
435+
const parseSpy = sinon.spy(ExportMapBuilder, 'parse');
436436

437-
expect(ExportMap.get(source, context)).to.be.null;
437+
expect(ExportMapBuilder.get(source, context)).to.be.null;
438438

439-
ExportMap.get(source, context);
439+
ExportMapBuilder.get(source, context);
440440

441441
expect(parseSpy.callCount).to.equal(1);
442442

0 commit comments

Comments
 (0)
Please sign in to comment.