-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
ModuleScope.js
75 lines (61 loc) · 2 KB
/
ModuleScope.js
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
import { forOwn } from '../../utils/object.js';
import relativeId from '../../utils/relativeId.js';
import Scope from './Scope.js';
import LocalVariable from '../variables/LocalVariable';
import { UNDEFINED_ASSIGNMENT } from '../values';
export default class ModuleScope extends Scope {
constructor ( module ) {
super( {
isModuleScope: true,
parent: module.bundle.scope
} );
this.module = module;
this.variables.this = new LocalVariable( 'this', null, UNDEFINED_ASSIGNMENT );
}
deshadow ( names ) {
names = new Set( names );
forOwn( this.module.imports, specifier => {
if ( specifier.module.isExternal ) return;
const addDeclaration = declaration => {
if ( declaration.isNamespace && !declaration.isExternal ) {
declaration.module.getExports().forEach( name => {
addDeclaration( declaration.module.traceExport( name ) );
} );
}
names.add( declaration.name );
};
specifier.module.getExports().forEach( name => {
addDeclaration( specifier.module.traceExport( name ) );
} );
if ( specifier.name !== '*' ) {
const declaration = specifier.module.traceExport( specifier.name );
if ( !declaration ) {
this.module.warn( {
code: 'NON_EXISTENT_EXPORT',
name: specifier.name,
source: specifier.module.id,
message: `Non-existent export '${specifier.name}' is imported from ${relativeId( specifier.module.id )}`
}, specifier.specifier.start );
return;
}
const name = declaration.getName( true );
if ( name !== specifier.name ) {
names.add( declaration.getName( true ) );
}
if ( specifier.name !== 'default' && specifier.specifier.imported.name !== specifier.specifier.local.name ) {
names.add( specifier.specifier.imported.name );
}
}
} );
super.deshadow( names );
}
findLexicalBoundary () {
return this;
}
findVariable ( name ) {
if ( this.variables[ name ] ) {
return this.variables[ name ];
}
return this.module.trace( name ) || this.parent.findVariable( name );
}
}