@@ -31,13 +31,14 @@ module ts {
31
31
32
32
var parent : Node ;
33
33
var container : Declaration ;
34
+ var blockScopeContainer : Node ;
34
35
var lastContainer : Declaration ;
35
36
var symbolCount = 0 ;
36
37
var Symbol = objectAllocator . getSymbolConstructor ( ) ;
37
38
38
39
if ( ! file . locals ) {
39
40
file . locals = { } ;
40
- container = file ;
41
+ container = blockScopeContainer = file ;
41
42
bind ( file ) ;
42
43
file . symbolCount = symbolCount ;
43
44
}
@@ -167,12 +168,13 @@ module ts {
167
168
168
169
// All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function
169
170
// 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 ) {
171
172
if ( symbolKind & SymbolFlags . HasLocals ) {
172
173
node . locals = { } ;
173
174
}
174
175
var saveParent = parent ;
175
176
var saveContainer = container ;
177
+ var savedBlockScopeContainer = blockScopeContainer ;
176
178
parent = node ;
177
179
if ( symbolKind & SymbolFlags . IsContainer ) {
178
180
container = node ;
@@ -184,12 +186,16 @@ module ts {
184
186
lastContainer = container ;
185
187
}
186
188
}
189
+ if ( isBlockScopeContainer ) {
190
+ blockScopeContainer = node ;
191
+ }
187
192
forEachChild ( node , bind ) ;
188
193
container = saveContainer ;
189
194
parent = saveParent ;
195
+ blockScopeContainer = savedBlockScopeContainer ;
190
196
}
191
197
192
- function bindDeclaration ( node : Declaration , symbolKind : SymbolFlags , symbolExcludes : SymbolFlags ) {
198
+ function bindDeclaration ( node : Declaration , symbolKind : SymbolFlags , symbolExcludes : SymbolFlags , isBlockScopeContainer : boolean ) {
193
199
switch ( container . kind ) {
194
200
case SyntaxKind . ModuleDeclaration :
195
201
declareModuleMember ( node , symbolKind , symbolExcludes ) ;
@@ -225,126 +231,168 @@ module ts {
225
231
declareSymbol ( container . symbol . exports , container . symbol , node , symbolKind , symbolExcludes ) ;
226
232
break ;
227
233
}
228
- bindChildren ( node , symbolKind ) ;
234
+ bindChildren ( node , symbolKind , isBlockScopeContainer ) ;
229
235
}
230
236
231
237
function bindConstructorDeclaration ( node : ConstructorDeclaration ) {
232
- bindDeclaration ( node , SymbolFlags . Constructor , 0 ) ;
238
+ bindDeclaration ( node , SymbolFlags . Constructor , 0 , /*isBlockScopeContainer*/ true ) ;
233
239
forEach ( node . parameters , p => {
234
240
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 ) ;
236
242
}
237
243
} ) ;
238
244
}
239
245
240
246
function bindModuleDeclaration ( node : ModuleDeclaration ) {
241
247
if ( node . name . kind === SyntaxKind . StringLiteral ) {
242
- bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes ) ;
248
+ bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes , /*isBlockScopeContainer*/ true ) ;
243
249
}
244
250
else if ( isInstantiated ( node ) ) {
245
- bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes ) ;
251
+ bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes , /*isBlockScopeContainer*/ true ) ;
246
252
}
247
253
else {
248
- bindDeclaration ( node , SymbolFlags . NamespaceModule , SymbolFlags . NamespaceModuleExcludes ) ;
254
+ bindDeclaration ( node , SymbolFlags . NamespaceModule , SymbolFlags . NamespaceModuleExcludes , /*isBlockScopeContainer*/ true ) ;
249
255
}
250
256
}
251
257
252
- function bindAnonymousDeclaration ( node : Node , symbolKind : SymbolFlags , name : string ) {
258
+ function bindAnonymousDeclaration ( node : Node , symbolKind : SymbolFlags , name : string , isBlockScopeContainer : boolean ) {
253
259
var symbol = createSymbol ( symbolKind , name ) ;
254
260
addDeclarationToSymbol ( symbol , node , symbolKind ) ;
255
- bindChildren ( node , symbolKind ) ;
261
+ bindChildren ( node , symbolKind , isBlockScopeContainer ) ;
256
262
}
257
263
258
264
function bindCatchVariableDeclaration ( node : CatchBlock ) {
259
265
var symbol = createSymbol ( SymbolFlags . Variable , node . variable . text || "__missing" ) ;
260
266
addDeclarationToSymbol ( symbol , node , SymbolFlags . Variable ) ;
261
267
var saveParent = parent ;
262
- parent = node ;
268
+ var savedBlockScopeContainer = blockScopeContainer ;
269
+ parent = blockScopeContainer = node ;
263
270
forEachChild ( node , bind ) ;
264
271
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 ) ;
265
294
}
266
295
267
296
function bind ( node : Node ) {
297
+ var isBlockScopeContainer : boolean ;
268
298
node . parent = parent ;
269
299
switch ( node . kind ) {
270
300
case SyntaxKind . TypeParameter :
271
- bindDeclaration ( < Declaration > node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes ) ;
301
+ bindDeclaration ( < Declaration > node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes , /*isBlockScopeContainer*/ false ) ;
272
302
break ;
273
303
case SyntaxKind . Parameter :
274
- bindDeclaration ( < Declaration > node , SymbolFlags . Variable , SymbolFlags . ParameterExcludes ) ;
304
+ bindDeclaration ( < Declaration > node , SymbolFlags . Variable , SymbolFlags . ParameterExcludes , /*isBlockScopeContainer*/ false ) ;
275
305
break ;
276
306
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
+ }
278
313
break ;
279
314
case SyntaxKind . Property :
280
315
case SyntaxKind . PropertyAssignment :
281
- bindDeclaration ( < Declaration > node , SymbolFlags . Property , SymbolFlags . PropertyExcludes ) ;
316
+ bindDeclaration ( < Declaration > node , SymbolFlags . Property , SymbolFlags . PropertyExcludes , /*isBlockScopeContainer*/ false ) ;
282
317
break ;
283
318
case SyntaxKind . EnumMember :
284
- bindDeclaration ( < Declaration > node , SymbolFlags . EnumMember , SymbolFlags . EnumMemberExcludes ) ;
319
+ bindDeclaration ( < Declaration > node , SymbolFlags . EnumMember , SymbolFlags . EnumMemberExcludes , /*isBlockScopeContainer*/ false ) ;
285
320
break ;
286
321
case SyntaxKind . CallSignature :
287
- bindDeclaration ( < Declaration > node , SymbolFlags . CallSignature , 0 ) ;
322
+ bindDeclaration ( < Declaration > node , SymbolFlags . CallSignature , 0 , /*isBlockScopeContainer*/ false ) ;
288
323
break ;
289
324
case SyntaxKind . Method :
290
- bindDeclaration ( < Declaration > node , SymbolFlags . Method , SymbolFlags . MethodExcludes ) ;
325
+ bindDeclaration ( < Declaration > node , SymbolFlags . Method , SymbolFlags . MethodExcludes , /*isBlockScopeContainer*/ true ) ;
291
326
break ;
292
327
case SyntaxKind . ConstructSignature :
293
- bindDeclaration ( < Declaration > node , SymbolFlags . ConstructSignature , 0 ) ;
328
+ bindDeclaration ( < Declaration > node , SymbolFlags . ConstructSignature , 0 , /*isBlockScopeContainer*/ true ) ;
294
329
break ;
295
330
case SyntaxKind . IndexSignature :
296
- bindDeclaration ( < Declaration > node , SymbolFlags . IndexSignature , 0 ) ;
331
+ bindDeclaration ( < Declaration > node , SymbolFlags . IndexSignature , 0 , /*isBlockScopeContainer*/ false ) ;
297
332
break ;
298
333
case SyntaxKind . FunctionDeclaration :
299
- bindDeclaration ( < Declaration > node , SymbolFlags . Function , SymbolFlags . FunctionExcludes ) ;
334
+ bindDeclaration ( < Declaration > node , SymbolFlags . Function , SymbolFlags . FunctionExcludes , /*isBlockScopeContainer*/ true ) ;
300
335
break ;
301
336
case SyntaxKind . Constructor :
302
337
bindConstructorDeclaration ( < ConstructorDeclaration > node ) ;
303
338
break ;
304
339
case SyntaxKind . GetAccessor :
305
- bindDeclaration ( < Declaration > node , SymbolFlags . GetAccessor , SymbolFlags . GetAccessorExcludes ) ;
340
+ bindDeclaration ( < Declaration > node , SymbolFlags . GetAccessor , SymbolFlags . GetAccessorExcludes , /*isBlockScopeContainer*/ true ) ;
306
341
break ;
307
342
case SyntaxKind . SetAccessor :
308
- bindDeclaration ( < Declaration > node , SymbolFlags . SetAccessor , SymbolFlags . SetAccessorExcludes ) ;
343
+ bindDeclaration ( < Declaration > node , SymbolFlags . SetAccessor , SymbolFlags . SetAccessorExcludes , /*isBlockScopeContainer*/ true ) ;
309
344
break ;
310
345
case SyntaxKind . TypeLiteral :
311
- bindAnonymousDeclaration ( node , SymbolFlags . TypeLiteral , "__type" ) ;
346
+ bindAnonymousDeclaration ( node , SymbolFlags . TypeLiteral , "__type" , /*isBlockScopeContainer*/ false ) ;
312
347
break ;
313
348
case SyntaxKind . ObjectLiteral :
314
- bindAnonymousDeclaration ( node , SymbolFlags . ObjectLiteral , "__object" ) ;
349
+ bindAnonymousDeclaration ( node , SymbolFlags . ObjectLiteral , "__object" , /*isBlockScopeContainer*/ false ) ;
315
350
break ;
316
351
case SyntaxKind . FunctionExpression :
317
352
case SyntaxKind . ArrowFunction :
318
- bindAnonymousDeclaration ( node , SymbolFlags . Function , "__function" ) ;
353
+ bindAnonymousDeclaration ( node , SymbolFlags . Function , "__function" , /*isBlockScopeContainer*/ true ) ;
319
354
break ;
320
355
case SyntaxKind . CatchBlock :
321
356
bindCatchVariableDeclaration ( < CatchBlock > node ) ;
322
357
break ;
323
358
case SyntaxKind . ClassDeclaration :
324
- bindDeclaration ( < Declaration > node , SymbolFlags . Class , SymbolFlags . ClassExcludes ) ;
359
+ bindDeclaration ( < Declaration > node , SymbolFlags . Class , SymbolFlags . ClassExcludes , /*isBlockScopeContainer*/ false ) ;
325
360
break ;
326
361
case SyntaxKind . InterfaceDeclaration :
327
- bindDeclaration ( < Declaration > node , SymbolFlags . Interface , SymbolFlags . InterfaceExcludes ) ;
362
+ bindDeclaration ( < Declaration > node , SymbolFlags . Interface , SymbolFlags . InterfaceExcludes , /*isBlockScopeContainer*/ false ) ;
328
363
break ;
329
364
case SyntaxKind . EnumDeclaration :
330
- bindDeclaration ( < Declaration > node , SymbolFlags . Enum , SymbolFlags . EnumExcludes ) ;
365
+ bindDeclaration ( < Declaration > node , SymbolFlags . Enum , SymbolFlags . EnumExcludes , /*isBlockScopeContainer*/ false ) ;
331
366
break ;
332
367
case SyntaxKind . ModuleDeclaration :
333
368
bindModuleDeclaration ( < ModuleDeclaration > node ) ;
334
369
break ;
335
370
case SyntaxKind . ImportDeclaration :
336
- bindDeclaration ( < Declaration > node , SymbolFlags . Import , SymbolFlags . ImportExcludes ) ;
371
+ bindDeclaration ( < Declaration > node , SymbolFlags . Import , SymbolFlags . ImportExcludes , /*isBlockScopeContainer*/ false ) ;
337
372
break ;
338
373
case SyntaxKind . SourceFile :
339
374
if ( isExternalModule ( < SourceFile > node ) ) {
340
- bindAnonymousDeclaration ( node , SymbolFlags . ValueModule , '"' + removeFileExtension ( ( < SourceFile > node ) . filename ) + '"' ) ;
375
+ bindAnonymousDeclaration ( node , SymbolFlags . ValueModule , '"' + removeFileExtension ( ( < SourceFile > node ) . filename ) + '"' , /*isBlockScopeContainer*/ true ) ;
341
376
break ;
342
377
}
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
+
343
388
default :
344
389
var saveParent = parent ;
390
+ var savedBlockScopeContainer = blockScopeContainer ;
345
391
parent = node ;
392
+ if ( isBlockScopeContainer ) blockScopeContainer = node ;
346
393
forEachChild ( node , bind ) ;
347
394
parent = saveParent ;
395
+ blockScopeContainer = savedBlockScopeContainer ;
348
396
}
349
397
}
350
398
}
0 commit comments