@@ -67,7 +67,8 @@ module ts {
6767
6868 if ( ! file . locals ) {
6969 file . locals = { } ;
70- container = blockScopeContainer = file ;
70+ container = file ;
71+ setBlockScopeContainer ( file , /*cleanLocals*/ false ) ;
7172 bind ( file ) ;
7273 file . symbolCount = symbolCount ;
7374 }
@@ -77,6 +78,13 @@ module ts {
7778 return new Symbol ( flags , name ) ;
7879 }
7980
81+ function setBlockScopeContainer ( node : Node , cleanLocals : boolean ) {
82+ blockScopeContainer = node ;
83+ if ( cleanLocals ) {
84+ blockScopeContainer . locals = undefined ;
85+ }
86+ }
87+
8088 function addDeclarationToSymbol ( symbol : Symbol , node : Declaration , symbolKind : SymbolFlags ) {
8189 symbol . flags |= symbolKind ;
8290 if ( ! symbol . declarations ) symbol . declarations = [ ] ;
@@ -236,7 +244,13 @@ module ts {
236244 }
237245
238246 if ( isBlockScopeContainer ) {
239- blockScopeContainer = node ;
247+ // in incremental scenarios we might reuse nodes that already have locals being allocated
248+ // during the bind step these locals should be dropped to prevent using stale data.
249+ // locals should always be dropped unless they were previously initialized by the binder
250+ // these cases are:
251+ // - node has locals (symbolKind & HasLocals) !== 0
252+ // - node is a source file
253+ setBlockScopeContainer ( node , /*cleanLocals*/ ( symbolKind & SymbolFlags . HasLocals ) === 0 && node . kind !== SyntaxKind . SourceFile ) ;
240254 }
241255
242256 forEachChild ( node , bind ) ;
@@ -342,14 +356,7 @@ module ts {
342356 }
343357
344358 function bindCatchVariableDeclaration ( node : CatchClause ) {
345- var symbol = createSymbol ( SymbolFlags . FunctionScopedVariable , node . name . text || "__missing" ) ;
346- addDeclarationToSymbol ( symbol , node , SymbolFlags . FunctionScopedVariable ) ;
347- var saveParent = parent ;
348- var savedBlockScopeContainer = blockScopeContainer ;
349- parent = blockScopeContainer = node ;
350- forEachChild ( node , bind ) ;
351- parent = saveParent ;
352- blockScopeContainer = savedBlockScopeContainer ;
359+ bindChildren ( node , /*symbolKind:*/ 0 , /*isBlockScopeContainer:*/ true ) ;
353360 }
354361
355362 function bindBlockScopedVariableDeclaration ( node : Declaration ) {
@@ -377,6 +384,7 @@ module ts {
377384
378385 function bind ( node : Node ) {
379386 node . parent = parent ;
387+
380388 switch ( node . kind ) {
381389 case SyntaxKind . TypeParameter :
382390 bindDeclaration ( < Declaration > node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes , /*isBlockScopeContainer*/ false ) ;
@@ -389,7 +397,7 @@ module ts {
389397 if ( isBindingPattern ( ( < Declaration > node ) . name ) ) {
390398 bindChildren ( node , 0 , /*isBlockScopeContainer*/ false ) ;
391399 }
392- else if ( getCombinedNodeFlags ( node ) & NodeFlags . BlockScoped ) {
400+ else if ( isBlockOrCatchScoped ( < Declaration > node ) ) {
393401 bindBlockScopedVariableDeclaration ( < Declaration > node ) ;
394402 }
395403 else {
0 commit comments