Do not allow use of block-scoped variable before its definition
This commit is contained in:
parent
cf89f5cf58
commit
1dde985f1d
|
@ -314,6 +314,21 @@ module ts {
|
|||
if (!s && nameNotFoundMessage) {
|
||||
error(errorLocation, nameNotFoundMessage, nameArg);
|
||||
}
|
||||
if (s && s.flags & SymbolFlags.BlockScoped) {
|
||||
var declaration = forEach(s.declarations, d => d.flags & NodeFlags.BlockScoped ? d : undefined);
|
||||
Debug.assert(declaration, "Bock-scoped variable declaration is undefined");
|
||||
var declarationSourceFile = getSourceFileOfNode(declaration);
|
||||
var referenceSourceFile = getSourceFileOfNode(errorLocation);
|
||||
if (declarationSourceFile === referenceSourceFile && declaration.pos > errorLocation.pos) {
|
||||
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, identifierToString(declaration.name));
|
||||
}
|
||||
else if (compilerOptions.out) {
|
||||
var sourceFiles = program.getSourceFiles();
|
||||
if (sourceFiles.indexOf(referenceSourceFile) < sourceFiles.indexOf(declarationSourceFile)) {
|
||||
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, identifierToString(declaration.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
@ -269,6 +269,7 @@ module ts {
|
|||
Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: { code: 2445, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible within class '{1}' and its subclasses." },
|
||||
Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: { code: 2446, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible through an instance of class '{1}'." },
|
||||
The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: { code: 2447, category: DiagnosticCategory.Error, key: "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead." },
|
||||
Block_scoped_variable_0_used_before_its_declaration: { code: 2448, category: DiagnosticCategory.Error, key: "Block-scoped variable '{0}' used before its declaration." },
|
||||
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
|
||||
Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." },
|
||||
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
|
||||
|
|
|
@ -451,27 +451,27 @@
|
|||
"category": "Error",
|
||||
"code": 1151
|
||||
},
|
||||
"'var', 'let' or 'const' expected.": {
|
||||
"'var', 'let' or 'const' expected.": {
|
||||
"category": "Error",
|
||||
"code": 1152
|
||||
},
|
||||
"'let' variable declarations are only available when targeting ECMAScript 6 and higher.": {
|
||||
"'let' variable declarations are only available when targeting ECMAScript 6 and higher.": {
|
||||
"category": "Error",
|
||||
"code": 1153
|
||||
},
|
||||
"'const' variable declarations are only available when targeting ECMAScript 6 and higher.": {
|
||||
"'const' variable declarations are only available when targeting ECMAScript 6 and higher.": {
|
||||
"category": "Error",
|
||||
"code": 1154
|
||||
},
|
||||
"const must be intialized.": {
|
||||
"const must be intialized.": {
|
||||
"category": "Error",
|
||||
"code": 1155
|
||||
},
|
||||
"const must be declared inside a block.": {
|
||||
"const must be declared inside a block.": {
|
||||
"category": "Error",
|
||||
"code": 1156
|
||||
},
|
||||
"let must be declared inside a block.": {
|
||||
"let must be declared inside a block.": {
|
||||
"category": "Error",
|
||||
"code": 1157
|
||||
},
|
||||
|
@ -1068,6 +1068,10 @@
|
|||
"category": "Error",
|
||||
"code": 2447
|
||||
},
|
||||
"Block-scoped variable '{0}' used before its declaration.": {
|
||||
"category": "Error",
|
||||
"code": 2448
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
tests/cases/compiler/constDeclarations-useBeforeDefinition.ts(3,5): error TS2448: Block-scoped variable 'c1' used before its declaration.
|
||||
tests/cases/compiler/constDeclarations-useBeforeDefinition.ts(9,5): error TS2448: Block-scoped variable 'v1' used before its declaration.
|
||||
|
||||
|
||||
==== tests/cases/compiler/constDeclarations-useBeforeDefinition.ts (2 errors) ====
|
||||
|
||||
{
|
||||
c1;
|
||||
~~
|
||||
!!! error TS2448: Block-scoped variable 'c1' used before its declaration.
|
||||
const c1 = 0;
|
||||
}
|
||||
|
||||
var v1;
|
||||
{
|
||||
v1;
|
||||
~~
|
||||
!!! error TS2448: Block-scoped variable 'v1' used before its declaration.
|
||||
const v1 = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
//// [constDeclarations-useBeforeDefinition.ts]
|
||||
|
||||
{
|
||||
c1;
|
||||
const c1 = 0;
|
||||
}
|
||||
|
||||
var v1;
|
||||
{
|
||||
v1;
|
||||
const v1 = 0;
|
||||
}
|
||||
|
||||
|
||||
//// [constDeclarations-useBeforeDefinition.js]
|
||||
{
|
||||
c1;
|
||||
const c1 = 0;
|
||||
}
|
||||
var v1;
|
||||
{
|
||||
v1;
|
||||
const v1 = 0;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
tests/cases/compiler/file1.ts(2,1): error TS2448: Block-scoped variable 'c' used before its declaration.
|
||||
|
||||
|
||||
==== tests/cases/compiler/file1.ts (1 errors) ====
|
||||
|
||||
c;
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'c' used before its declaration.
|
||||
|
||||
==== tests/cases/compiler/file2.ts (0 errors) ====
|
||||
const c = 0;
|
|
@ -0,0 +1,12 @@
|
|||
//// [tests/cases/compiler/constDeclarations-useBeforeDefinition2.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
|
||||
c;
|
||||
|
||||
//// [file2.ts]
|
||||
const c = 0;
|
||||
|
||||
//// [out.js]
|
||||
c;
|
||||
const c = 0;
|
|
@ -0,0 +1,21 @@
|
|||
tests/cases/compiler/letDeclarations-useBeforeDefinition.ts(3,5): error TS2448: Block-scoped variable 'l1' used before its declaration.
|
||||
tests/cases/compiler/letDeclarations-useBeforeDefinition.ts(9,5): error TS2448: Block-scoped variable 'v1' used before its declaration.
|
||||
|
||||
|
||||
==== tests/cases/compiler/letDeclarations-useBeforeDefinition.ts (2 errors) ====
|
||||
|
||||
{
|
||||
l1;
|
||||
~~
|
||||
!!! error TS2448: Block-scoped variable 'l1' used before its declaration.
|
||||
let l1;
|
||||
}
|
||||
|
||||
var v1;
|
||||
{
|
||||
v1;
|
||||
~~
|
||||
!!! error TS2448: Block-scoped variable 'v1' used before its declaration.
|
||||
let v1 = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
//// [letDeclarations-useBeforeDefinition.ts]
|
||||
|
||||
{
|
||||
l1;
|
||||
let l1;
|
||||
}
|
||||
|
||||
var v1;
|
||||
{
|
||||
v1;
|
||||
let v1 = 0;
|
||||
}
|
||||
|
||||
|
||||
//// [letDeclarations-useBeforeDefinition.js]
|
||||
{
|
||||
l1;
|
||||
let l1;
|
||||
}
|
||||
var v1;
|
||||
{
|
||||
v1;
|
||||
let v1 = 0;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
tests/cases/compiler/file1.ts(2,1): error TS2448: Block-scoped variable 'l' used before its declaration.
|
||||
|
||||
|
||||
==== tests/cases/compiler/file1.ts (1 errors) ====
|
||||
|
||||
l;
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'l' used before its declaration.
|
||||
|
||||
==== tests/cases/compiler/file2.ts (0 errors) ====
|
||||
const l = 0;
|
|
@ -0,0 +1,12 @@
|
|||
//// [tests/cases/compiler/letDeclarations-useBeforeDefinition2.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
|
||||
l;
|
||||
|
||||
//// [file2.ts]
|
||||
const l = 0;
|
||||
|
||||
//// [out.js]
|
||||
l;
|
||||
const l = 0;
|
18
tests/baselines/reference/letDeclarations3.errors.txt
Normal file
18
tests/baselines/reference/letDeclarations3.errors.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
tests/cases/compiler/letDeclarations3.ts(3,5): error TS2300: Duplicate identifier 'l1'.
|
||||
tests/cases/compiler/letDeclarations3.ts(3,9): error TS2300: Duplicate identifier 'l1'.
|
||||
tests/cases/compiler/letDeclarations3.ts(3,13): error TS2300: Duplicate identifier 'l1'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/letDeclarations3.ts (3 errors) ====
|
||||
|
||||
// Duplicate variables
|
||||
let l1, l1, l1;
|
||||
~~
|
||||
!!! error TS2300: Duplicate identifier 'l1'.
|
||||
~~
|
||||
!!! error TS2300: Duplicate identifier 'l1'.
|
||||
~~
|
||||
!!! error TS2300: Duplicate identifier 'l1'.
|
||||
|
||||
// unexpected 'let'
|
||||
let l2, let, l3;
|
|
@ -0,0 +1,12 @@
|
|||
// @target: ES6
|
||||
|
||||
{
|
||||
c1;
|
||||
const c1 = 0;
|
||||
}
|
||||
|
||||
var v1;
|
||||
{
|
||||
v1;
|
||||
const v1 = 0;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// @target: ES6
|
||||
// @out: out.js
|
||||
|
||||
// @Filename: file1.ts
|
||||
c;
|
||||
|
||||
// @Filename: file2.ts
|
||||
const c = 0;
|
12
tests/cases/compiler/letDeclarations-useBeforeDefinition.ts
Normal file
12
tests/cases/compiler/letDeclarations-useBeforeDefinition.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
// @target: ES6
|
||||
|
||||
{
|
||||
l1;
|
||||
let l1;
|
||||
}
|
||||
|
||||
var v1;
|
||||
{
|
||||
v1;
|
||||
let v1 = 0;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// @target: ES6
|
||||
// @out: out.js
|
||||
|
||||
// @Filename: file1.ts
|
||||
l;
|
||||
|
||||
// @Filename: file2.ts
|
||||
const l = 0;
|
Loading…
Reference in a new issue