Skip to content

Commit 5cbcafa

Browse files
Merge pull request #5477 from Microsoft/mutatedArrayInForOf
Always create a temporary for iterated expressions in a for-of loop
2 parents 16f69da + d5dd69b commit 5cbcafa

39 files changed

+207
-113
lines changed

src/compiler/emitter.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3614,10 +3614,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
36143614
//
36153615
// for (let v of arr) { }
36163616
//
3617-
// we don't want to emit a temporary variable for the RHS, just use it directly.
3618-
let rhsIsIdentifier = node.expression.kind === SyntaxKind.Identifier;
3617+
// we can't reuse 'arr' because it might be modified within the body of the loop.
36193618
let counter = createTempVariable(TempFlags._i);
3620-
let rhsReference = rhsIsIdentifier ? <Identifier>node.expression : createTempVariable(TempFlags.Auto);
3619+
let rhsReference = createSynthesizedNode(SyntaxKind.Identifier) as Identifier;
3620+
rhsReference.text = node.expression.kind === SyntaxKind.Identifier ?
3621+
makeUniqueName((<Identifier>node.expression).text) :
3622+
makeTempVariableName(TempFlags.Auto);
36213623

36223624
// This is the let keyword for the counter and rhsReference. The let keyword for
36233625
// the LHS will be emitted inside the body.
@@ -3629,15 +3631,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
36293631
write(" = 0");
36303632
emitEnd(node.expression);
36313633

3632-
if (!rhsIsIdentifier) {
3633-
// , _a = expr
3634-
write(", ");
3635-
emitStart(node.expression);
3636-
emitNodeWithoutSourceMap(rhsReference);
3637-
write(" = ");
3638-
emitNodeWithoutSourceMap(node.expression);
3639-
emitEnd(node.expression);
3640-
}
3634+
// , _a = expr
3635+
write(", ");
3636+
emitStart(node.expression);
3637+
emitNodeWithoutSourceMap(rhsReference);
3638+
write(" = ");
3639+
emitNodeWithoutSourceMap(node.expression);
3640+
emitEnd(node.expression);
36413641

36423642
write("; ");
36433643

tests/baselines/reference/ES3For-ofTypeCheck4.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ for (const v of union) { }
44

55
//// [ES3For-ofTypeCheck4.js]
66
var union;
7-
for (var _i = 0; _i < union.length; _i++) {
8-
var v = union[_i];
7+
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
8+
var v = union_1[_i];
99
}

tests/baselines/reference/ES3For-ofTypeCheck6.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ for (var v of union) { }
44

55
//// [ES3For-ofTypeCheck6.js]
66
var union;
7-
for (var _i = 0; _i < union.length; _i++) {
8-
var v = union[_i];
7+
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
8+
var v = union_1[_i];
99
}

tests/baselines/reference/ES5For-of24.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ for (var v of a) {
66

77
//// [ES5For-of24.js]
88
var a = [1, 2, 3];
9-
for (var _i = 0; _i < a.length; _i++) {
10-
var v = a[_i];
11-
var a_1 = 0;
9+
for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
10+
var v = a_1[_i];
11+
var a_2 = 0;
1212
}

tests/baselines/reference/ES5For-of25.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/baselines/reference/ES5For-of25.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/baselines/reference/ES5For-of25.sourcemap.txt

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ sourceFile:ES5For-of25.ts
2121
10> ^
2222
11> ^
2323
12> ^
24-
13> ^^^^^^^^^^^^^^^^^^^^^^->
24+
13> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^->
2525
1 >
2626
2 >var
2727
3 > a
@@ -47,58 +47,58 @@ sourceFile:ES5For-of25.ts
4747
11>Emitted(1, 18) Source(1, 18) + SourceIndex(0)
4848
12>Emitted(1, 19) Source(1, 19) + SourceIndex(0)
4949
---
50-
>>>for (var _i = 0; _i < a.length; _i++) {
50+
>>>for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
5151
1->
5252
2 >^^^
5353
3 > ^
5454
4 > ^
5555
5 > ^^^^^^^^^^
5656
6 > ^^
57-
7 > ^^^^^^^^^^^^^
58-
8 > ^^
59-
9 > ^^^^
60-
10> ^
57+
7 > ^^^^^^^
58+
8 > ^^
59+
9 > ^^^^^^^^^^^^^^^
60+
10> ^^
61+
11> ^^^^
62+
12> ^
6163
1->
6264
>
6365
2 >for
6466
3 >
6567
4 > (var v of
6668
5 > a
6769
6 >
68-
7 > var v
69-
8 >
70-
9 > var v of a
71-
10> )
70+
7 > a
71+
8 >
72+
9 > var v
73+
10>
74+
11> var v of a
75+
12> )
7276
1->Emitted(2, 1) Source(2, 1) + SourceIndex(0)
7377
2 >Emitted(2, 4) Source(2, 4) + SourceIndex(0)
7478
3 >Emitted(2, 5) Source(2, 5) + SourceIndex(0)
7579
4 >Emitted(2, 6) Source(2, 15) + SourceIndex(0)
7680
5 >Emitted(2, 16) Source(2, 16) + SourceIndex(0)
77-
6 >Emitted(2, 18) Source(2, 6) + SourceIndex(0)
78-
7 >Emitted(2, 31) Source(2, 11) + SourceIndex(0)
79-
8 >Emitted(2, 33) Source(2, 6) + SourceIndex(0)
80-
9 >Emitted(2, 37) Source(2, 16) + SourceIndex(0)
81-
10>Emitted(2, 38) Source(2, 17) + SourceIndex(0)
81+
6 >Emitted(2, 18) Source(2, 15) + SourceIndex(0)
82+
7 >Emitted(2, 25) Source(2, 16) + SourceIndex(0)
83+
8 >Emitted(2, 27) Source(2, 6) + SourceIndex(0)
84+
9 >Emitted(2, 42) Source(2, 11) + SourceIndex(0)
85+
10>Emitted(2, 44) Source(2, 6) + SourceIndex(0)
86+
11>Emitted(2, 48) Source(2, 16) + SourceIndex(0)
87+
12>Emitted(2, 49) Source(2, 17) + SourceIndex(0)
8288
---
83-
>>> var v = a[_i];
89+
>>> var v = a_1[_i];
8490
1 >^^^^
8591
2 > ^^^^
8692
3 > ^
87-
4 > ^^^
88-
5 > ^
89-
6 > ^^^^
93+
4 > ^^^^^^^^^^
9094
1 >
9195
2 > var
9296
3 > v
93-
4 > of
94-
5 > a
95-
6 >
97+
4 >
9698
1 >Emitted(3, 5) Source(2, 6) + SourceIndex(0)
9799
2 >Emitted(3, 9) Source(2, 10) + SourceIndex(0)
98100
3 >Emitted(3, 10) Source(2, 11) + SourceIndex(0)
99-
4 >Emitted(3, 13) Source(2, 15) + SourceIndex(0)
100-
5 >Emitted(3, 14) Source(2, 16) + SourceIndex(0)
101-
6 >Emitted(3, 18) Source(2, 11) + SourceIndex(0)
101+
4 >Emitted(3, 20) Source(2, 11) + SourceIndex(0)
102102
---
103103
>>> v;
104104
1 >^^^^

tests/baselines/reference/ES5For-of30.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ for ([a = 1, b = ""] of tuple) {
99
//// [ES5For-of30.js]
1010
var a, b;
1111
var tuple = [2, "3"];
12-
for (var _i = 0; _i < tuple.length; _i++) {
13-
_a = tuple[_i], _b = _a[0], a = _b === void 0 ? 1 : _b, _c = _a[1], b = _c === void 0 ? "" : _c;
12+
for (var _i = 0, tuple_1 = tuple; _i < tuple_1.length; _i++) {
13+
_a = tuple_1[_i], _b = _a[0], a = _b === void 0 ? 1 : _b, _c = _a[1], b = _c === void 0 ? "" : _c;
1414
a;
1515
b;
1616
}

tests/baselines/reference/ES5For-ofTypeCheck11.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ for (v of union) { }
66
//// [ES5For-ofTypeCheck11.js]
77
var union;
88
var v;
9-
for (var _i = 0; _i < union.length; _i++) {
10-
v = union[_i];
9+
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
10+
v = union_1[_i];
1111
}

tests/baselines/reference/ES5For-ofTypeCheck3.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ for (var v of tuple) { }
44

55
//// [ES5For-ofTypeCheck3.js]
66
var tuple = ["", 0];
7-
for (var _i = 0; _i < tuple.length; _i++) {
8-
var v = tuple[_i];
7+
for (var _i = 0, tuple_1 = tuple; _i < tuple_1.length; _i++) {
8+
var v = tuple_1[_i];
99
}

tests/baselines/reference/ES5For-ofTypeCheck4.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ for (const v of union) { }
44

55
//// [ES5For-ofTypeCheck4.js]
66
var union;
7-
for (var _i = 0; _i < union.length; _i++) {
8-
var v = union[_i];
7+
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
8+
var v = union_1[_i];
99
}

tests/baselines/reference/ES5For-ofTypeCheck5.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ for (var v of union) { }
44

55
//// [ES5For-ofTypeCheck5.js]
66
var union;
7-
for (var _i = 0; _i < union.length; _i++) {
8-
var v = union[_i];
7+
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
8+
var v = union_1[_i];
99
}

tests/baselines/reference/ES5For-ofTypeCheck6.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ for (var v of union) { }
44

55
//// [ES5For-ofTypeCheck6.js]
66
var union;
7-
for (var _i = 0; _i < union.length; _i++) {
8-
var v = union[_i];
7+
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
8+
var v = union_1[_i];
99
}

tests/baselines/reference/ES5For-ofTypeCheck7.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ for (var v of union) { }
44

55
//// [ES5For-ofTypeCheck7.js]
66
var union;
7-
for (var _i = 0; _i < union.length; _i++) {
8-
var v = union[_i];
7+
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
8+
var v = union_1[_i];
99
}

tests/baselines/reference/ES5For-ofTypeCheck8.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ for (v of union) { }
66
//// [ES5For-ofTypeCheck8.js]
77
var union;
88
var v;
9-
for (var _i = 0; _i < union.length; _i++) {
10-
v = union[_i];
9+
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
10+
v = union_1[_i];
1111
}

tests/baselines/reference/ES5For-ofTypeCheck9.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ for (let v of union) { }
44

55
//// [ES5For-ofTypeCheck9.js]
66
var union;
7-
for (var _i = 0; _i < union.length; _i++) {
8-
var v = union[_i];
7+
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
8+
var v = union_1[_i];
99
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [ES5for-of32.ts]
2+
3+
var array = [1,2,3];
4+
var sum = 0;
5+
6+
for (let num of array) {
7+
if (sum === 0) {
8+
array = [4,5,6]
9+
}
10+
11+
sum += num;
12+
}
13+
14+
//// [ES5for-of32.js]
15+
var array = [1, 2, 3];
16+
var sum = 0;
17+
for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
18+
var num = array_1[_i];
19+
if (sum === 0) {
20+
array = [4, 5, 6];
21+
}
22+
sum += num;
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/conformance/statements/for-ofStatements/ES5for-of32.ts ===
2+
3+
var array = [1,2,3];
4+
>array : Symbol(array, Decl(ES5for-of32.ts, 1, 3))
5+
6+
var sum = 0;
7+
>sum : Symbol(sum, Decl(ES5for-of32.ts, 2, 3))
8+
9+
for (let num of array) {
10+
>num : Symbol(num, Decl(ES5for-of32.ts, 4, 8))
11+
>array : Symbol(array, Decl(ES5for-of32.ts, 1, 3))
12+
13+
if (sum === 0) {
14+
>sum : Symbol(sum, Decl(ES5for-of32.ts, 2, 3))
15+
16+
array = [4,5,6]
17+
>array : Symbol(array, Decl(ES5for-of32.ts, 1, 3))
18+
}
19+
20+
sum += num;
21+
>sum : Symbol(sum, Decl(ES5for-of32.ts, 2, 3))
22+
>num : Symbol(num, Decl(ES5for-of32.ts, 4, 8))
23+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/conformance/statements/for-ofStatements/ES5for-of32.ts ===
2+
3+
var array = [1,2,3];
4+
>array : number[]
5+
>[1,2,3] : number[]
6+
>1 : number
7+
>2 : number
8+
>3 : number
9+
10+
var sum = 0;
11+
>sum : number
12+
>0 : number
13+
14+
for (let num of array) {
15+
>num : number
16+
>array : number[]
17+
18+
if (sum === 0) {
19+
>sum === 0 : boolean
20+
>sum : number
21+
>0 : number
22+
23+
array = [4,5,6]
24+
>array = [4,5,6] : number[]
25+
>array : number[]
26+
>[4,5,6] : number[]
27+
>4 : number
28+
>5 : number
29+
>6 : number
30+
}
31+
32+
sum += num;
33+
>sum += num : number
34+
>sum : number
35+
>num : number
36+
}

tests/baselines/reference/argumentsObjectIterator01_ES5.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ function doubleAndReturnAsArray(x: number, y: number, z: number): [number, numbe
1111
//// [argumentsObjectIterator01_ES5.js]
1212
function doubleAndReturnAsArray(x, y, z) {
1313
var result = [];
14-
for (var _i = 0; _i < arguments.length; _i++) {
15-
var arg = arguments[_i];
14+
for (var _i = 0, arguments_1 = arguments; _i < arguments_1.length; _i++) {
15+
var arg = arguments_1[_i];
1616
result.push(arg + arg);
1717
}
1818
return result;

tests/baselines/reference/emptyVariableDeclarationBindingPatterns01_ES5.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,22 +80,22 @@
8080
})();
8181
(function () {
8282
var ns = [];
83-
for (var _i = 0; _i < ns.length; _i++) {
84-
var _a = ns[_i];
83+
for (var _i = 0, ns_1 = ns; _i < ns_1.length; _i++) {
84+
var _a = ns_1[_i];
8585
}
86-
for (var _b = 0; _b < ns.length; _b++) {
87-
var _c = ns[_b];
86+
for (var _b = 0, ns_2 = ns; _b < ns_2.length; _b++) {
87+
var _c = ns_2[_b];
8888
}
89-
for (var _d = 0; _d < ns.length; _d++) {
90-
var _e = ns[_d];
89+
for (var _d = 0, ns_3 = ns; _d < ns_3.length; _d++) {
90+
var _e = ns_3[_d];
9191
}
92-
for (var _f = 0; _f < ns.length; _f++) {
93-
var _g = ns[_f];
92+
for (var _f = 0, ns_4 = ns; _f < ns_4.length; _f++) {
93+
var _g = ns_4[_f];
9494
}
95-
for (var _h = 0; _h < ns.length; _h++) {
96-
var _j = ns[_h];
95+
for (var _h = 0, ns_5 = ns; _h < ns_5.length; _h++) {
96+
var _j = ns_5[_h];
9797
}
98-
for (var _k = 0; _k < ns.length; _k++) {
99-
var _l = ns[_k];
98+
for (var _k = 0, ns_6 = ns; _k < ns_6.length; _k++) {
99+
var _l = ns_6[_k];
100100
}
101101
})();

tests/baselines/reference/parserES5ForOfStatement10.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ for (const v of X) {
33
}
44

55
//// [parserES5ForOfStatement10.js]
6-
for (var _i = 0; _i < X.length; _i++) {
7-
var v = X[_i];
6+
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
7+
var v = X_1[_i];
88
}

0 commit comments

Comments
 (0)