@@ -92,13 +92,17 @@ namespace ts {
92
92
IsContainerWithLocals = IsContainer | HasLocals
93
93
}
94
94
95
+ const binder = createBinder ( ) ;
96
+
95
97
export function bindSourceFile ( file : SourceFile , options : CompilerOptions ) {
96
98
let start = new Date ( ) . getTime ( ) ;
97
- bindSourceFileWorker ( file , options ) ;
99
+ binder ( file , options ) ;
98
100
bindTime += new Date ( ) . getTime ( ) - start ;
99
101
}
100
102
101
- function bindSourceFileWorker ( file : SourceFile , options : CompilerOptions ) {
103
+ function createBinder ( ) : ( file : SourceFile , options : CompilerOptions ) => void {
104
+ let file : SourceFile ;
105
+ let options : CompilerOptions ;
102
106
let parent : Node ;
103
107
let container : Node ;
104
108
let blockScopeContainer : Node ;
@@ -115,19 +119,37 @@ namespace ts {
115
119
// If this file is an external module, then it is automatically in strict-mode according to
116
120
// ES6. If it is not an external module, then we'll determine if it is in strict mode or
117
121
// not depending on if we see "use strict" in certain places (or if we hit a class/namespace).
118
- let inStrictMode = ! ! file . externalModuleIndicator ;
122
+ let inStrictMode : boolean ;
119
123
120
124
let symbolCount = 0 ;
121
- let Symbol = objectAllocator . getSymbolConstructor ( ) ;
122
- let classifiableNames : Map < string > = { } ;
125
+ let Symbol : { new ( flags : SymbolFlags , name : string ) : Symbol } ;
126
+ let classifiableNames : Map < string > ;
127
+
128
+ function bindSourceFile ( f : SourceFile , opts : CompilerOptions ) {
129
+ file = f ;
130
+ options = opts ;
131
+ inStrictMode = ! ! file . externalModuleIndicator ;
132
+ classifiableNames = { } ;
133
+ Symbol = objectAllocator . getSymbolConstructor ( ) ;
134
+
135
+ if ( ! file . locals ) {
136
+ bind ( file ) ;
137
+ file . symbolCount = symbolCount ;
138
+ file . classifiableNames = classifiableNames ;
139
+ }
123
140
124
- if ( ! file . locals ) {
125
- bind ( file ) ;
126
- file . symbolCount = symbolCount ;
127
- file . classifiableNames = classifiableNames ;
141
+ parent = undefined ;
142
+ container = undefined ;
143
+ blockScopeContainer = undefined ;
144
+ lastContainer = undefined ;
145
+ seenThisKeyword = false ;
146
+ hasExplicitReturn = false ;
147
+ labelStack = undefined ;
148
+ labelIndexMap = undefined ;
149
+ implicitLabels = undefined ;
128
150
}
129
151
130
- return ;
152
+ return bindSourceFile ;
131
153
132
154
function createSymbol ( flags : SymbolFlags , name : string ) : Symbol {
133
155
symbolCount ++ ;
@@ -360,31 +382,23 @@ namespace ts {
360
382
blockScopeContainer . locals = undefined ;
361
383
}
362
384
363
- if ( node . kind === SyntaxKind . InterfaceDeclaration ) {
364
- seenThisKeyword = false ;
365
- bindWithReachabilityChecks ( node ) ;
366
- node . flags = seenThisKeyword ? node . flags | NodeFlags . ContainsThis : node . flags & ~ NodeFlags . ContainsThis ;
367
- }
368
- else {
369
- bindWithReachabilityChecks ( node ) ;
370
- }
371
-
372
- container = saveContainer ;
373
- parent = saveParent ;
374
- blockScopeContainer = savedBlockScopeContainer ;
375
- }
376
-
377
- function bindWithReachabilityChecks ( node : Node ) : void {
378
385
let savedReachabilityState : Reachability ;
379
386
let savedLabelStack : Reachability [ ] ;
380
387
let savedLabels : Map < number > ;
381
388
let savedImplicitLabels : number [ ] ;
382
389
let savedHasExplicitReturn : boolean ;
383
390
391
+ const kind = node . kind ;
392
+ let flags = node . flags ;
393
+
384
394
// reset all reachability check related flags on node (for incremental scenarios)
385
- node . flags &= ~ NodeFlags . ReachabilityCheckFlags ;
395
+ flags &= ~ NodeFlags . ReachabilityCheckFlags ;
396
+
397
+ if ( kind === SyntaxKind . InterfaceDeclaration ) {
398
+ seenThisKeyword = false ;
399
+ }
386
400
387
- let saveState = node . kind === SyntaxKind . SourceFile || node . kind === SyntaxKind . ModuleBlock || isFunctionLike ( node ) ;
401
+ let saveState = kind === SyntaxKind . SourceFile || kind === SyntaxKind . ModuleBlock || isFunctionLikeKind ( kind ) ;
388
402
if ( saveState ) {
389
403
savedReachabilityState = currentReachabilityState ;
390
404
savedLabelStack = labelStack ;
@@ -399,20 +413,30 @@ namespace ts {
399
413
400
414
bindReachableStatement ( node ) ;
401
415
402
- if ( currentReachabilityState === Reachability . Reachable && isFunctionLike ( node ) && nodeIsPresent ( ( < FunctionLikeDeclaration > node ) . body ) ) {
403
- node . flags |= NodeFlags . HasImplicitReturn ;
416
+ if ( currentReachabilityState === Reachability . Reachable && isFunctionLikeKind ( kind ) && nodeIsPresent ( ( < FunctionLikeDeclaration > node ) . body ) ) {
417
+ flags |= NodeFlags . HasImplicitReturn ;
404
418
if ( hasExplicitReturn ) {
405
- node . flags |= NodeFlags . HasExplicitReturn ;
419
+ flags |= NodeFlags . HasExplicitReturn ;
406
420
}
407
421
}
408
422
423
+ if ( kind === SyntaxKind . InterfaceDeclaration ) {
424
+ flags = seenThisKeyword ? flags | NodeFlags . ContainsThis : flags & ~ NodeFlags . ContainsThis ;
425
+ }
426
+
427
+ node . flags = flags ;
428
+
409
429
if ( saveState ) {
410
430
hasExplicitReturn = savedHasExplicitReturn ;
411
431
currentReachabilityState = savedReachabilityState ;
412
432
labelStack = savedLabelStack ;
413
433
labelIndexMap = savedLabels ;
414
434
implicitLabels = savedImplicitLabels ;
415
435
}
436
+
437
+ container = saveContainer ;
438
+ parent = saveParent ;
439
+ blockScopeContainer = savedBlockScopeContainer ;
416
440
}
417
441
418
442
/**
0 commit comments