-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
LocalVariable.js
91 lines (78 loc) · 3.33 KB
/
LocalVariable.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import Variable from './Variable';
import VariableReassignmentTracker from './VariableReassignmentTracker';
// To avoid infinite recursions
const MAX_PATH_DEPTH = 7;
export default class LocalVariable extends Variable {
constructor ( name, declarator, init ) {
super( name );
this.isReassigned = false;
this.exportName = null;
this.declarations = new Set( declarator ? [ declarator ] : null );
this.boundExpressions = new VariableReassignmentTracker( init );
}
addDeclaration ( identifier ) {
this.declarations.add( identifier );
}
reassignPath ( path, options ) {
if ( path.length > MAX_PATH_DEPTH ) return;
if ( path.length === 0 ) {
this.isReassigned = true;
}
if ( !options.hasNodeBeenAssignedAtPath( path, this ) ) {
this.boundExpressions.reassignPath( path, options.addAssignedNodeAtPath( path, this ) );
}
}
forEachReturnExpressionWhenCalledAtPath ( path, callOptions, callback, options ) {
if ( path.length > MAX_PATH_DEPTH ) return;
this.boundExpressions.forEachAtPath( path, ( relativePath, node ) =>
!options.hasNodeBeenCalledAtPathWithOptions( relativePath, node, callOptions ) && node
.forEachReturnExpressionWhenCalledAtPath( relativePath, callOptions, callback,
options.addCalledNodeAtPathWithOptions( relativePath, node, callOptions ) ) );
}
getName ( es ) {
if ( es ) return this.name;
if ( !this.isReassigned || !this.exportName ) return this.name;
return `exports.${this.exportName}`;
}
hasEffectsWhenAccessedAtPath ( path, options ) {
return path.length > MAX_PATH_DEPTH
|| this.boundExpressions.someAtPath( path, ( relativePath, node ) =>
relativePath.length > 0
&& !options.hasNodeBeenAccessedAtPath( relativePath, node )
&& node.hasEffectsWhenAccessedAtPath( relativePath, options.addAccessedNodeAtPath( relativePath, node ) ) );
}
hasEffectsWhenAssignedAtPath ( path, options ) {
return this.included
|| path.length > MAX_PATH_DEPTH
|| this.boundExpressions.someAtPath( path, ( relativePath, node ) =>
relativePath.length > 0
&& !options.hasNodeBeenAssignedAtPath( relativePath, node ) && node
.hasEffectsWhenAssignedAtPath( relativePath,
options.addAssignedNodeAtPath( relativePath, node ) ) );
}
hasEffectsWhenCalledAtPath ( path, callOptions, options ) {
return path.length > MAX_PATH_DEPTH
|| (this.included && path.length > 0)
|| this.boundExpressions.someAtPath( path, ( relativePath, node ) =>
!options.hasNodeBeenCalledAtPathWithOptions( relativePath, node, callOptions ) && node
.hasEffectsWhenCalledAtPath( relativePath, callOptions,
options.addCalledNodeAtPathWithOptions( relativePath, node, callOptions ) )
);
}
includeVariable () {
if ( !super.includeVariable() ) return false;
this.declarations.forEach( identifier => identifier.includeInBundle() );
return true;
}
someReturnExpressionWhenCalledAtPath ( path, callOptions, predicateFunction, options ) {
return path.length > MAX_PATH_DEPTH
|| (this.included && path.length > 0)
|| this.boundExpressions.someAtPath( path, ( relativePath, node ) =>
!options.hasNodeBeenCalledAtPathWithOptions( relativePath, node, callOptions ) && node
.someReturnExpressionWhenCalledAtPath( relativePath, callOptions, predicateFunction,
options.addCalledNodeAtPathWithOptions( relativePath, node, callOptions ) ) );
}
toString () {
return this.name;
}
}