Skip to content

Commit

Permalink
Allow const in for statements
Browse files Browse the repository at this point in the history
  • Loading branch information
mhegazy committed Oct 15, 2014
1 parent 82f5fb4 commit 3e45601
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 50 deletions.
4 changes: 2 additions & 2 deletions src/compiler/diagnosticInformationMap.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ module ts {
new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 1150, category: DiagnosticCategory.Error, key: "'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead." },
An_enum_member_cannot_have_a_numeric_name: { code: 1151, category: DiagnosticCategory.Error, key: "An enum member cannot have a numeric name." },
var_let_or_const_expected: { code: 1152, category: DiagnosticCategory.Error, key: "'var', 'let' or 'const' expected." },
let_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1153, category: DiagnosticCategory.Error, key: "'let' variable declarations are only available when targeting ECMAScript 6 and higher." },
const_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1154, category: DiagnosticCategory.Error, key: "'const' variable declarations are only available when targeting ECMAScript 6 and higher." },
let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1153, category: DiagnosticCategory.Error, key: "'let' declarations are only available when targeting ECMAScript 6 and higher." },
const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1154, category: DiagnosticCategory.Error, key: "'const' declarations are only available when targeting ECMAScript 6 and higher." },
const_must_be_intialized: { code: 1155, category: DiagnosticCategory.Error, key: "const must be intialized." },
const_must_be_declared_inside_a_block: { code: 1156, category: DiagnosticCategory.Error, key: "const must be declared inside a block." },
let_must_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "let must be declared inside a block." },
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -455,11 +455,11 @@
"category": "Error",
"code": 1152
},
"'let' variable declarations are only available when targeting ECMAScript 6 and higher.": {
"'let' 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' declarations are only available when targeting ECMAScript 6 and higher.": {
"category": "Error",
"code": 1154
},
Expand Down
15 changes: 12 additions & 3 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2654,7 +2654,16 @@ module ts {
error(Diagnostics.Variable_declaration_list_cannot_be_empty);
}
if (languageVersion < ScriptTarget.ES6) {
grammarErrorAtPos(declarations.pos, declarations.end - declarations.pos, Diagnostics.let_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
grammarErrorAtPos(declarations.pos, declarations.end - declarations.pos, Diagnostics.let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
}
}
else if (parseOptional(SyntaxKind.ConstKeyword)) {
var declarations = parseVariableDeclarationList(NodeFlags.Const, true);

This comment has been minimized.

Copy link
@ahejlsberg

ahejlsberg Oct 17, 2014

Member

So ES6 permits a const declaration in a for statement, but it is still an error to re-assign the const, right? Not sure why you'd ever want to do that, but if that's what ES6 says then so be it.

This comment has been minimized.

Copy link
@mhegazy

mhegazy Oct 17, 2014

Author Contributor

the only benefit is getting a fresh binding for every iteration, so it can be captured, but not changed later on. I could not come up with a meaningful use case that requires a new binding and read-only that is not identical to:

while (true) {
    const c = 0;
    ....
}
if (!declarations.length) {
error(Diagnostics.Variable_declaration_list_cannot_be_empty);
}
if (languageVersion < ScriptTarget.ES6) {
grammarErrorAtPos(declarations.pos, declarations.end - declarations.pos, Diagnostics.const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
}
}
else {
Expand Down Expand Up @@ -3145,10 +3154,10 @@ module ts {
}
if (languageVersion < ScriptTarget.ES6) {
if (node.flags & NodeFlags.Let) {
grammarErrorOnNode(node, Diagnostics.let_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
grammarErrorOnNode(node, Diagnostics.let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
}
else if (node.flags & NodeFlags.Const) {
grammarErrorOnNode(node, Diagnostics.const_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
grammarErrorOnNode(node, Diagnostics.const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
}
}
else if (!allowLetDeclarations){
Expand Down
53 changes: 19 additions & 34 deletions tests/baselines/reference/constDeclarations-errors.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,13 @@ tests/cases/compiler/constDeclarations-errors.ts(5,7): error TS1155: const must
tests/cases/compiler/constDeclarations-errors.ts(5,11): error TS1155: const must be intialized.
tests/cases/compiler/constDeclarations-errors.ts(5,15): error TS1155: const must be intialized.
tests/cases/compiler/constDeclarations-errors.ts(5,27): error TS1155: const must be intialized.
tests/cases/compiler/constDeclarations-errors.ts(8,5): error TS1109: Expression expected.
tests/cases/compiler/constDeclarations-errors.ts(8,5): error TS1156: const must be declared inside a block.
tests/cases/compiler/constDeclarations-errors.ts(8,11): error TS1155: const must be intialized.
tests/cases/compiler/constDeclarations-errors.ts(8,13): error TS1005: ';' expected.
tests/cases/compiler/constDeclarations-errors.ts(8,13): error TS1128: Declaration or statement expected.
tests/cases/compiler/constDeclarations-errors.ts(8,18): error TS1128: Declaration or statement expected.
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,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(14,11): error TS1155: const must be intialized.
tests/cases/compiler/constDeclarations-errors.ts(17,20): error TS1155: const must be intialized.
tests/cases/compiler/constDeclarations-errors.ts(11,27): error TS2449: The operand of an increment or decrement operator cannot be a constant.


==== tests/cases/compiler/constDeclarations-errors.ts (17 errors) ====
==== tests/cases/compiler/constDeclarations-errors.ts (10 errors) ====

// error, missing intialicer
const c1;
Expand All @@ -36,30 +29,22 @@ tests/cases/compiler/constDeclarations-errors.ts(10,25): error TS2304: Cannot fi
~~
!!! error TS1155: const must be intialized.

// error, wrong context
// error, can not be unintalized
for(const c in {}) { }
~~~~~
!!! error TS1109: Expression expected.
~~~~~~~
!!! error TS1156: const must be declared inside a block.
~
!!! error TS1155: const must be intialized.
~~
!!! error TS1005: ';' expected.
~~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS1128: Declaration or statement expected.

for(const c = 0; c < 9; c++) { }
~~~~~
!!! error TS1109: Expression expected.
~~~~~~~~~~~~
!!! error TS1156: const must be declared inside a block.
~
!!! error TS1005: ';' expected.
~
!!! error TS2304: Cannot find name 'c'.
~
!!! error TS2304: Cannot find name 'c'.

// error, assigning to a const
for(const c8 = 0; c8 < 1; c8++) { }
~~
!!! error TS2449: The operand of an increment or decrement operator cannot be a constant.

// error, can not be unintalized
for(const c9; c9 < 1;) { }
~~
!!! error TS1155: const must be intialized.

// error, can not be unintalized
for(const c10 = 0, c11; c10 < 1;) { }
~~~
!!! error TS1155: const must be intialized.
12 changes: 6 additions & 6 deletions tests/baselines/reference/constDeclarations-es5.errors.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
tests/cases/compiler/constDeclarations-es5.ts(2,1): error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher.
tests/cases/compiler/constDeclarations-es5.ts(3,1): error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher.
tests/cases/compiler/constDeclarations-es5.ts(4,1): error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher.
tests/cases/compiler/constDeclarations-es5.ts(2,1): error TS1154: 'const' declarations are only available when targeting ECMAScript 6 and higher.
tests/cases/compiler/constDeclarations-es5.ts(3,1): error TS1154: 'const' declarations are only available when targeting ECMAScript 6 and higher.
tests/cases/compiler/constDeclarations-es5.ts(4,1): error TS1154: 'const' declarations are only available when targeting ECMAScript 6 and higher.


==== tests/cases/compiler/constDeclarations-es5.ts (3 errors) ====

const z7 = false;
~~~~~~~~~~~~~~~~~
!!! error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher.
!!! error TS1154: 'const' declarations are only available when targeting ECMAScript 6 and higher.
const z8: number = 23;
~~~~~~~~~~~~~~~~~~~~~~
!!! error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher.
!!! error TS1154: 'const' declarations are only available when targeting ECMAScript 6 and higher.
const z9 = 0, z10 :string = "", z11 = null;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher.
!!! error TS1154: 'const' declarations are only available when targeting ECMAScript 6 and higher.

27 changes: 27 additions & 0 deletions tests/baselines/reference/constDeclarations-scopes2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//// [constDeclarations-scopes2.ts]

// global
const c = "string";

var n: number;
var b: boolean;

// for scope
for (const c = 0; c < 10; n = c ) {
// for block
const c = false;
b = c;
}



//// [constDeclarations-scopes2.js]
// global
const c = "string";
var n;
var b;
for (var c = 0; c < 10; n = c) {
// for block
const c = false;
b = c;
}
32 changes: 32 additions & 0 deletions tests/baselines/reference/constDeclarations-scopes2.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
=== tests/cases/compiler/constDeclarations-scopes2.ts ===

// global
const c = "string";
>c : string

var n: number;
>n : number

var b: boolean;
>b : boolean

// for scope
for (const c = 0; c < 10; n = c ) {
>c : number
>c < 10 : boolean
>c : number
>n = c : number
>n : number
>c : number

// for block
const c = false;
>c : boolean

b = c;
>b = c : boolean
>b : boolean
>c : boolean
}


13 changes: 12 additions & 1 deletion tests/baselines/reference/constDeclarations.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@
const c1 = false;
const c2: number = 23;
const c3 = 0, c4 :string = "", c5 = null;



for(const c4 = 0; c4 < 9; ) { break; }


for(const c5 = 0, c6 = 0; c5 < c6; ) { break; }

//// [constDeclarations.js]
// No error
const c1 = false;
const c2 = 23;
const c3 = 0, c4 = "", c5 = null;
for (var c4 = 0; c4 < 9;) {
break;
}
for (var c5 = 0, c6 = 0; c5 < c6;) {
break;
}


//// [constDeclarations.d.ts]
Expand Down
14 changes: 14 additions & 0 deletions tests/baselines/reference/constDeclarations.types
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,17 @@ const c3 = 0, c4 :string = "", c5 = null;
>c4 : string
>c5 : any


for(const c4 = 0; c4 < 9; ) { break; }
>c4 : number
>c4 < 9 : boolean
>c4 : number


for(const c5 = 0, c6 = 0; c5 < c6; ) { break; }
>c5 : number
>c6 : number
>c5 < c6 : boolean
>c5 : number
>c6 : number

11 changes: 9 additions & 2 deletions tests/cases/compiler/constDeclarations-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ const c1;
const c2: number;
const c3, c4, c5 :string, c6; // error, missing initialicer

// error, wrong context
// error, can not be unintalized
for(const c in {}) { }

for(const c = 0; c < 9; c++) { }
// error, assigning to a const
for(const c8 = 0; c8 < 1; c8++) { }

// error, can not be unintalized
for(const c9; c9 < 1;) { }

// error, can not be unintalized
for(const c10 = 0, c11; c10 < 1;) { }
15 changes: 15 additions & 0 deletions tests/cases/compiler/constDeclarations-scopes2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// @target: ES6

// global
const c = "string";

var n: number;
var b: boolean;

// for scope
for (const c = 0; c < 10; n = c ) {
// for block
const c = false;
b = c;
}

6 changes: 6 additions & 0 deletions tests/cases/compiler/constDeclarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@
const c1 = false;
const c2: number = 23;
const c3 = 0, c4 :string = "", c5 = null;


for(const c4 = 0; c4 < 9; ) { break; }


for(const c5 = 0, c6 = 0; c5 < c6; ) { break; }

0 comments on commit 3e45601

Please sign in to comment.