Add binder support for block scoped variable declarations

This commit is contained in:
Mohamed Hegazy 2014-10-13 20:54:26 -07:00
parent 6f6f4afeb1
commit cf89f5cf58
15 changed files with 1766 additions and 40 deletions

View File

@ -31,13 +31,14 @@ module ts {
var parent: Node;
var container: Declaration;
var blockScopeContainer: Node;
var lastContainer: Declaration;
var symbolCount = 0;
var Symbol = objectAllocator.getSymbolConstructor();
if (!file.locals) {
file.locals = {};
container = file;
container = blockScopeContainer = file;
bind(file);
file.symbolCount = symbolCount;
}
@ -167,12 +168,13 @@ module ts {
// All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function
// in the type checker to validate that the local name used for a container is unique.
function bindChildren(node: Declaration, symbolKind: SymbolFlags) {
function bindChildren(node: Declaration, symbolKind: SymbolFlags, isBlockScopeContainer: boolean) {
if (symbolKind & SymbolFlags.HasLocals) {
node.locals = {};
}
var saveParent = parent;
var saveContainer = container;
var savedBlockScopeContainer = blockScopeContainer;
parent = node;
if (symbolKind & SymbolFlags.IsContainer) {
container = node;
@ -184,12 +186,16 @@ module ts {
lastContainer = container;
}
}
if (isBlockScopeContainer) {
blockScopeContainer = node;
}
forEachChild(node, bind);
container = saveContainer;
parent = saveParent;
blockScopeContainer = savedBlockScopeContainer;
}
function bindDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) {
function bindDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean) {
switch (container.kind) {
case SyntaxKind.ModuleDeclaration:
declareModuleMember(node, symbolKind, symbolExcludes);
@ -225,126 +231,168 @@ module ts {
declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
break;
}
bindChildren(node, symbolKind);
bindChildren(node, symbolKind, isBlockScopeContainer);
}
function bindConstructorDeclaration(node: ConstructorDeclaration) {
bindDeclaration(node, SymbolFlags.Constructor, 0);
bindDeclaration(node, SymbolFlags.Constructor, 0, /*isBlockScopeContainer*/ true);
forEach(node.parameters, p => {
if (p.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected)) {
bindDeclaration(p, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
bindDeclaration(p, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
}
});
}
function bindModuleDeclaration(node: ModuleDeclaration) {
if (node.name.kind === SyntaxKind.StringLiteral) {
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true);
}
else if (isInstantiated(node)) {
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true);
}
else {
bindDeclaration(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes);
bindDeclaration(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes, /*isBlockScopeContainer*/ true);
}
}
function bindAnonymousDeclaration(node: Node, symbolKind: SymbolFlags, name: string) {
function bindAnonymousDeclaration(node: Node, symbolKind: SymbolFlags, name: string, isBlockScopeContainer: boolean) {
var symbol = createSymbol(symbolKind, name);
addDeclarationToSymbol(symbol, node, symbolKind);
bindChildren(node, symbolKind);
bindChildren(node, symbolKind, isBlockScopeContainer);
}
function bindCatchVariableDeclaration(node: CatchBlock) {
var symbol = createSymbol(SymbolFlags.Variable, node.variable.text || "__missing");
addDeclarationToSymbol(symbol, node, SymbolFlags.Variable);
var saveParent = parent;
parent = node;
var savedBlockScopeContainer = blockScopeContainer;
parent = blockScopeContainer = node;
forEachChild(node, bind);
parent = saveParent;
blockScopeContainer = savedBlockScopeContainer;
}
function bindBlockScopedVariableDeclaration(node: Declaration) {
var symbolKind = SymbolFlags.Variable | SymbolFlags.BlockScoped;
switch (blockScopeContainer.kind) {
case SyntaxKind.ModuleDeclaration:
declareModuleMember(node, symbolKind, SymbolFlags.BlockScopedExcludes);
break;
case SyntaxKind.SourceFile:
if (isExternalModule(<SourceFile>container)) {
declareModuleMember(node, symbolKind, SymbolFlags.BlockScopedExcludes);
break;
}
default:
if (!blockScopeContainer.locals) {
blockScopeContainer.locals = {};
}
declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, SymbolFlags.BlockScopedExcludes);
}
bindChildren(node, symbolKind, /*isBlockScopeContainer*/ false);
}
function bind(node: Node) {
var isBlockScopeContainer: boolean;
node.parent = parent;
switch (node.kind) {
case SyntaxKind.TypeParameter:
bindDeclaration(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
bindDeclaration(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.Parameter:
bindDeclaration(<Declaration>node, SymbolFlags.Variable, SymbolFlags.ParameterExcludes);
bindDeclaration(<Declaration>node, SymbolFlags.Variable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.VariableDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Variable, SymbolFlags.VariableExcludes);
if (node.flags & NodeFlags.BlockScoped) {
bindBlockScopedVariableDeclaration(<Declaration>node);
}
else {
bindDeclaration(<Declaration>node, SymbolFlags.Variable, SymbolFlags.VariableExcludes, /*isBlockScopeContainer*/ false);
}
break;
case SyntaxKind.Property:
case SyntaxKind.PropertyAssignment:
bindDeclaration(<Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
bindDeclaration(<Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.EnumMember:
bindDeclaration(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes);
bindDeclaration(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.CallSignature:
bindDeclaration(<Declaration>node, SymbolFlags.CallSignature, 0);
bindDeclaration(<Declaration>node, SymbolFlags.CallSignature, 0, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.Method:
bindDeclaration(<Declaration>node, SymbolFlags.Method, SymbolFlags.MethodExcludes);
bindDeclaration(<Declaration>node, SymbolFlags.Method, SymbolFlags.MethodExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.ConstructSignature:
bindDeclaration(<Declaration>node, SymbolFlags.ConstructSignature, 0);
bindDeclaration(<Declaration>node, SymbolFlags.ConstructSignature, 0, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.IndexSignature:
bindDeclaration(<Declaration>node, SymbolFlags.IndexSignature, 0);
bindDeclaration(<Declaration>node, SymbolFlags.IndexSignature, 0, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.FunctionDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes);
bindDeclaration(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.Constructor:
bindConstructorDeclaration(<ConstructorDeclaration>node);
break;
case SyntaxKind.GetAccessor:
bindDeclaration(<Declaration>node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes);
bindDeclaration(<Declaration>node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.SetAccessor:
bindDeclaration(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes);
bindDeclaration(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.TypeLiteral:
bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type");
bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type", /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.ObjectLiteral:
bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object");
bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object", /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
bindAnonymousDeclaration(node, SymbolFlags.Function, "__function");
bindAnonymousDeclaration(node, SymbolFlags.Function, "__function", /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.CatchBlock:
bindCatchVariableDeclaration(<CatchBlock>node);
break;
case SyntaxKind.ClassDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
bindDeclaration(<Declaration>node, SymbolFlags.Class, SymbolFlags.ClassExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.InterfaceDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes);
bindDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.EnumDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Enum, SymbolFlags.EnumExcludes);
bindDeclaration(<Declaration>node, SymbolFlags.Enum, SymbolFlags.EnumExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.ModuleDeclaration:
bindModuleDeclaration(<ModuleDeclaration>node);
break;
case SyntaxKind.ImportDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Import, SymbolFlags.ImportExcludes);
bindDeclaration(<Declaration>node, SymbolFlags.Import, SymbolFlags.ImportExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.SourceFile:
if (isExternalModule(<SourceFile>node)) {
bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((<SourceFile>node).filename) + '"');
bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((<SourceFile>node).filename) + '"', /*isBlockScopeContainer*/ true);
break;
}
case SyntaxKind.Block:
case SyntaxKind.TryBlock:
case SyntaxKind.CatchBlock:
case SyntaxKind.FinallyBlock:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.SwitchStatement:
isBlockScopeContainer = true;
default:
var saveParent = parent;
var savedBlockScopeContainer = blockScopeContainer;
parent = node;
if (isBlockScopeContainer) blockScopeContainer = node;
forEachChild(node, bind);
parent = saveParent;
blockScopeContainer = savedBlockScopeContainer;
}
}
}

View File

@ -245,11 +245,12 @@ module ts {
MultiLine = 0x00000100, // Multi-line array or object literal
Synthetic = 0x00000200, // Synthetic node (for full fidelity)
DeclarationFile = 0x00000400, // Node is a .d.ts file
Let = 0x00000800,
Const = 0x00001000,
Let = 0x00000800, // Variable declaration
Const = 0x00001000, // Variable declaration
Modifier = Export | Ambient | Public | Private | Protected | Static,
AccessibilityModifier = Public | Private | Protected
AccessibilityModifier = Public | Private | Protected,
BlockScoped = Let | Const
}
export interface Node extends TextRange {
@ -768,6 +769,8 @@ module ts {
Undefined = 0x08000000, // Symbol for the undefined
BlockScoped = 0x10000000,
Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor,
Type = Class | Interface | Enum | TypeLiteral | ObjectLiteral | TypeParameter,
Namespace = ValueModule | NamespaceModule,
@ -776,7 +779,8 @@ module ts {
Signature = CallSignature | ConstructSignature | IndexSignature,
ParameterExcludes = Value,
VariableExcludes = Value & ~Variable,
VariableExcludes = (Value | BlockScoped) & ~Variable,
BlockScopedExcludes = Value,
PropertyExcludes = Value,
EnumMemberExcludes = Value,
FunctionExcludes = Value & ~(Function | ValueModule),

View File

@ -13,10 +13,11 @@ tests/cases/compiler/constDeclarations-errors.ts(8,18): error TS1128: Declaratio
tests/cases/compiler/constDeclarations-errors.ts(10,5): error TS1109: Expression expected.
tests/cases/compiler/constDeclarations-errors.ts(10,5): error TS1156: const must be declared inside a block.
tests/cases/compiler/constDeclarations-errors.ts(10,28): error TS1005: ';' expected.
tests/cases/compiler/constDeclarations-errors.ts(10,11): error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'.
tests/cases/compiler/constDeclarations-errors.ts(10,18): error TS2304: Cannot find name 'c'.
tests/cases/compiler/constDeclarations-errors.ts(10,25): error TS2304: Cannot find name 'c'.
==== tests/cases/compiler/constDeclarations-errors.ts (16 errors) ====
==== tests/cases/compiler/constDeclarations-errors.ts (17 errors) ====
// error, missing intialicer
const c1;
@ -57,6 +58,8 @@ tests/cases/compiler/constDeclarations-errors.ts(10,11): error TS2403: Subsequen
!!! error TS1156: const must be declared inside a block.
~
!!! error TS1005: ';' expected.
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'.
~
!!! error TS2304: Cannot find name 'c'.
~
!!! error TS2304: Cannot find name 'c'.

View File

@ -0,0 +1,153 @@
tests/cases/compiler/constDeclarations-scopes.ts(28,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'.
==== tests/cases/compiler/constDeclarations-scopes.ts (1 errors) ====
// global
const c = "string";
var n: number;
// Control flow statements with blocks
if (true) {
const c = 0;
n = c;
}
else {
const c = 0;
n = c;
}
while (true) {
const c = 0;
n = c;
}
do {
const c = 0;
n = c;
} while (true);
var obj;
with (obj) {
~~~
!!! error TS2410: All symbols within a 'with' block will be resolved to 'any'.
const c = 0;
n = c;
}
for (var i = 0; i < 10; i++) {
const c = 0;
n = c;
}
for (var i2 in {}) {
const c = 0;
n = c;
}
if (true) {
label: const c = 0;
n = c;
}
while (false) {
label2: label3: label4: const c = 0;
n = c;
}
// Try/catch/finally
try {
const c = 0;
n = c;
}
catch (e) {
const c = 0;
n = c;
}
finally {
const c = 0;
n = c;
}
// Switch
switch (0) {
case 0:
const c = 0;
n = c;
break;
}
// blocks
{
const c = 0;
n = c;
{
const c = false;
var b: boolean = c;
}
}
// functions
function F() {
const c = 0;
n = c;
}
var F2 = () => {
const c = 0;
n = c;
};
var F3 = function () {
const c = 0;
n = c;
};
// modules
module m {
const c = 0;
n = c;
{
const c = false;
var b2: boolean = c;
}
}
// methods
class C {
constructor() {
const c = 0;
n = c;
}
method() {
const c = 0;
n = c;
}
get v() {
const c = 0;
n = c;
return n;
}
set v(value) {
const c = 0;
n = c;
}
}
// object literals
var o = {
f() {
const c = 0;
n = c;
},
f2: () => {
const c = 0;
n = c;
}
}

View File

@ -0,0 +1,276 @@
//// [constDeclarations-scopes.ts]
// global
const c = "string";
var n: number;
// Control flow statements with blocks
if (true) {
const c = 0;
n = c;
}
else {
const c = 0;
n = c;
}
while (true) {
const c = 0;
n = c;
}
do {
const c = 0;
n = c;
} while (true);
var obj;
with (obj) {
const c = 0;
n = c;
}
for (var i = 0; i < 10; i++) {
const c = 0;
n = c;
}
for (var i2 in {}) {
const c = 0;
n = c;
}
if (true) {
label: const c = 0;
n = c;
}
while (false) {
label2: label3: label4: const c = 0;
n = c;
}
// Try/catch/finally
try {
const c = 0;
n = c;
}
catch (e) {
const c = 0;
n = c;
}
finally {
const c = 0;
n = c;
}
// Switch
switch (0) {
case 0:
const c = 0;
n = c;
break;
}
// blocks
{
const c = 0;
n = c;
{
const c = false;
var b: boolean = c;
}
}
// functions
function F() {
const c = 0;
n = c;
}
var F2 = () => {
const c = 0;
n = c;
};
var F3 = function () {
const c = 0;
n = c;
};
// modules
module m {
const c = 0;
n = c;
{
const c = false;
var b2: boolean = c;
}
}
// methods
class C {
constructor() {
const c = 0;
n = c;
}
method() {
const c = 0;
n = c;
}
get v() {
const c = 0;
n = c;
return n;
}
set v(value) {
const c = 0;
n = c;
}
}
// object literals
var o = {
f() {
const c = 0;
n = c;
},
f2: () => {
const c = 0;
n = c;
}
}
//// [constDeclarations-scopes.js]
// global
const c = "string";
var n;
// Control flow statements with blocks
if (true) {
const c = 0;
n = c;
}
else {
const c = 0;
n = c;
}
while (true) {
const c = 0;
n = c;
}
do {
const c = 0;
n = c;
} while (true);
var obj;
with (obj) {
const c = 0;
n = c;
}
for (var i = 0; i < 10; i++) {
const c = 0;
n = c;
}
for (var i2 in {}) {
const c = 0;
n = c;
}
if (true) {
label: const c = 0;
n = c;
}
while (false) {
label2: label3: label4: const c = 0;
n = c;
}
try {
const c = 0;
n = c;
}
catch (e) {
const c = 0;
n = c;
}
finally {
const c = 0;
n = c;
}
switch (0) {
case 0:
const c = 0;
n = c;
break;
}
{
const c = 0;
n = c;
{
const c = false;
var b = c;
}
}
// functions
function F() {
const c = 0;
n = c;
}
var F2 = function () {
const c = 0;
n = c;
};
var F3 = function () {
const c = 0;
n = c;
};
// modules
var m;
(function (m) {
const c = 0;
n = c;
{
const c = false;
var b2 = c;
}
})(m || (m = {}));
// methods
var C = (function () {
function C() {
const c = 0;
n = c;
}
C.prototype.method = function () {
const c = 0;
n = c;
};
Object.defineProperty(C.prototype, "v", {
get: function () {
const c = 0;
n = c;
return n;
},
set: function (value) {
const c = 0;
n = c;
},
enumerable: true,
configurable: true
});
return C;
})();
// object literals
var o = {
f: function () {
const c = 0;
n = c;
},
f2: function () {
const c = 0;
n = c;
}
};

View File

@ -0,0 +1,152 @@
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(3,5): error TS2300: Duplicate identifier 'var1'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(4,5): error TS2300: Duplicate identifier 'var1'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(6,5): error TS2300: Duplicate identifier 'var2'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(7,7): error TS2300: Duplicate identifier 'var2'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(9,7): error TS2300: Duplicate identifier 'var3'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(10,5): error TS2300: Duplicate identifier 'var3'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(12,7): error TS2300: Duplicate identifier 'var4'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(13,7): error TS2300: Duplicate identifier 'var4'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(15,5): error TS2300: Duplicate identifier 'var5'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(16,5): error TS2300: Duplicate identifier 'var5'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(18,5): error TS2300: Duplicate identifier 'var6'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(19,5): error TS2300: Duplicate identifier 'var6'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(22,9): error TS2300: Duplicate identifier 'var7'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(23,9): error TS2300: Duplicate identifier 'var7'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(25,13): error TS2300: Duplicate identifier 'var8'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(26,15): error TS2300: Duplicate identifier 'var8'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(32,13): error TS2300: Duplicate identifier 'var9'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(33,13): error TS2300: Duplicate identifier 'var9'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(37,11): error TS2300: Duplicate identifier 'var10'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(38,11): error TS2300: Duplicate identifier 'var10'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(41,9): error TS2300: Duplicate identifier 'var11'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(42,9): error TS2300: Duplicate identifier 'var11'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(46,9): error TS2300: Duplicate identifier 'var12'.
tests/cases/compiler/letDeclarations-scopes-duplicates.ts(47,9): error TS2300: Duplicate identifier 'var12'.
==== tests/cases/compiler/letDeclarations-scopes-duplicates.ts (24 errors) ====
// Errors: redeclaration
let var1 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var1'.
let var1 = 0; // error
~~~~
!!! error TS2300: Duplicate identifier 'var1'.
let var2 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var2'.
const var2 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var2'.
const var3 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var3'.
let var3 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var3'.
const var4 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var4'.
const var4 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var4'.
var var5 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var5'.
let var5 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var5'.
let var6 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var6'.
var var6 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var6'.
{
let var7 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var7'.
let var7 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var7'.
{
let var8 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var8'.
const var8 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var8'.
}
}
switch (0) {
default:
let var9 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var9'.
let var9 = 0;
~~~~
!!! error TS2300: Duplicate identifier 'var9'.
}
try {
const var10 = 0;
~~~~~
!!! error TS2300: Duplicate identifier 'var10'.
const var10 = 0;
~~~~~
!!! error TS2300: Duplicate identifier 'var10'.
}
catch (e) {
let var11 = 0;
~~~~~
!!! error TS2300: Duplicate identifier 'var11'.
let var11 = 0;
~~~~~
!!! error TS2300: Duplicate identifier 'var11'.
}
function F1() {
let var12;
~~~~~
!!! error TS2300: Duplicate identifier 'var12'.
let var12;
~~~~~
!!! error TS2300: Duplicate identifier 'var12'.
}
// OK
var var20 = 0;
var var20 = 0
{
let var20 = 0;
{
let var20 = 0;
}
}
switch (0) {
default:
let var20 = 0;
}
try {
let var20 = 0;
}
catch (e) {
let var20 = 0;
}
function F() {
let var20;
}

View File

@ -0,0 +1,140 @@
//// [letDeclarations-scopes-duplicates.ts]
// Errors: redeclaration
let var1 = 0;
let var1 = 0; // error
let var2 = 0;
const var2 = 0;
const var3 = 0;
let var3 = 0;
const var4 = 0;
const var4 = 0;
var var5 = 0;
let var5 = 0;
let var6 = 0;
var var6 = 0;
{
let var7 = 0;
let var7 = 0;
{
let var8 = 0;
const var8 = 0;
}
}
switch (0) {
default:
let var9 = 0;
let var9 = 0;
}
try {
const var10 = 0;
const var10 = 0;
}
catch (e) {
let var11 = 0;
let var11 = 0;
}
function F1() {
let var12;
let var12;
}
// OK
var var20 = 0;
var var20 = 0
{
let var20 = 0;
{
let var20 = 0;
}
}
switch (0) {
default:
let var20 = 0;
}
try {
let var20 = 0;
}
catch (e) {
let var20 = 0;
}
function F() {
let var20;
}
//// [letDeclarations-scopes-duplicates.js]
// Errors: redeclaration
let var1 = 0;
let var1 = 0; // error
let var2 = 0;
const var2 = 0;
const var3 = 0;
let var3 = 0;
const var4 = 0;
const var4 = 0;
var var5 = 0;
let var5 = 0;
let var6 = 0;
var var6 = 0;
{
let var7 = 0;
let var7 = 0;
{
let var8 = 0;
const var8 = 0;
}
}
switch (0) {
default:
let var9 = 0;
let var9 = 0;
}
try {
const var10 = 0;
const var10 = 0;
}
catch (e) {
let var11 = 0;
let var11 = 0;
}
function F1() {
let var12;
let var12;
}
// OK
var var20 = 0;
var var20 = 0;
{
let var20 = 0;
{
let var20 = 0;
}
}
switch (0) {
default:
let var20 = 0;
}
try {
let var20 = 0;
}
catch (e) {
let var20 = 0;
}
function F() {
let var20;
}

View File

@ -0,0 +1,161 @@
tests/cases/compiler/letDeclarations-scopes.ts(28,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'.
==== tests/cases/compiler/letDeclarations-scopes.ts (1 errors) ====
// global
let l = "string";
var n: number;
// Control flow statements with blocks
if (true) {
let l = 0;
n = l;
}
else {
let l = 0;
n = l;
}
while (true) {
let l = 0;
n = l;
}
do {
let l = 0;
n = l;
} while (true);
var obj;
with (obj) {
~~~
!!! error TS2410: All symbols within a 'with' block will be resolved to 'any'.
let l = 0;
n = l;
}
for (var i = 0; i < 10; i++) {
let l = 0;
n = l;
}
for (var i2 in {}) {
let l = 0;
n = l;
}
if (true) {
label: let l = 0;
n = l;
}
while (false) {
label2: label3: label4: let l = 0;
n = l;
}
for (let l = 0; n = l; l++) {
let l = true;
var b3: boolean = l;
}
for (let l in {}) {
}
// Try/catch/finally
try {
let l = 0;
n = l;
}
catch (e) {
let l = 0;
n = l;
}
finally {
let l = 0;
n = l;
}
// Switch
switch (0) {
case 0:
let l = 0;
n = l;
break;
}
// blocks
{
let l = 0;
n = l;
{
let l = false;
var b: boolean = l;
}
}
// functions
function F() {
let l = 0;
n = l;
}
var F2 = () => {
let l = 0;
n = l;
};
var F3 = function () {
let l = 0;
n = l;
};
// modules
module m {
let l = 0;
n = l;
{
let l = false;
var b2: boolean = l;
}
}
// methods
class C {
constructor() {
let l = 0;
n = l;
}
method() {
let l = 0;
n = l;
}
get v() {
let l = 0;
n = l;
return n;
}
set v(value) {
let l = 0;
n = l;
}
}
// object literals
var o = {
f() {
let l = 0;
n = l;
},
f2: () => {
let l = 0;
n = l;
}
}

View File

@ -0,0 +1,290 @@
//// [letDeclarations-scopes.ts]
// global
let l = "string";
var n: number;
// Control flow statements with blocks
if (true) {
let l = 0;
n = l;
}
else {
let l = 0;
n = l;
}
while (true) {
let l = 0;
n = l;
}
do {
let l = 0;
n = l;
} while (true);
var obj;
with (obj) {
let l = 0;
n = l;
}
for (var i = 0; i < 10; i++) {
let l = 0;
n = l;
}
for (var i2 in {}) {
let l = 0;
n = l;
}
if (true) {
label: let l = 0;
n = l;
}
while (false) {
label2: label3: label4: let l = 0;
n = l;
}
for (let l = 0; n = l; l++) {
let l = true;
var b3: boolean = l;
}
for (let l in {}) {
}
// Try/catch/finally
try {
let l = 0;
n = l;
}
catch (e) {
let l = 0;
n = l;
}
finally {
let l = 0;
n = l;
}
// Switch
switch (0) {
case 0:
let l = 0;
n = l;
break;
}
// blocks
{
let l = 0;
n = l;
{
let l = false;
var b: boolean = l;
}
}
// functions
function F() {
let l = 0;
n = l;
}
var F2 = () => {
let l = 0;
n = l;
};
var F3 = function () {
let l = 0;
n = l;
};
// modules
module m {
let l = 0;
n = l;
{
let l = false;
var b2: boolean = l;
}
}
// methods
class C {
constructor() {
let l = 0;
n = l;
}
method() {
let l = 0;
n = l;
}
get v() {
let l = 0;
n = l;
return n;
}
set v(value) {
let l = 0;
n = l;
}
}
// object literals
var o = {
f() {
let l = 0;
n = l;
},
f2: () => {
let l = 0;
n = l;
}
}
//// [letDeclarations-scopes.js]
// global
let l = "string";
var n;
// Control flow statements with blocks
if (true) {
let l = 0;
n = l;
}
else {
let l = 0;
n = l;
}
while (true) {
let l = 0;
n = l;
}
do {
let l = 0;
n = l;
} while (true);
var obj;
with (obj) {
let l = 0;
n = l;
}
for (var i = 0; i < 10; i++) {
let l = 0;
n = l;
}
for (var i2 in {}) {
let l = 0;
n = l;
}
if (true) {
label: let l = 0;
n = l;
}
while (false) {
label2: label3: label4: let l = 0;
n = l;
}
for (let l = 0; n = l; l++) {
let l = true;
var b3 = l;
}
for (let l in {}) {
}
try {
let l = 0;
n = l;
}
catch (e) {
let l = 0;
n = l;
}
finally {
let l = 0;
n = l;
}
switch (0) {
case 0:
let l = 0;
n = l;
break;
}
{
let l = 0;
n = l;
{
let l = false;
var b = l;
}
}
// functions
function F() {
let l = 0;
n = l;
}
var F2 = function () {
let l = 0;
n = l;
};
var F3 = function () {
let l = 0;
n = l;
};
// modules
var m;
(function (m) {
let l = 0;
n = l;
{
let l = false;
var b2 = l;
}
})(m || (m = {}));
// methods
var C = (function () {
function C() {
let l = 0;
n = l;
}
C.prototype.method = function () {
let l = 0;
n = l;
};
Object.defineProperty(C.prototype, "v", {
get: function () {
let l = 0;
n = l;
return n;
},
set: function (value) {
let l = 0;
n = l;
},
enumerable: true,
configurable: true
});
return C;
})();
// object literals
var o = {
f: function () {
let l = 0;
n = l;
},
f2: function () {
let l = 0;
n = l;
}
};

View File

@ -0,0 +1,42 @@
tests/cases/compiler/letDeclarations-scopes2.ts(9,5): error TS2304: Cannot find name 'local2'.
tests/cases/compiler/letDeclarations-scopes2.ts(21,5): error TS2304: Cannot find name 'local2'.
tests/cases/compiler/letDeclarations-scopes2.ts(24,1): error TS2304: Cannot find name 'local'.
tests/cases/compiler/letDeclarations-scopes2.ts(26,1): error TS2304: Cannot find name 'local2'.
==== tests/cases/compiler/letDeclarations-scopes2.ts (4 errors) ====
let global = 0;
{
let local = 0;
local; // OK
global; // OK
local2; // Error
~~~~~~
!!! error TS2304: Cannot find name 'local2'.
{
let local2 = 0;
local; // OK
global; // OK
local2; // OK
}
local; // OK
global; // OK
local2; // Error
~~~~~~
!!! error TS2304: Cannot find name 'local2'.
}
local; // Error
~~~~~
!!! error TS2304: Cannot find name 'local'.
global; // OK
local2; // Error
~~~~~~
!!! error TS2304: Cannot find name 'local2'.

View File

@ -0,0 +1,49 @@
//// [letDeclarations-scopes2.ts]
let global = 0;
{
let local = 0;
local; // OK
global; // OK
local2; // Error
{
let local2 = 0;
local; // OK
global; // OK
local2; // OK
}
local; // OK
global; // OK
local2; // Error
}
local; // Error
global; // OK
local2; // Error
//// [letDeclarations-scopes2.js]
let global = 0;
{
let local = 0;
local; // OK
global; // OK
local2; // Error
{
let local2 = 0;
local; // OK
global; // OK
local2; // OK
}
local; // OK
global; // OK
local2; // Error
}
local; // Error
global; // OK
local2; // Error

View File

@ -0,0 +1,148 @@
// @target: ES6
// global
const c = "string";
var n: number;
// Control flow statements with blocks
if (true) {
const c = 0;
n = c;
}
else {
const c = 0;
n = c;
}
while (true) {
const c = 0;
n = c;
}
do {
const c = 0;
n = c;
} while (true);
var obj;
with (obj) {
const c = 0;
n = c;
}
for (var i = 0; i < 10; i++) {
const c = 0;
n = c;
}
for (var i2 in {}) {
const c = 0;
n = c;
}
if (true) {
label: const c = 0;
n = c;
}
while (false) {
label2: label3: label4: const c = 0;
n = c;
}
// Try/catch/finally
try {
const c = 0;
n = c;
}
catch (e) {
const c = 0;
n = c;
}
finally {
const c = 0;
n = c;
}
// Switch
switch (0) {
case 0:
const c = 0;
n = c;
break;
}
// blocks
{
const c = 0;
n = c;
{
const c = false;
var b: boolean = c;
}
}
// functions
function F() {
const c = 0;
n = c;
}
var F2 = () => {
const c = 0;
n = c;
};
var F3 = function () {
const c = 0;
n = c;
};
// modules
module m {
const c = 0;
n = c;
{
const c = false;
var b2: boolean = c;
}
}
// methods
class C {
constructor() {
const c = 0;
n = c;
}
method() {
const c = 0;
n = c;
}
get v() {
const c = 0;
n = c;
return n;
}
set v(value) {
const c = 0;
n = c;
}
}
// object literals
var o = {
f() {
const c = 0;
n = c;
},
f2: () => {
const c = 0;
n = c;
}
}

View File

@ -0,0 +1,77 @@
// @target: ES6
// Errors: redeclaration
let var1 = 0;
let var1 = 0; // error
let var2 = 0;
const var2 = 0;
const var3 = 0;
let var3 = 0;
const var4 = 0;
const var4 = 0;
var var5 = 0;
let var5 = 0;
let var6 = 0;
var var6 = 0;
{
let var7 = 0;
let var7 = 0;
{
let var8 = 0;
const var8 = 0;
}
}
switch (0) {
default:
let var9 = 0;
let var9 = 0;
}
try {
const var10 = 0;
const var10 = 0;
}
catch (e) {
let var11 = 0;
let var11 = 0;
}
function F1() {
let var12;
let var12;
}
// OK
var var20 = 0;
var var20 = 0
{
let var20 = 0;
{
let var20 = 0;
}
}
switch (0) {
default:
let var20 = 0;
}
try {
let var20 = 0;
}
catch (e) {
let var20 = 0;
}
function F() {
let var20;
}

View File

@ -0,0 +1,156 @@
// @target: ES6
// global
let l = "string";
var n: number;
// Control flow statements with blocks
if (true) {
let l = 0;
n = l;
}
else {
let l = 0;
n = l;
}
while (true) {
let l = 0;
n = l;
}
do {
let l = 0;
n = l;
} while (true);
var obj;
with (obj) {
let l = 0;
n = l;
}
for (var i = 0; i < 10; i++) {
let l = 0;
n = l;
}
for (var i2 in {}) {
let l = 0;
n = l;
}
if (true) {
label: let l = 0;
n = l;
}
while (false) {
label2: label3: label4: let l = 0;
n = l;
}
for (let l = 0; n = l; l++) {
let l = true;
var b3: boolean = l;
}
for (let l in {}) {
}
// Try/catch/finally
try {
let l = 0;
n = l;
}
catch (e) {
let l = 0;
n = l;
}
finally {
let l = 0;
n = l;
}
// Switch
switch (0) {
case 0:
let l = 0;
n = l;
break;
}
// blocks
{
let l = 0;
n = l;
{
let l = false;
var b: boolean = l;
}
}
// functions
function F() {
let l = 0;
n = l;
}
var F2 = () => {
let l = 0;
n = l;
};
var F3 = function () {
let l = 0;
n = l;
};
// modules
module m {
let l = 0;
n = l;
{
let l = false;
var b2: boolean = l;
}
}
// methods
class C {
constructor() {
let l = 0;
n = l;
}
method() {
let l = 0;
n = l;
}
get v() {
let l = 0;
n = l;
return n;
}
set v(value) {
let l = 0;
n = l;
}
}
// object literals
var o = {
f() {
let l = 0;
n = l;
},
f2: () => {
let l = 0;
n = l;
}
}

View File

@ -0,0 +1,27 @@
// @target: ES6
let global = 0;
{
let local = 0;
local; // OK
global; // OK
local2; // Error
{
let local2 = 0;
local; // OK
global; // OK
local2; // OK
}
local; // OK
global; // OK
local2; // Error
}
local; // Error
global; // OK
local2; // Error