Merge pull request #5477 from Microsoft/mutatedArrayInForOf

Always create a temporary for iterated expressions in a for-of loop
This commit is contained in:
Daniel Rosenwasser
2015-10-30 17:42:45 -07:00
39 changed files with 207 additions and 113 deletions

View File

@@ -3614,10 +3614,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
//
// for (let v of arr) { }
//
// we don't want to emit a temporary variable for the RHS, just use it directly.
let rhsIsIdentifier = node.expression.kind === SyntaxKind.Identifier;
// we can't reuse 'arr' because it might be modified within the body of the loop.
let counter = createTempVariable(TempFlags._i);
let rhsReference = rhsIsIdentifier ? <Identifier>node.expression : createTempVariable(TempFlags.Auto);
let rhsReference = createSynthesizedNode(SyntaxKind.Identifier) as Identifier;
rhsReference.text = node.expression.kind === SyntaxKind.Identifier ?
makeUniqueName((<Identifier>node.expression).text) :
makeTempVariableName(TempFlags.Auto);
// This is the let keyword for the counter and rhsReference. The let keyword for
// the LHS will be emitted inside the body.
@@ -3629,15 +3631,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(" = 0");
emitEnd(node.expression);
if (!rhsIsIdentifier) {
// , _a = expr
write(", ");
emitStart(node.expression);
emitNodeWithoutSourceMap(rhsReference);
write(" = ");
emitNodeWithoutSourceMap(node.expression);
emitEnd(node.expression);
}
// , _a = expr
write(", ");
emitStart(node.expression);
emitNodeWithoutSourceMap(rhsReference);
write(" = ");
emitNodeWithoutSourceMap(node.expression);
emitEnd(node.expression);
write("; ");

View File

@@ -4,6 +4,6 @@ for (const v of union) { }
//// [ES3For-ofTypeCheck4.js]
var union;
for (var _i = 0; _i < union.length; _i++) {
var v = union[_i];
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
var v = union_1[_i];
}

View File

@@ -4,6 +4,6 @@ for (var v of union) { }
//// [ES3For-ofTypeCheck6.js]
var union;
for (var _i = 0; _i < union.length; _i++) {
var v = union[_i];
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
var v = union_1[_i];
}

View File

@@ -6,7 +6,7 @@ for (var v of a) {
//// [ES5For-of24.js]
var a = [1, 2, 3];
for (var _i = 0; _i < a.length; _i++) {
var v = a[_i];
var a_1 = 0;
for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
var v = a_1[_i];
var a_2 = 0;
}

View File

@@ -7,8 +7,8 @@ for (var v of a) {
//// [ES5For-of25.js]
var a = [1, 2, 3];
for (var _i = 0; _i < a.length; _i++) {
var v = a[_i];
for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
var v = a_1[_i];
v;
a;
}

View File

@@ -1,2 +1,2 @@
//// [ES5For-of25.js.map]
{"version":3,"file":"ES5For-of25.js","sourceRoot":"","sources":["ES5For-of25.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAClB,GAAG,CAAC,CAAU,UAAC,EAAV,aAAK,EAAL,IAAU,CAAC;IAAX,IAAI,CAAC,GAAI,CAAC,IAAL;IACN,CAAC,CAAC;IACF,CAAC,CAAC;CACL"}
{"version":3,"file":"ES5For-of25.js","sourceRoot":"","sources":["ES5For-of25.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAClB,GAAG,CAAC,CAAU,UAAC,EAAD,OAAC,EAAV,eAAK,EAAL,IAAU,CAAC;IAAX,IAAI,CAAC,UAAA;IACN,CAAC,CAAC;IACF,CAAC,CAAC;CACL"}

View File

@@ -21,7 +21,7 @@ sourceFile:ES5For-of25.ts
10> ^
11> ^
12> ^
13> ^^^^^^^^^^^^^^^^^^^^^^->
13> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^->
1 >
2 >var
3 > a
@@ -47,17 +47,19 @@ sourceFile:ES5For-of25.ts
11>Emitted(1, 18) Source(1, 18) + SourceIndex(0)
12>Emitted(1, 19) Source(1, 19) + SourceIndex(0)
---
>>>for (var _i = 0; _i < a.length; _i++) {
>>>for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
1->
2 >^^^
3 > ^
4 > ^
5 > ^^^^^^^^^^
6 > ^^
7 > ^^^^^^^^^^^^^
8 > ^^
9 > ^^^^
10> ^
7 > ^^^^^^^
8 > ^^
9 > ^^^^^^^^^^^^^^^
10> ^^
11> ^^^^
12> ^
1->
>
2 >for
@@ -65,40 +67,38 @@ sourceFile:ES5For-of25.ts
4 > (var v of
5 > a
6 >
7 > var v
8 >
9 > var v of a
10> )
7 > a
8 >
9 > var v
10>
11> var v of a
12> )
1->Emitted(2, 1) Source(2, 1) + SourceIndex(0)
2 >Emitted(2, 4) Source(2, 4) + SourceIndex(0)
3 >Emitted(2, 5) Source(2, 5) + SourceIndex(0)
4 >Emitted(2, 6) Source(2, 15) + SourceIndex(0)
5 >Emitted(2, 16) Source(2, 16) + SourceIndex(0)
6 >Emitted(2, 18) Source(2, 6) + SourceIndex(0)
7 >Emitted(2, 31) Source(2, 11) + SourceIndex(0)
8 >Emitted(2, 33) Source(2, 6) + SourceIndex(0)
9 >Emitted(2, 37) Source(2, 16) + SourceIndex(0)
10>Emitted(2, 38) Source(2, 17) + SourceIndex(0)
6 >Emitted(2, 18) Source(2, 15) + SourceIndex(0)
7 >Emitted(2, 25) Source(2, 16) + SourceIndex(0)
8 >Emitted(2, 27) Source(2, 6) + SourceIndex(0)
9 >Emitted(2, 42) Source(2, 11) + SourceIndex(0)
10>Emitted(2, 44) Source(2, 6) + SourceIndex(0)
11>Emitted(2, 48) Source(2, 16) + SourceIndex(0)
12>Emitted(2, 49) Source(2, 17) + SourceIndex(0)
---
>>> var v = a[_i];
>>> var v = a_1[_i];
1 >^^^^
2 > ^^^^
3 > ^
4 > ^^^
5 > ^
6 > ^^^^
4 > ^^^^^^^^^^
1 >
2 > var
3 > v
4 > of
5 > a
6 >
4 >
1 >Emitted(3, 5) Source(2, 6) + SourceIndex(0)
2 >Emitted(3, 9) Source(2, 10) + SourceIndex(0)
3 >Emitted(3, 10) Source(2, 11) + SourceIndex(0)
4 >Emitted(3, 13) Source(2, 15) + SourceIndex(0)
5 >Emitted(3, 14) Source(2, 16) + SourceIndex(0)
6 >Emitted(3, 18) Source(2, 11) + SourceIndex(0)
4 >Emitted(3, 20) Source(2, 11) + SourceIndex(0)
---
>>> v;
1 >^^^^

View File

@@ -9,8 +9,8 @@ for ([a = 1, b = ""] of tuple) {
//// [ES5For-of30.js]
var a, b;
var tuple = [2, "3"];
for (var _i = 0; _i < tuple.length; _i++) {
_a = tuple[_i], _b = _a[0], a = _b === void 0 ? 1 : _b, _c = _a[1], b = _c === void 0 ? "" : _c;
for (var _i = 0, tuple_1 = tuple; _i < tuple_1.length; _i++) {
_a = tuple_1[_i], _b = _a[0], a = _b === void 0 ? 1 : _b, _c = _a[1], b = _c === void 0 ? "" : _c;
a;
b;
}

View File

@@ -6,6 +6,6 @@ for (v of union) { }
//// [ES5For-ofTypeCheck11.js]
var union;
var v;
for (var _i = 0; _i < union.length; _i++) {
v = union[_i];
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
v = union_1[_i];
}

View File

@@ -4,6 +4,6 @@ for (var v of tuple) { }
//// [ES5For-ofTypeCheck3.js]
var tuple = ["", 0];
for (var _i = 0; _i < tuple.length; _i++) {
var v = tuple[_i];
for (var _i = 0, tuple_1 = tuple; _i < tuple_1.length; _i++) {
var v = tuple_1[_i];
}

View File

@@ -4,6 +4,6 @@ for (const v of union) { }
//// [ES5For-ofTypeCheck4.js]
var union;
for (var _i = 0; _i < union.length; _i++) {
var v = union[_i];
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
var v = union_1[_i];
}

View File

@@ -4,6 +4,6 @@ for (var v of union) { }
//// [ES5For-ofTypeCheck5.js]
var union;
for (var _i = 0; _i < union.length; _i++) {
var v = union[_i];
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
var v = union_1[_i];
}

View File

@@ -4,6 +4,6 @@ for (var v of union) { }
//// [ES5For-ofTypeCheck6.js]
var union;
for (var _i = 0; _i < union.length; _i++) {
var v = union[_i];
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
var v = union_1[_i];
}

View File

@@ -4,6 +4,6 @@ for (var v of union) { }
//// [ES5For-ofTypeCheck7.js]
var union;
for (var _i = 0; _i < union.length; _i++) {
var v = union[_i];
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
var v = union_1[_i];
}

View File

@@ -6,6 +6,6 @@ for (v of union) { }
//// [ES5For-ofTypeCheck8.js]
var union;
var v;
for (var _i = 0; _i < union.length; _i++) {
v = union[_i];
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
v = union_1[_i];
}

View File

@@ -4,6 +4,6 @@ for (let v of union) { }
//// [ES5For-ofTypeCheck9.js]
var union;
for (var _i = 0; _i < union.length; _i++) {
var v = union[_i];
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
var v = union_1[_i];
}

View File

@@ -0,0 +1,23 @@
//// [ES5for-of32.ts]
var array = [1,2,3];
var sum = 0;
for (let num of array) {
if (sum === 0) {
array = [4,5,6]
}
sum += num;
}
//// [ES5for-of32.js]
var array = [1, 2, 3];
var sum = 0;
for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
var num = array_1[_i];
if (sum === 0) {
array = [4, 5, 6];
}
sum += num;
}

View File

@@ -0,0 +1,23 @@
=== tests/cases/conformance/statements/for-ofStatements/ES5for-of32.ts ===
var array = [1,2,3];
>array : Symbol(array, Decl(ES5for-of32.ts, 1, 3))
var sum = 0;
>sum : Symbol(sum, Decl(ES5for-of32.ts, 2, 3))
for (let num of array) {
>num : Symbol(num, Decl(ES5for-of32.ts, 4, 8))
>array : Symbol(array, Decl(ES5for-of32.ts, 1, 3))
if (sum === 0) {
>sum : Symbol(sum, Decl(ES5for-of32.ts, 2, 3))
array = [4,5,6]
>array : Symbol(array, Decl(ES5for-of32.ts, 1, 3))
}
sum += num;
>sum : Symbol(sum, Decl(ES5for-of32.ts, 2, 3))
>num : Symbol(num, Decl(ES5for-of32.ts, 4, 8))
}

View File

@@ -0,0 +1,36 @@
=== tests/cases/conformance/statements/for-ofStatements/ES5for-of32.ts ===
var array = [1,2,3];
>array : number[]
>[1,2,3] : number[]
>1 : number
>2 : number
>3 : number
var sum = 0;
>sum : number
>0 : number
for (let num of array) {
>num : number
>array : number[]
if (sum === 0) {
>sum === 0 : boolean
>sum : number
>0 : number
array = [4,5,6]
>array = [4,5,6] : number[]
>array : number[]
>[4,5,6] : number[]
>4 : number
>5 : number
>6 : number
}
sum += num;
>sum += num : number
>sum : number
>num : number
}

View File

@@ -11,8 +11,8 @@ function doubleAndReturnAsArray(x: number, y: number, z: number): [number, numbe
//// [argumentsObjectIterator01_ES5.js]
function doubleAndReturnAsArray(x, y, z) {
var result = [];
for (var _i = 0; _i < arguments.length; _i++) {
var arg = arguments[_i];
for (var _i = 0, arguments_1 = arguments; _i < arguments_1.length; _i++) {
var arg = arguments_1[_i];
result.push(arg + arg);
}
return result;

View File

@@ -80,22 +80,22 @@
})();
(function () {
var ns = [];
for (var _i = 0; _i < ns.length; _i++) {
var _a = ns[_i];
for (var _i = 0, ns_1 = ns; _i < ns_1.length; _i++) {
var _a = ns_1[_i];
}
for (var _b = 0; _b < ns.length; _b++) {
var _c = ns[_b];
for (var _b = 0, ns_2 = ns; _b < ns_2.length; _b++) {
var _c = ns_2[_b];
}
for (var _d = 0; _d < ns.length; _d++) {
var _e = ns[_d];
for (var _d = 0, ns_3 = ns; _d < ns_3.length; _d++) {
var _e = ns_3[_d];
}
for (var _f = 0; _f < ns.length; _f++) {
var _g = ns[_f];
for (var _f = 0, ns_4 = ns; _f < ns_4.length; _f++) {
var _g = ns_4[_f];
}
for (var _h = 0; _h < ns.length; _h++) {
var _j = ns[_h];
for (var _h = 0, ns_5 = ns; _h < ns_5.length; _h++) {
var _j = ns_5[_h];
}
for (var _k = 0; _k < ns.length; _k++) {
var _l = ns[_k];
for (var _k = 0, ns_6 = ns; _k < ns_6.length; _k++) {
var _l = ns_6[_k];
}
})();

View File

@@ -3,6 +3,6 @@ for (const v of X) {
}
//// [parserES5ForOfStatement10.js]
for (var _i = 0; _i < X.length; _i++) {
var v = X[_i];
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var v = X_1[_i];
}

View File

@@ -3,6 +3,6 @@ for (const [a, b] of X) {
}
//// [parserES5ForOfStatement11.js]
for (var _i = 0; _i < X.length; _i++) {
var _a = X[_i], a = _a[0], b = _a[1];
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var _a = X_1[_i], a = _a[0], b = _a[1];
}

View File

@@ -3,6 +3,6 @@ for (const {a, b} of X) {
}
//// [parserES5ForOfStatement12.js]
for (var _i = 0; _i < X.length; _i++) {
var _a = X[_i], a = _a.a, b = _a.b;
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var _a = X_1[_i], a = _a.a, b = _a.b;
}

View File

@@ -3,6 +3,6 @@ for (let {a, b} of X) {
}
//// [parserES5ForOfStatement13.js]
for (var _i = 0; _i < X.length; _i++) {
var _a = X[_i], a = _a.a, b = _a.b;
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var _a = X_1[_i], a = _a.a, b = _a.b;
}

View File

@@ -3,6 +3,6 @@ for (let [a, b] of X) {
}
//// [parserES5ForOfStatement14.js]
for (var _i = 0; _i < X.length; _i++) {
var _a = X[_i], a = _a[0], b = _a[1];
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var _a = X_1[_i], a = _a[0], b = _a[1];
}

View File

@@ -3,6 +3,6 @@ for (var [a, b] of X) {
}
//// [parserES5ForOfStatement15.js]
for (var _i = 0; _i < X.length; _i++) {
var _a = X[_i], a = _a[0], b = _a[1];
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var _a = X_1[_i], a = _a[0], b = _a[1];
}

View File

@@ -3,6 +3,6 @@ for (var {a, b} of X) {
}
//// [parserES5ForOfStatement16.js]
for (var _i = 0; _i < X.length; _i++) {
var _a = X[_i], a = _a.a, b = _a.b;
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var _a = X_1[_i], a = _a.a, b = _a.b;
}

View File

@@ -2,6 +2,6 @@
for (var of of of) { }
//// [parserES5ForOfStatement18.js]
for (var _i = 0; _i < of.length; _i++) {
var of = of[_i];
for (var _i = 0, of_1 = of; _i < of_1.length; _i++) {
var of = of_1[_i];
}

View File

@@ -3,6 +3,6 @@ for (var of X) {
}
//// [parserES5ForOfStatement2.js]
for (var _i = 0; _i < X.length; _i++) {
var _a = X[_i];
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var _a = X_1[_i];
}

View File

@@ -2,6 +2,6 @@
for (var of of) { }
//// [parserES5ForOfStatement21.js]
for (var _i = 0; _i < of.length; _i++) {
var _a = of[_i];
for (var _i = 0, of_1 = of; _i < of_1.length; _i++) {
var _a = of_1[_i];
}

View File

@@ -3,6 +3,6 @@ for (var a, b of X) {
}
//// [parserES5ForOfStatement3.js]
for (var _i = 0; _i < X.length; _i++) {
var a = X[_i];
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var a = X_1[_i];
}

View File

@@ -3,6 +3,6 @@ for (var a = 1 of X) {
}
//// [parserES5ForOfStatement4.js]
for (var _i = 0; _i < X.length; _i++) {
var a = 1 = X[_i];
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var a = 1 = X_1[_i];
}

View File

@@ -3,6 +3,6 @@ for (var a: number of X) {
}
//// [parserES5ForOfStatement5.js]
for (var _i = 0; _i < X.length; _i++) {
var a = X[_i];
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var a = X_1[_i];
}

View File

@@ -3,6 +3,6 @@ for (var a = 1, b = 2 of X) {
}
//// [parserES5ForOfStatement6.js]
for (var _i = 0; _i < X.length; _i++) {
var a = 1 = X[_i];
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var a = 1 = X_1[_i];
}

View File

@@ -3,6 +3,6 @@ for (var a: number = 1, b: string = "" of X) {
}
//// [parserES5ForOfStatement7.js]
for (var _i = 0; _i < X.length; _i++) {
var a = 1 = X[_i];
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var a = 1 = X_1[_i];
}

View File

@@ -3,6 +3,6 @@ for (var v of X) {
}
//// [parserES5ForOfStatement8.js]
for (var _i = 0; _i < X.length; _i++) {
var v = X[_i];
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var v = X_1[_i];
}

View File

@@ -3,6 +3,6 @@ for (let v of X) {
}
//// [parserES5ForOfStatement9.js]
for (var _i = 0; _i < X.length; _i++) {
var v = X[_i];
for (var _i = 0, X_1 = X; _i < X_1.length; _i++) {
var v = X_1[_i];
}

View File

@@ -0,0 +1,12 @@
//@target: ES5
var array = [1,2,3];
var sum = 0;
for (let num of array) {
if (sum === 0) {
array = [4,5,6]
}
sum += num;
}