diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index c1398f75da605..ad016972d0d1e 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -2286,14 +2286,19 @@ namespace ts { } } + startLexicalEnvironment(); let loopBody = visitNode(node.statement, visitor, isStatement); + const lexicalEnvironment = endLexicalEnvironment(); const currentState = convertedLoopState; convertedLoopState = outerConvertedLoopState; - if (loopOutParameters.length) { + if (loopOutParameters.length || lexicalEnvironment) { const statements = isBlock(loopBody) ? (loopBody).statements.slice() : [loopBody]; - copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements); + if (loopOutParameters.length) { + copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements); + } + addRange(statements, lexicalEnvironment) loopBody = createBlock(statements, /*location*/ undefined, /*multiline*/ true); } diff --git a/tests/baselines/reference/capturedLetConstInLoop9.js b/tests/baselines/reference/capturedLetConstInLoop9.js index 84f9a021054e0..8f88855a9ade7 100644 --- a/tests/baselines/reference/capturedLetConstInLoop9.js +++ b/tests/baselines/reference/capturedLetConstInLoop9.js @@ -208,6 +208,7 @@ function foo() { } (function () { return b; }); return { value: 100 }; + var _a; }; for (var _c = 0, _d = []; _c < _d.length; _c++) { var b = _d[_c]; @@ -221,6 +222,7 @@ function foo() { } } (function () { return a; }); + var _b; }; var arguments_1 = arguments, x, z, x1, z1; l0: for (var _i = 0, _a = []; _i < _a.length; _i++) { @@ -238,7 +240,6 @@ function foo() { use(z); use(x1); use(z1); - var _b, _a; } function foo2() { for (var _i = 0, _a = []; _i < _a.length; _i++) { diff --git a/tests/baselines/reference/newLexicalEnvironmentForConvertedLoop.js b/tests/baselines/reference/newLexicalEnvironmentForConvertedLoop.js new file mode 100644 index 0000000000000..8525352d41559 --- /dev/null +++ b/tests/baselines/reference/newLexicalEnvironmentForConvertedLoop.js @@ -0,0 +1,31 @@ +//// [newLexicalEnvironmentForConvertedLoop.ts] +function baz(x: any) { + return [[x, x]]; +} + +function foo(set: any) { + for (const [value, i] of baz(set.values)) { + const bar: any = []; + (() => bar); + + set.values.push(...[]); + } +}; + +//// [newLexicalEnvironmentForConvertedLoop.js] +function baz(x) { + return [[x, x]]; +} +function foo(set) { + var _loop_1 = function (value, i) { + var bar = []; + (function () { return bar; }); + (_a = set.values).push.apply(_a, []); + var _a; + }; + for (var _i = 0, _a = baz(set.values); _i < _a.length; _i++) { + var _b = _a[_i], value = _b[0], i = _b[1]; + _loop_1(value, i); + } +} +; diff --git a/tests/baselines/reference/newLexicalEnvironmentForConvertedLoop.symbols b/tests/baselines/reference/newLexicalEnvironmentForConvertedLoop.symbols new file mode 100644 index 0000000000000..19d657218d66a --- /dev/null +++ b/tests/baselines/reference/newLexicalEnvironmentForConvertedLoop.symbols @@ -0,0 +1,30 @@ +=== tests/cases/compiler/newLexicalEnvironmentForConvertedLoop.ts === +function baz(x: any) { +>baz : Symbol(baz, Decl(newLexicalEnvironmentForConvertedLoop.ts, 0, 0)) +>x : Symbol(x, Decl(newLexicalEnvironmentForConvertedLoop.ts, 0, 13)) + + return [[x, x]]; +>x : Symbol(x, Decl(newLexicalEnvironmentForConvertedLoop.ts, 0, 13)) +>x : Symbol(x, Decl(newLexicalEnvironmentForConvertedLoop.ts, 0, 13)) +} + +function foo(set: any) { +>foo : Symbol(foo, Decl(newLexicalEnvironmentForConvertedLoop.ts, 2, 1)) +>set : Symbol(set, Decl(newLexicalEnvironmentForConvertedLoop.ts, 4, 13)) + + for (const [value, i] of baz(set.values)) { +>value : Symbol(value, Decl(newLexicalEnvironmentForConvertedLoop.ts, 5, 14)) +>i : Symbol(i, Decl(newLexicalEnvironmentForConvertedLoop.ts, 5, 20)) +>baz : Symbol(baz, Decl(newLexicalEnvironmentForConvertedLoop.ts, 0, 0)) +>set : Symbol(set, Decl(newLexicalEnvironmentForConvertedLoop.ts, 4, 13)) + + const bar: any = []; +>bar : Symbol(bar, Decl(newLexicalEnvironmentForConvertedLoop.ts, 6, 9)) + + (() => bar); +>bar : Symbol(bar, Decl(newLexicalEnvironmentForConvertedLoop.ts, 6, 9)) + + set.values.push(...[]); +>set : Symbol(set, Decl(newLexicalEnvironmentForConvertedLoop.ts, 4, 13)) + } +}; diff --git a/tests/baselines/reference/newLexicalEnvironmentForConvertedLoop.types b/tests/baselines/reference/newLexicalEnvironmentForConvertedLoop.types new file mode 100644 index 0000000000000..dcc6f1375a345 --- /dev/null +++ b/tests/baselines/reference/newLexicalEnvironmentForConvertedLoop.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/newLexicalEnvironmentForConvertedLoop.ts === +function baz(x: any) { +>baz : (x: any) => any[][] +>x : any + + return [[x, x]]; +>[[x, x]] : any[][] +>[x, x] : any[] +>x : any +>x : any +} + +function foo(set: any) { +>foo : (set: any) => void +>set : any + + for (const [value, i] of baz(set.values)) { +>value : any +>i : any +>baz(set.values) : any[][] +>baz : (x: any) => any[][] +>set.values : any +>set : any +>values : any + + const bar: any = []; +>bar : any +>[] : undefined[] + + (() => bar); +>(() => bar) : () => any +>() => bar : () => any +>bar : any + + set.values.push(...[]); +>set.values.push(...[]) : any +>set.values.push : any +>set.values : any +>set : any +>values : any +>push : any +>...[] : undefined +>[] : undefined[] + } +}; diff --git a/tests/cases/compiler/newLexicalEnvironmentForConvertedLoop.ts b/tests/cases/compiler/newLexicalEnvironmentForConvertedLoop.ts new file mode 100644 index 0000000000000..25b351d62a1f8 --- /dev/null +++ b/tests/cases/compiler/newLexicalEnvironmentForConvertedLoop.ts @@ -0,0 +1,13 @@ +// @target: es5 +function baz(x: any) { + return [[x, x]]; +} + +function foo(set: any) { + for (const [value, i] of baz(set.values)) { + const bar: any = []; + (() => bar); + + set.values.push(...[]); + } +}; \ No newline at end of file