@@ -31,13 +31,14 @@ module ts {
3131
3232 var parent : Node ;
3333 var container : Declaration ;
34+ var blockScopeContainer : Node ;
3435 var lastContainer : Declaration ;
3536 var symbolCount = 0 ;
3637 var Symbol = objectAllocator . getSymbolConstructor ( ) ;
3738
3839 if ( ! file . locals ) {
3940 file . locals = { } ;
40- container = file ;
41+ container = blockScopeContainer = file ;
4142 bind ( file ) ;
4243 file . symbolCount = symbolCount ;
4344 }
@@ -167,12 +168,13 @@ module ts {
167168
168169 // All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function
169170 // in the type checker to validate that the local name used for a container is unique.
170- function bindChildren ( node : Declaration , symbolKind : SymbolFlags ) {
171+ function bindChildren ( node : Declaration , symbolKind : SymbolFlags , isBlockScopeContainer : boolean ) {
171172 if ( symbolKind & SymbolFlags . HasLocals ) {
172173 node . locals = { } ;
173174 }
174175 var saveParent = parent ;
175176 var saveContainer = container ;
177+ var savedBlockScopeContainer = blockScopeContainer ;
176178 parent = node ;
177179 if ( symbolKind & SymbolFlags . IsContainer ) {
178180 container = node ;
@@ -184,12 +186,16 @@ module ts {
184186 lastContainer = container ;
185187 }
186188 }
189+ if ( isBlockScopeContainer ) {
190+ blockScopeContainer = node ;
191+ }
187192 forEachChild ( node , bind ) ;
188193 container = saveContainer ;
189194 parent = saveParent ;
195+ blockScopeContainer = savedBlockScopeContainer ;
190196 }
191197
192- function bindDeclaration ( node : Declaration , symbolKind : SymbolFlags , symbolExcludes : SymbolFlags ) {
198+ function bindDeclaration ( node : Declaration , symbolKind : SymbolFlags , symbolExcludes : SymbolFlags , isBlockScopeContainer : boolean ) {
193199 switch ( container . kind ) {
194200 case SyntaxKind . ModuleDeclaration :
195201 declareModuleMember ( node , symbolKind , symbolExcludes ) ;
@@ -225,126 +231,168 @@ module ts {
225231 declareSymbol ( container . symbol . exports , container . symbol , node , symbolKind , symbolExcludes ) ;
226232 break ;
227233 }
228- bindChildren ( node , symbolKind ) ;
234+ bindChildren ( node , symbolKind , isBlockScopeContainer ) ;
229235 }
230236
231237 function bindConstructorDeclaration ( node : ConstructorDeclaration ) {
232- bindDeclaration ( node , SymbolFlags . Constructor , 0 ) ;
238+ bindDeclaration ( node , SymbolFlags . Constructor , 0 , /*isBlockScopeContainer*/ true ) ;
233239 forEach ( node . parameters , p => {
234240 if ( p . flags & ( NodeFlags . Public | NodeFlags . Private | NodeFlags . Protected ) ) {
235- bindDeclaration ( p , SymbolFlags . Property , SymbolFlags . PropertyExcludes ) ;
241+ bindDeclaration ( p , SymbolFlags . Property , SymbolFlags . PropertyExcludes , /*isBlockScopeContainer*/ false ) ;
236242 }
237243 } ) ;
238244 }
239245
240246 function bindModuleDeclaration ( node : ModuleDeclaration ) {
241247 if ( node . name . kind === SyntaxKind . StringLiteral ) {
242- bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes ) ;
248+ bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes , /*isBlockScopeContainer*/ true ) ;
243249 }
244250 else if ( isInstantiated ( node ) ) {
245- bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes ) ;
251+ bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes , /*isBlockScopeContainer*/ true ) ;
246252 }
247253 else {
248- bindDeclaration ( node , SymbolFlags . NamespaceModule , SymbolFlags . NamespaceModuleExcludes ) ;
254+ bindDeclaration ( node , SymbolFlags . NamespaceModule , SymbolFlags . NamespaceModuleExcludes , /*isBlockScopeContainer*/ true ) ;
249255 }
250256 }
251257
252- function bindAnonymousDeclaration ( node : Node , symbolKind : SymbolFlags , name : string ) {
258+ function bindAnonymousDeclaration ( node : Node , symbolKind : SymbolFlags , name : string , isBlockScopeContainer : boolean ) {
253259 var symbol = createSymbol ( symbolKind , name ) ;
254260 addDeclarationToSymbol ( symbol , node , symbolKind ) ;
255- bindChildren ( node , symbolKind ) ;
261+ bindChildren ( node , symbolKind , isBlockScopeContainer ) ;
256262 }
257263
258264 function bindCatchVariableDeclaration ( node : CatchBlock ) {
259265 var symbol = createSymbol ( SymbolFlags . Variable , node . variable . text || "__missing" ) ;
260266 addDeclarationToSymbol ( symbol , node , SymbolFlags . Variable ) ;
261267 var saveParent = parent ;
262- parent = node ;
268+ var savedBlockScopeContainer = blockScopeContainer ;
269+ parent = blockScopeContainer = node ;
263270 forEachChild ( node , bind ) ;
264271 parent = saveParent ;
272+ blockScopeContainer = savedBlockScopeContainer ;
273+ }
274+
275+ function bindBlockScopedVariableDeclaration ( node : Declaration ) {
276+ var symbolKind = SymbolFlags . Variable | SymbolFlags . BlockScoped ;
277+ switch ( blockScopeContainer . kind ) {
278+ case SyntaxKind . ModuleDeclaration :
279+ declareModuleMember ( node , symbolKind , SymbolFlags . BlockScopedExcludes ) ;
280+ break ;
281+ case SyntaxKind . SourceFile :
282+ if ( isExternalModule ( < SourceFile > container ) ) {
283+ declareModuleMember ( node , symbolKind , SymbolFlags . BlockScopedExcludes ) ;
284+ break ;
285+ }
286+ default :
287+ if ( ! blockScopeContainer . locals ) {
288+ blockScopeContainer . locals = { } ;
289+ }
290+ declareSymbol ( blockScopeContainer . locals , undefined , node , symbolKind , SymbolFlags . BlockScopedExcludes ) ;
291+ }
292+
293+ bindChildren ( node , symbolKind , /*isBlockScopeContainer*/ false ) ;
265294 }
266295
267296 function bind ( node : Node ) {
297+ var isBlockScopeContainer : boolean ;
268298 node . parent = parent ;
269299 switch ( node . kind ) {
270300 case SyntaxKind . TypeParameter :
271- bindDeclaration ( < Declaration > node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes ) ;
301+ bindDeclaration ( < Declaration > node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes , /*isBlockScopeContainer*/ false ) ;
272302 break ;
273303 case SyntaxKind . Parameter :
274- bindDeclaration ( < Declaration > node , SymbolFlags . Variable , SymbolFlags . ParameterExcludes ) ;
304+ bindDeclaration ( < Declaration > node , SymbolFlags . Variable , SymbolFlags . ParameterExcludes , /*isBlockScopeContainer*/ false ) ;
275305 break ;
276306 case SyntaxKind . VariableDeclaration :
277- bindDeclaration ( < Declaration > node , SymbolFlags . Variable , SymbolFlags . VariableExcludes ) ;
307+ if ( node . flags & NodeFlags . BlockScoped ) {
308+ bindBlockScopedVariableDeclaration ( < Declaration > node ) ;
309+ }
310+ else {
311+ bindDeclaration ( < Declaration > node , SymbolFlags . Variable , SymbolFlags . VariableExcludes , /*isBlockScopeContainer*/ false ) ;
312+ }
278313 break ;
279314 case SyntaxKind . Property :
280315 case SyntaxKind . PropertyAssignment :
281- bindDeclaration ( < Declaration > node , SymbolFlags . Property , SymbolFlags . PropertyExcludes ) ;
316+ bindDeclaration ( < Declaration > node , SymbolFlags . Property , SymbolFlags . PropertyExcludes , /*isBlockScopeContainer*/ false ) ;
282317 break ;
283318 case SyntaxKind . EnumMember :
284- bindDeclaration ( < Declaration > node , SymbolFlags . EnumMember , SymbolFlags . EnumMemberExcludes ) ;
319+ bindDeclaration ( < Declaration > node , SymbolFlags . EnumMember , SymbolFlags . EnumMemberExcludes , /*isBlockScopeContainer*/ false ) ;
285320 break ;
286321 case SyntaxKind . CallSignature :
287- bindDeclaration ( < Declaration > node , SymbolFlags . CallSignature , 0 ) ;
322+ bindDeclaration ( < Declaration > node , SymbolFlags . CallSignature , 0 , /*isBlockScopeContainer*/ false ) ;
288323 break ;
289324 case SyntaxKind . Method :
290- bindDeclaration ( < Declaration > node , SymbolFlags . Method , SymbolFlags . MethodExcludes ) ;
325+ bindDeclaration ( < Declaration > node , SymbolFlags . Method , SymbolFlags . MethodExcludes , /*isBlockScopeContainer*/ true ) ;
291326 break ;
292327 case SyntaxKind . ConstructSignature :
293- bindDeclaration ( < Declaration > node , SymbolFlags . ConstructSignature , 0 ) ;
328+ bindDeclaration ( < Declaration > node , SymbolFlags . ConstructSignature , 0 , /*isBlockScopeContainer*/ true ) ;
294329 break ;
295330 case SyntaxKind . IndexSignature :
296- bindDeclaration ( < Declaration > node , SymbolFlags . IndexSignature , 0 ) ;
331+ bindDeclaration ( < Declaration > node , SymbolFlags . IndexSignature , 0 , /*isBlockScopeContainer*/ false ) ;
297332 break ;
298333 case SyntaxKind . FunctionDeclaration :
299- bindDeclaration ( < Declaration > node , SymbolFlags . Function , SymbolFlags . FunctionExcludes ) ;
334+ bindDeclaration ( < Declaration > node , SymbolFlags . Function , SymbolFlags . FunctionExcludes , /*isBlockScopeContainer*/ true ) ;
300335 break ;
301336 case SyntaxKind . Constructor :
302337 bindConstructorDeclaration ( < ConstructorDeclaration > node ) ;
303338 break ;
304339 case SyntaxKind . GetAccessor :
305- bindDeclaration ( < Declaration > node , SymbolFlags . GetAccessor , SymbolFlags . GetAccessorExcludes ) ;
340+ bindDeclaration ( < Declaration > node , SymbolFlags . GetAccessor , SymbolFlags . GetAccessorExcludes , /*isBlockScopeContainer*/ true ) ;
306341 break ;
307342 case SyntaxKind . SetAccessor :
308- bindDeclaration ( < Declaration > node , SymbolFlags . SetAccessor , SymbolFlags . SetAccessorExcludes ) ;
343+ bindDeclaration ( < Declaration > node , SymbolFlags . SetAccessor , SymbolFlags . SetAccessorExcludes , /*isBlockScopeContainer*/ true ) ;
309344 break ;
310345 case SyntaxKind . TypeLiteral :
311- bindAnonymousDeclaration ( node , SymbolFlags . TypeLiteral , "__type" ) ;
346+ bindAnonymousDeclaration ( node , SymbolFlags . TypeLiteral , "__type" , /*isBlockScopeContainer*/ false ) ;
312347 break ;
313348 case SyntaxKind . ObjectLiteral :
314- bindAnonymousDeclaration ( node , SymbolFlags . ObjectLiteral , "__object" ) ;
349+ bindAnonymousDeclaration ( node , SymbolFlags . ObjectLiteral , "__object" , /*isBlockScopeContainer*/ false ) ;
315350 break ;
316351 case SyntaxKind . FunctionExpression :
317352 case SyntaxKind . ArrowFunction :
318- bindAnonymousDeclaration ( node , SymbolFlags . Function , "__function" ) ;
353+ bindAnonymousDeclaration ( node , SymbolFlags . Function , "__function" , /*isBlockScopeContainer*/ true ) ;
319354 break ;
320355 case SyntaxKind . CatchBlock :
321356 bindCatchVariableDeclaration ( < CatchBlock > node ) ;
322357 break ;
323358 case SyntaxKind . ClassDeclaration :
324- bindDeclaration ( < Declaration > node , SymbolFlags . Class , SymbolFlags . ClassExcludes ) ;
359+ bindDeclaration ( < Declaration > node , SymbolFlags . Class , SymbolFlags . ClassExcludes , /*isBlockScopeContainer*/ false ) ;
325360 break ;
326361 case SyntaxKind . InterfaceDeclaration :
327- bindDeclaration ( < Declaration > node , SymbolFlags . Interface , SymbolFlags . InterfaceExcludes ) ;
362+ bindDeclaration ( < Declaration > node , SymbolFlags . Interface , SymbolFlags . InterfaceExcludes , /*isBlockScopeContainer*/ false ) ;
328363 break ;
329364 case SyntaxKind . EnumDeclaration :
330- bindDeclaration ( < Declaration > node , SymbolFlags . Enum , SymbolFlags . EnumExcludes ) ;
365+ bindDeclaration ( < Declaration > node , SymbolFlags . Enum , SymbolFlags . EnumExcludes , /*isBlockScopeContainer*/ false ) ;
331366 break ;
332367 case SyntaxKind . ModuleDeclaration :
333368 bindModuleDeclaration ( < ModuleDeclaration > node ) ;
334369 break ;
335370 case SyntaxKind . ImportDeclaration :
336- bindDeclaration ( < Declaration > node , SymbolFlags . Import , SymbolFlags . ImportExcludes ) ;
371+ bindDeclaration ( < Declaration > node , SymbolFlags . Import , SymbolFlags . ImportExcludes , /*isBlockScopeContainer*/ false ) ;
337372 break ;
338373 case SyntaxKind . SourceFile :
339374 if ( isExternalModule ( < SourceFile > node ) ) {
340- bindAnonymousDeclaration ( node , SymbolFlags . ValueModule , '"' + removeFileExtension ( ( < SourceFile > node ) . filename ) + '"' ) ;
375+ bindAnonymousDeclaration ( node , SymbolFlags . ValueModule , '"' + removeFileExtension ( ( < SourceFile > node ) . filename ) + '"' , /*isBlockScopeContainer*/ true ) ;
341376 break ;
342377 }
378+
379+ case SyntaxKind . Block :
380+ case SyntaxKind . TryBlock :
381+ case SyntaxKind . CatchBlock :
382+ case SyntaxKind . FinallyBlock :
383+ case SyntaxKind . ForStatement :
384+ case SyntaxKind . ForInStatement :
385+ case SyntaxKind . SwitchStatement :
386+ isBlockScopeContainer = true ;
387+
343388 default :
344389 var saveParent = parent ;
390+ var savedBlockScopeContainer = blockScopeContainer ;
345391 parent = node ;
392+ if ( isBlockScopeContainer ) blockScopeContainer = node ;
346393 forEachChild ( node , bind ) ;
347394 parent = saveParent ;
395+ blockScopeContainer = savedBlockScopeContainer ;
348396 }
349397 }
350398 }
0 commit comments