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
}

0 commit comments

Comments
 (0)