From f915efa6d7108a91ce4763b9685a50aca126ca3c Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 3 Mar 2015 14:45:16 -0800 Subject: [PATCH] Emit for...of when LHS is expression --- src/compiler/emitter.ts | 26 ++++++++++++++----- tests/baselines/reference/ES5For-of10.js | 20 ++++++++++++++ tests/baselines/reference/ES5For-of11.js | 9 +++++++ tests/baselines/reference/ES5For-of12.js | 7 +++++ tests/baselines/reference/ES5For-of8.js | 16 ++++++++++++ tests/baselines/reference/ES5For-of9.js | 21 +++++++++++++++ .../reference/parserES5ForOfStatement2.js | 3 ++- .../reference/parserES5ForOfStatement21.js | 3 ++- .../for-ofStatements/ES5For-of10.ts | 7 +++++ .../for-ofStatements/ES5For-of11.ts | 2 ++ .../for-ofStatements/ES5For-of12.ts | 1 + .../statements/for-ofStatements/ES5For-of8.ts | 6 +++++ .../statements/for-ofStatements/ES5For-of9.ts | 8 ++++++ 13 files changed, 120 insertions(+), 9 deletions(-) create mode 100644 tests/baselines/reference/ES5For-of10.js create mode 100644 tests/baselines/reference/ES5For-of11.js create mode 100644 tests/baselines/reference/ES5For-of12.js create mode 100644 tests/baselines/reference/ES5For-of8.js create mode 100644 tests/baselines/reference/ES5For-of9.js create mode 100644 tests/cases/conformance/statements/for-ofStatements/ES5For-of10.ts create mode 100644 tests/cases/conformance/statements/for-ofStatements/ES5For-of11.ts create mode 100644 tests/cases/conformance/statements/for-ofStatements/ES5For-of12.ts create mode 100644 tests/cases/conformance/statements/for-ofStatements/ES5For-of8.ts create mode 100644 tests/cases/conformance/statements/for-ofStatements/ES5For-of9.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f80696b9836..995df97e971 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3491,10 +3491,10 @@ module ts { var endPos = emitToken(SyntaxKind.ForKeyword, node.pos); write(" "); endPos = emitToken(SyntaxKind.OpenParenToken, endPos); + write("var "); if (node.initializer.kind === SyntaxKind.VariableDeclarationList) { var variableDeclarationList = node.initializer; if (variableDeclarationList.declarations.length >= 1) { - write("var "); var decl = variableDeclarationList.declarations[0]; // TODO handle binding patterns emit(decl.name); @@ -3537,13 +3537,25 @@ module ts { // v = _a[_i]; if (decl) { emit(decl.name); - write(" = "); - emit(rhsReference) - write("["); - emit(counter); - write("];"); - writeLine(); } + else if (variableDeclarationList) { + // It's an empty declaration list. This can only happen in an error case, if the user wrote + // for (var of []) {} + var emptyDeclarationListTemp = createTempVariable(node, /*forLoopVariable*/ false); + write("var "); + emit(emptyDeclarationListTemp); + } + else { + // Initializer is an expression. Emit the expression in the body, so that it's + // evaluated on every iteration. + emit(node.initializer); + } + write(" = "); + emit(rhsReference) + write("["); + emit(counter); + write("];"); + writeLine(); if (node.statement.kind === SyntaxKind.Block) { emitLines((node.statement).statements); diff --git a/tests/baselines/reference/ES5For-of10.js b/tests/baselines/reference/ES5For-of10.js new file mode 100644 index 00000000000..ea081ed8ab0 --- /dev/null +++ b/tests/baselines/reference/ES5For-of10.js @@ -0,0 +1,20 @@ +//// [ES5For-of10.ts] +function foo() { + return { x: 0 }; +} +for (foo().x of []) { + for (foo().x of []) + var p = foo().x; +} + +//// [ES5For-of10.js] +function foo() { + return { x: 0 }; +} +for (var _i = 0, _a = []; _i < _a.length; _i++) { + foo().x = _a[_i]; + for (var _i_1 = 0, _a_1 = []; _i_1 < _a_1.length; _i_1++) { + foo().x = _a_1[_i_1]; + var p = foo().x; + } +} diff --git a/tests/baselines/reference/ES5For-of11.js b/tests/baselines/reference/ES5For-of11.js new file mode 100644 index 00000000000..dc1268524f1 --- /dev/null +++ b/tests/baselines/reference/ES5For-of11.js @@ -0,0 +1,9 @@ +//// [ES5For-of11.ts] +var v; +for (v of []) { } + +//// [ES5For-of11.js] +var v; +for (var _i = 0, _a = []; _i < _a.length; _i++) { + v = _a[_i]; +} diff --git a/tests/baselines/reference/ES5For-of12.js b/tests/baselines/reference/ES5For-of12.js new file mode 100644 index 00000000000..3dbdd30251c --- /dev/null +++ b/tests/baselines/reference/ES5For-of12.js @@ -0,0 +1,7 @@ +//// [ES5For-of12.ts] +for ([""] of []) { } + +//// [ES5For-of12.js] +for (var _i = 0, _a = []; _i < _a.length; _i++) { + [""] = _a[_i]; +} diff --git a/tests/baselines/reference/ES5For-of8.js b/tests/baselines/reference/ES5For-of8.js new file mode 100644 index 00000000000..a3d20b92056 --- /dev/null +++ b/tests/baselines/reference/ES5For-of8.js @@ -0,0 +1,16 @@ +//// [ES5For-of8.ts] +function foo() { + return { x: 0 }; +} +for (foo().x of []) { + var p = foo().x; +} + +//// [ES5For-of8.js] +function foo() { + return { x: 0 }; +} +for (var _i = 0, _a = []; _i < _a.length; _i++) { + foo().x = _a[_i]; + var p = foo().x; +} diff --git a/tests/baselines/reference/ES5For-of9.js b/tests/baselines/reference/ES5For-of9.js new file mode 100644 index 00000000000..f0c5142d4eb --- /dev/null +++ b/tests/baselines/reference/ES5For-of9.js @@ -0,0 +1,21 @@ +//// [ES5For-of9.ts] +function foo() { + return { x: 0 }; +} +for (foo().x of []) { + for (foo().x of []) { + var p = foo().x; + } +} + +//// [ES5For-of9.js] +function foo() { + return { x: 0 }; +} +for (var _i = 0, _a = []; _i < _a.length; _i++) { + foo().x = _a[_i]; + for (var _i_1 = 0, _a_1 = []; _i_1 < _a_1.length; _i_1++) { + foo().x = _a_1[_i_1]; + var p = foo().x; + } +} diff --git a/tests/baselines/reference/parserES5ForOfStatement2.js b/tests/baselines/reference/parserES5ForOfStatement2.js index 5b622e7b7b9..0acc5abb671 100644 --- a/tests/baselines/reference/parserES5ForOfStatement2.js +++ b/tests/baselines/reference/parserES5ForOfStatement2.js @@ -3,5 +3,6 @@ for (var of X) { } //// [parserES5ForOfStatement2.js] -for (_i = 0, _a = X; _i < _a.length; _i++) { +for (var _i = 0, _a = X; _i < _a.length; _i++) { + var _a_1 = _a[_i]; } diff --git a/tests/baselines/reference/parserES5ForOfStatement21.js b/tests/baselines/reference/parserES5ForOfStatement21.js index 08e2e173701..2a8734b90af 100644 --- a/tests/baselines/reference/parserES5ForOfStatement21.js +++ b/tests/baselines/reference/parserES5ForOfStatement21.js @@ -2,5 +2,6 @@ for (var of of) { } //// [parserES5ForOfStatement21.js] -for (_i = 0, _a = of; _i < _a.length; _i++) { +for (var _i = 0, _a = of; _i < _a.length; _i++) { + var _a_1 = _a[_i]; } diff --git a/tests/cases/conformance/statements/for-ofStatements/ES5For-of10.ts b/tests/cases/conformance/statements/for-ofStatements/ES5For-of10.ts new file mode 100644 index 00000000000..78cb7668dae --- /dev/null +++ b/tests/cases/conformance/statements/for-ofStatements/ES5For-of10.ts @@ -0,0 +1,7 @@ +function foo() { + return { x: 0 }; +} +for (foo().x of []) { + for (foo().x of []) + var p = foo().x; +} \ No newline at end of file diff --git a/tests/cases/conformance/statements/for-ofStatements/ES5For-of11.ts b/tests/cases/conformance/statements/for-ofStatements/ES5For-of11.ts new file mode 100644 index 00000000000..9a83efa5135 --- /dev/null +++ b/tests/cases/conformance/statements/for-ofStatements/ES5For-of11.ts @@ -0,0 +1,2 @@ +var v; +for (v of []) { } \ No newline at end of file diff --git a/tests/cases/conformance/statements/for-ofStatements/ES5For-of12.ts b/tests/cases/conformance/statements/for-ofStatements/ES5For-of12.ts new file mode 100644 index 00000000000..5fbfa31df5f --- /dev/null +++ b/tests/cases/conformance/statements/for-ofStatements/ES5For-of12.ts @@ -0,0 +1 @@ +for ([""] of []) { } \ No newline at end of file diff --git a/tests/cases/conformance/statements/for-ofStatements/ES5For-of8.ts b/tests/cases/conformance/statements/for-ofStatements/ES5For-of8.ts new file mode 100644 index 00000000000..5ad1fb7d58f --- /dev/null +++ b/tests/cases/conformance/statements/for-ofStatements/ES5For-of8.ts @@ -0,0 +1,6 @@ +function foo() { + return { x: 0 }; +} +for (foo().x of []) { + var p = foo().x; +} \ No newline at end of file diff --git a/tests/cases/conformance/statements/for-ofStatements/ES5For-of9.ts b/tests/cases/conformance/statements/for-ofStatements/ES5For-of9.ts new file mode 100644 index 00000000000..5e234df7319 --- /dev/null +++ b/tests/cases/conformance/statements/for-ofStatements/ES5For-of9.ts @@ -0,0 +1,8 @@ +function foo() { + return { x: 0 }; +} +for (foo().x of []) { + for (foo().x of []) { + var p = foo().x; + } +} \ No newline at end of file