Class declarations should be block scoped.

This commit is contained in:
unknown
2015-04-01 16:24:51 -07:00
parent 490dfef41b
commit 22a87fb9ca
8 changed files with 122 additions and 7 deletions

View File

@@ -388,23 +388,28 @@ module ts {
bindChildren(node, /*symbolKind:*/ 0, /*isBlockScopeContainer:*/ true);
}
function bindBlockScopedVariableDeclaration(node: Declaration) {
function bindBlockScopedDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) {
switch (blockScopeContainer.kind) {
case SyntaxKind.ModuleDeclaration:
declareModuleMember(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
declareModuleMember(node, symbolKind, symbolExcludes);
break;
case SyntaxKind.SourceFile:
if (isExternalModule(<SourceFile>container)) {
declareModuleMember(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
declareModuleMember(node, symbolKind, symbolExcludes);
break;
}
// fall through.
default:
if (!blockScopeContainer.locals) {
blockScopeContainer.locals = {};
}
declareSymbol(blockScopeContainer.locals, undefined, node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, symbolExcludes);
}
bindChildren(node, SymbolFlags.BlockScopedVariable, /*isBlockScopeContainer*/ false);
bindChildren(node, symbolKind, /*isBlockScopeContainer*/ false);
}
function bindBlockScopedVariableDeclaration(node: Declaration) {
bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
}
function getDestructuringParameterName(node: Declaration) {
@@ -493,7 +498,7 @@ module ts {
bindCatchVariableDeclaration(<CatchClause>node);
break;
case SyntaxKind.ClassDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Class, SymbolFlags.ClassExcludes, /*isBlockScopeContainer*/ false);
bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
break;
case SyntaxKind.InterfaceDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes, /*isBlockScopeContainer*/ false);

View File

@@ -0,0 +1,13 @@
tests/cases/compiler/classDeclarationBlockScoping1.ts(5,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration.
==== tests/cases/compiler/classDeclarationBlockScoping1.ts (1 errors) ====
class C {
}
{
class C {
~
!!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration.
}
}

View File

@@ -0,0 +1,22 @@
//// [classDeclarationBlockScoping1.ts]
class C {
}
{
class C {
}
}
//// [classDeclarationBlockScoping1.js]
var C = (function () {
function C() {
}
return C;
})();
{
var C = (function () {
function C() {
}
return C;
})();
}

View File

@@ -0,0 +1,18 @@
tests/cases/compiler/classDeclarationBlockScoping2.ts(2,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration.
tests/cases/compiler/classDeclarationBlockScoping2.ts(5,15): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration.
==== tests/cases/compiler/classDeclarationBlockScoping2.ts (2 errors) ====
function f() {
class C {}
~
!!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration.
var c1 = C;
{
class C {}
~
!!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration.
var c2 = C;
}
return C === c1;
}

View File

@@ -0,0 +1,29 @@
//// [classDeclarationBlockScoping2.ts]
function f() {
class C {}
var c1 = C;
{
class C {}
var c2 = C;
}
return C === c1;
}
//// [classDeclarationBlockScoping2.js]
function f() {
var C = (function () {
function C() {
}
return C;
})();
var c1 = C;
{
var C = (function () {
function C() {
}
return C;
})();
var c2 = C;
}
return C === c1;
}

View File

@@ -8,9 +8,13 @@ tests/cases/compiler/externModule.ts(18,6): error TS2390: Constructor implementa
tests/cases/compiler/externModule.ts(20,13): error TS2391: Function implementation is missing or not immediately following the declaration.
tests/cases/compiler/externModule.ts(26,13): error TS2391: Function implementation is missing or not immediately following the declaration.
tests/cases/compiler/externModule.ts(28,13): error TS2391: Function implementation is missing or not immediately following the declaration.
tests/cases/compiler/externModule.ts(32,11): error TS2304: Cannot find name 'XDate'.
tests/cases/compiler/externModule.ts(34,7): error TS2304: Cannot find name 'XDate'.
tests/cases/compiler/externModule.ts(36,7): error TS2304: Cannot find name 'XDate'.
tests/cases/compiler/externModule.ts(37,3): error TS2304: Cannot find name 'XDate'.
==== tests/cases/compiler/externModule.ts (10 errors) ====
==== tests/cases/compiler/externModule.ts (14 errors) ====
declare module {
~~~~~~~
!!! error TS2304: Cannot find name 'declare'.
@@ -63,10 +67,18 @@ tests/cases/compiler/externModule.ts(28,13): error TS2391: Function implementati
}
var d=new XDate();
~~~~~
!!! error TS2304: Cannot find name 'XDate'.
d.getDay();
d=new XDate(1978,2);
~~~~~
!!! error TS2304: Cannot find name 'XDate'.
d.getXDate();
var n=XDate.parse("3/2/2004");
~~~~~
!!! error TS2304: Cannot find name 'XDate'.
n=XDate.UTC(1964,2,1);
~~~~~
!!! error TS2304: Cannot find name 'XDate'.

View File

@@ -0,0 +1,7 @@
class C {
}
{
class C {
}
}

View File

@@ -0,0 +1,9 @@
function f() {
class C {}
var c1 = C;
{
class C {}
var c2 = C;
}
return C === c1;
}