@@ -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
}
@@ -86,10 +87,11 @@ module ts {
86
87
}
87
88
// Report errors every position with duplicate declaration
88
89
// Report errors on previous encountered declarations
90
+ var message = symbol . flags & SymbolFlags . BlockScopedVariable ? Diagnostics . Cannot_redeclare_block_scoped_variable_0 : Diagnostics . Duplicate_identifier_0 ;
89
91
forEach ( symbol . declarations , ( declaration ) => {
90
- file . semanticErrors . push ( createDiagnosticForNode ( declaration . name , Diagnostics . Duplicate_identifier_0 , getDisplayName ( declaration ) ) ) ;
92
+ file . semanticErrors . push ( createDiagnosticForNode ( declaration . name , message , getDisplayName ( declaration ) ) ) ;
91
93
} ) ;
92
- file . semanticErrors . push ( createDiagnosticForNode ( node . name , Diagnostics . Duplicate_identifier_0 , getDisplayName ( node ) ) ) ;
94
+ file . semanticErrors . push ( createDiagnosticForNode ( node . name , message , getDisplayName ( node ) ) ) ;
93
95
94
96
symbol = createSymbol ( 0 , name ) ;
95
97
}
@@ -167,12 +169,13 @@ module ts {
167
169
168
170
// All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function
169
171
// in the type checker to validate that the local name used for a container is unique.
170
- function bindChildren ( node : Declaration , symbolKind : SymbolFlags ) {
172
+ function bindChildren ( node : Declaration , symbolKind : SymbolFlags , isBlockScopeContainer : boolean ) {
171
173
if ( symbolKind & SymbolFlags . HasLocals ) {
172
174
node . locals = { } ;
173
175
}
174
176
var saveParent = parent ;
175
177
var saveContainer = container ;
178
+ var savedBlockScopeContainer = blockScopeContainer ;
176
179
parent = node ;
177
180
if ( symbolKind & SymbolFlags . IsContainer ) {
178
181
container = node ;
@@ -184,12 +187,16 @@ module ts {
184
187
lastContainer = container ;
185
188
}
186
189
}
190
+ if ( isBlockScopeContainer ) {
191
+ blockScopeContainer = node ;
192
+ }
187
193
forEachChild ( node , bind ) ;
188
194
container = saveContainer ;
189
195
parent = saveParent ;
196
+ blockScopeContainer = savedBlockScopeContainer ;
190
197
}
191
198
192
- function bindDeclaration ( node : Declaration , symbolKind : SymbolFlags , symbolExcludes : SymbolFlags ) {
199
+ function bindDeclaration ( node : Declaration , symbolKind : SymbolFlags , symbolExcludes : SymbolFlags , isBlockScopeContainer : boolean ) {
193
200
switch ( container . kind ) {
194
201
case SyntaxKind . ModuleDeclaration :
195
202
declareModuleMember ( node , symbolKind , symbolExcludes ) ;
@@ -225,121 +232,159 @@ module ts {
225
232
declareSymbol ( container . symbol . exports , container . symbol , node , symbolKind , symbolExcludes ) ;
226
233
break ;
227
234
}
228
- bindChildren ( node , symbolKind ) ;
235
+ bindChildren ( node , symbolKind , isBlockScopeContainer ) ;
229
236
}
230
237
231
238
function bindConstructorDeclaration ( node : ConstructorDeclaration ) {
232
- bindDeclaration ( node , SymbolFlags . Constructor , 0 ) ;
239
+ bindDeclaration ( node , SymbolFlags . Constructor , 0 , /*isBlockScopeContainer*/ true ) ;
233
240
forEach ( node . parameters , p => {
234
241
if ( p . flags & ( NodeFlags . Public | NodeFlags . Private | NodeFlags . Protected ) ) {
235
- bindDeclaration ( p , SymbolFlags . Property , SymbolFlags . PropertyExcludes ) ;
242
+ bindDeclaration ( p , SymbolFlags . Property , SymbolFlags . PropertyExcludes , /*isBlockScopeContainer*/ false ) ;
236
243
}
237
244
} ) ;
238
245
}
239
246
240
247
function bindModuleDeclaration ( node : ModuleDeclaration ) {
241
248
if ( node . name . kind === SyntaxKind . StringLiteral ) {
242
- bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes ) ;
249
+ bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes , /*isBlockScopeContainer*/ true ) ;
243
250
}
244
251
else if ( isInstantiated ( node ) ) {
245
- bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes ) ;
252
+ bindDeclaration ( node , SymbolFlags . ValueModule , SymbolFlags . ValueModuleExcludes , /*isBlockScopeContainer*/ true ) ;
246
253
}
247
254
else {
248
- bindDeclaration ( node , SymbolFlags . NamespaceModule , SymbolFlags . NamespaceModuleExcludes ) ;
255
+ bindDeclaration ( node , SymbolFlags . NamespaceModule , SymbolFlags . NamespaceModuleExcludes , /*isBlockScopeContainer*/ true ) ;
249
256
}
250
257
}
251
258
252
- function bindAnonymousDeclaration ( node : Node , symbolKind : SymbolFlags , name : string ) {
259
+ function bindAnonymousDeclaration ( node : Node , symbolKind : SymbolFlags , name : string , isBlockScopeContainer : boolean ) {
253
260
var symbol = createSymbol ( symbolKind , name ) ;
254
261
addDeclarationToSymbol ( symbol , node , symbolKind ) ;
255
- bindChildren ( node , symbolKind ) ;
262
+ bindChildren ( node , symbolKind , isBlockScopeContainer ) ;
256
263
}
257
264
258
265
function bindCatchVariableDeclaration ( node : CatchBlock ) {
259
- var symbol = createSymbol ( SymbolFlags . Variable , node . variable . text || "__missing" ) ;
260
- addDeclarationToSymbol ( symbol , node , SymbolFlags . Variable ) ;
266
+ var symbol = createSymbol ( SymbolFlags . FunctionScopedVariable , node . variable . text || "__missing" ) ;
267
+ addDeclarationToSymbol ( symbol , node , SymbolFlags . FunctionScopedVariable ) ;
261
268
var saveParent = parent ;
262
- parent = node ;
269
+ var savedBlockScopeContainer = blockScopeContainer ;
270
+ parent = blockScopeContainer = node ;
263
271
forEachChild ( node , bind ) ;
264
272
parent = saveParent ;
273
+ blockScopeContainer = savedBlockScopeContainer ;
274
+ }
275
+
276
+ function bindBlockScopedVariableDeclaration ( node : Declaration ) {
277
+ switch ( blockScopeContainer . kind ) {
278
+ case SyntaxKind . ModuleDeclaration :
279
+ declareModuleMember ( node , SymbolFlags . BlockScopedVariable , SymbolFlags . BlockScopedVariableExcludes ) ;
280
+ break ;
281
+ case SyntaxKind . SourceFile :
282
+ if ( isExternalModule ( < SourceFile > container ) ) {
283
+ declareModuleMember ( node , SymbolFlags . BlockScopedVariable , SymbolFlags . BlockScopedVariableExcludes ) ;
284
+ break ;
285
+ }
286
+ default :
287
+ if ( ! blockScopeContainer . locals ) {
288
+ blockScopeContainer . locals = { } ;
289
+ }
290
+ declareSymbol ( blockScopeContainer . locals , undefined , node , SymbolFlags . BlockScopedVariable , SymbolFlags . BlockScopedVariableExcludes ) ;
291
+ }
292
+
293
+ bindChildren ( node , SymbolFlags . BlockScopedVariable , /*isBlockScopeContainer*/ false ) ;
265
294
}
266
295
267
296
function bind ( node : Node ) {
268
297
node . parent = parent ;
269
298
switch ( node . kind ) {
270
299
case SyntaxKind . TypeParameter :
271
- bindDeclaration ( < Declaration > node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes ) ;
300
+ bindDeclaration ( < Declaration > node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes , /*isBlockScopeContainer*/ false ) ;
272
301
break ;
273
302
case SyntaxKind . Parameter :
274
- bindDeclaration ( < Declaration > node , SymbolFlags . Variable , SymbolFlags . ParameterExcludes ) ;
303
+ bindDeclaration ( < Declaration > node , SymbolFlags . FunctionScopedVariable , SymbolFlags . ParameterExcludes , /*isBlockScopeContainer*/ false ) ;
275
304
break ;
276
305
case SyntaxKind . VariableDeclaration :
277
- bindDeclaration ( < Declaration > node , SymbolFlags . Variable , SymbolFlags . VariableExcludes ) ;
306
+ if ( node . flags & NodeFlags . BlockScoped ) {
307
+ bindBlockScopedVariableDeclaration ( < Declaration > node ) ;
308
+ }
309
+ else {
310
+ bindDeclaration ( < Declaration > node , SymbolFlags . FunctionScopedVariable , SymbolFlags . FunctionScopedVariableExcludes , /*isBlockScopeContainer*/ false ) ;
311
+ }
278
312
break ;
279
313
case SyntaxKind . Property :
280
314
case SyntaxKind . PropertyAssignment :
281
- bindDeclaration ( < Declaration > node , SymbolFlags . Property , SymbolFlags . PropertyExcludes ) ;
315
+ bindDeclaration ( < Declaration > node , SymbolFlags . Property , SymbolFlags . PropertyExcludes , /*isBlockScopeContainer*/ false ) ;
282
316
break ;
283
317
case SyntaxKind . EnumMember :
284
- bindDeclaration ( < Declaration > node , SymbolFlags . EnumMember , SymbolFlags . EnumMemberExcludes ) ;
318
+ bindDeclaration ( < Declaration > node , SymbolFlags . EnumMember , SymbolFlags . EnumMemberExcludes , /*isBlockScopeContainer*/ false ) ;
285
319
break ;
286
320
case SyntaxKind . CallSignature :
287
- bindDeclaration ( < Declaration > node , SymbolFlags . CallSignature , 0 ) ;
321
+ bindDeclaration ( < Declaration > node , SymbolFlags . CallSignature , 0 , /*isBlockScopeContainer*/ false ) ;
288
322
break ;
289
323
case SyntaxKind . Method :
290
- bindDeclaration ( < Declaration > node , SymbolFlags . Method , SymbolFlags . MethodExcludes ) ;
324
+ bindDeclaration ( < Declaration > node , SymbolFlags . Method , SymbolFlags . MethodExcludes , /*isBlockScopeContainer*/ true ) ;
291
325
break ;
292
326
case SyntaxKind . ConstructSignature :
293
- bindDeclaration ( < Declaration > node , SymbolFlags . ConstructSignature , 0 ) ;
327
+ bindDeclaration ( < Declaration > node , SymbolFlags . ConstructSignature , 0 , /*isBlockScopeContainer*/ true ) ;
294
328
break ;
295
329
case SyntaxKind . IndexSignature :
296
- bindDeclaration ( < Declaration > node , SymbolFlags . IndexSignature , 0 ) ;
330
+ bindDeclaration ( < Declaration > node , SymbolFlags . IndexSignature , 0 , /*isBlockScopeContainer*/ false ) ;
297
331
break ;
298
332
case SyntaxKind . FunctionDeclaration :
299
- bindDeclaration ( < Declaration > node , SymbolFlags . Function , SymbolFlags . FunctionExcludes ) ;
333
+ bindDeclaration ( < Declaration > node , SymbolFlags . Function , SymbolFlags . FunctionExcludes , /*isBlockScopeContainer*/ true ) ;
300
334
break ;
301
335
case SyntaxKind . Constructor :
302
336
bindConstructorDeclaration ( < ConstructorDeclaration > node ) ;
303
337
break ;
304
338
case SyntaxKind . GetAccessor :
305
- bindDeclaration ( < Declaration > node , SymbolFlags . GetAccessor , SymbolFlags . GetAccessorExcludes ) ;
339
+ bindDeclaration ( < Declaration > node , SymbolFlags . GetAccessor , SymbolFlags . GetAccessorExcludes , /*isBlockScopeContainer*/ true ) ;
306
340
break ;
307
341
case SyntaxKind . SetAccessor :
308
- bindDeclaration ( < Declaration > node , SymbolFlags . SetAccessor , SymbolFlags . SetAccessorExcludes ) ;
342
+ bindDeclaration ( < Declaration > node , SymbolFlags . SetAccessor , SymbolFlags . SetAccessorExcludes , /*isBlockScopeContainer*/ true ) ;
309
343
break ;
310
344
case SyntaxKind . TypeLiteral :
311
- bindAnonymousDeclaration ( node , SymbolFlags . TypeLiteral , "__type" ) ;
345
+ bindAnonymousDeclaration ( node , SymbolFlags . TypeLiteral , "__type" , /*isBlockScopeContainer*/ false ) ;
312
346
break ;
313
347
case SyntaxKind . ObjectLiteral :
314
- bindAnonymousDeclaration ( node , SymbolFlags . ObjectLiteral , "__object" ) ;
348
+ bindAnonymousDeclaration ( node , SymbolFlags . ObjectLiteral , "__object" , /*isBlockScopeContainer*/ false ) ;
315
349
break ;
316
350
case SyntaxKind . FunctionExpression :
317
351
case SyntaxKind . ArrowFunction :
318
- bindAnonymousDeclaration ( node , SymbolFlags . Function , "__function" ) ;
352
+ bindAnonymousDeclaration ( node , SymbolFlags . Function , "__function" , /*isBlockScopeContainer*/ true ) ;
319
353
break ;
320
354
case SyntaxKind . CatchBlock :
321
355
bindCatchVariableDeclaration ( < CatchBlock > node ) ;
322
356
break ;
323
357
case SyntaxKind . ClassDeclaration :
324
- bindDeclaration ( < Declaration > node , SymbolFlags . Class , SymbolFlags . ClassExcludes ) ;
358
+ bindDeclaration ( < Declaration > node , SymbolFlags . Class , SymbolFlags . ClassExcludes , /*isBlockScopeContainer*/ false ) ;
325
359
break ;
326
360
case SyntaxKind . InterfaceDeclaration :
327
- bindDeclaration ( < Declaration > node , SymbolFlags . Interface , SymbolFlags . InterfaceExcludes ) ;
361
+ bindDeclaration ( < Declaration > node , SymbolFlags . Interface , SymbolFlags . InterfaceExcludes , /*isBlockScopeContainer*/ false ) ;
328
362
break ;
329
363
case SyntaxKind . EnumDeclaration :
330
- bindDeclaration ( < Declaration > node , SymbolFlags . Enum , SymbolFlags . EnumExcludes ) ;
364
+ bindDeclaration ( < Declaration > node , SymbolFlags . Enum , SymbolFlags . EnumExcludes , /*isBlockScopeContainer*/ false ) ;
331
365
break ;
332
366
case SyntaxKind . ModuleDeclaration :
333
367
bindModuleDeclaration ( < ModuleDeclaration > node ) ;
334
368
break ;
335
369
case SyntaxKind . ImportDeclaration :
336
- bindDeclaration ( < Declaration > node , SymbolFlags . Import , SymbolFlags . ImportExcludes ) ;
370
+ bindDeclaration ( < Declaration > node , SymbolFlags . Import , SymbolFlags . ImportExcludes , /*isBlockScopeContainer*/ false ) ;
337
371
break ;
338
372
case SyntaxKind . SourceFile :
339
373
if ( isExternalModule ( < SourceFile > node ) ) {
340
- bindAnonymousDeclaration ( node , SymbolFlags . ValueModule , '"' + removeFileExtension ( ( < SourceFile > node ) . filename ) + '"' ) ;
374
+ bindAnonymousDeclaration ( node , SymbolFlags . ValueModule , '"' + removeFileExtension ( ( < SourceFile > node ) . filename ) + '"' , /*isBlockScopeContainer*/ true ) ;
341
375
break ;
342
376
}
377
+
378
+ case SyntaxKind . Block :
379
+ case SyntaxKind . TryBlock :
380
+ case SyntaxKind . CatchBlock :
381
+ case SyntaxKind . FinallyBlock :
382
+ case SyntaxKind . ForStatement :
383
+ case SyntaxKind . ForInStatement :
384
+ case SyntaxKind . SwitchStatement :
385
+ bindChildren ( node , 0 , true ) ;
386
+ break ;
387
+
343
388
default :
344
389
var saveParent = parent ;
345
390
parent = node ;
0 commit comments