diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 7e3ee93f2f64d..8e474546ec9f7 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4218,12 +4218,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge function emitVariableDeclaration(node: VariableDeclaration) { if (isBindingPattern(node.name)) { - if (languageVersion < ScriptTarget.ES6) { - emitDestructuring(node, /*isAssignmentExpressionStatement*/ false); - } - else { + const isExported = getCombinedNodeFlags(node) & NodeFlags.Export; + if (languageVersion >= ScriptTarget.ES6 && (!isExported || modulekind === ModuleKind.ES6)) { + // emit ES6 destructuring only if target module is ES6 or variable is not exported + // exported variables in CJS/AMD are prefixed with 'exports.' so result javascript { exports.toString } = 1; is illegal + + const isTopLevelDeclarationInSystemModule = + modulekind === ModuleKind.System && + shouldHoistVariable(node, /*checkIfSourceFileLevelDecl*/true); + + if (isTopLevelDeclarationInSystemModule) { + // In System modules top level variables are hoisted + // so variable declarations with destructuring are turned into destructuring assignments. + // As a result, they will need parentheses to disambiguate object binding assignments from blocks. + write("("); + } + emit(node.name); emitOptional(" = ", node.initializer); + + if (isTopLevelDeclarationInSystemModule) { + write(")"); + } + } + else { + emitDestructuring(node, /*isAssignmentExpressionStatement*/ false); } } else { diff --git a/tests/baselines/reference/destructuringInVariableDeclarations1.js b/tests/baselines/reference/destructuringInVariableDeclarations1.js new file mode 100644 index 0000000000000..707218b41e295 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations1.js @@ -0,0 +1,13 @@ +//// [destructuringInVariableDeclarations1.ts] +export let { toString } = 1; +{ + let { toFixed } = 1; +} + + +//// [destructuringInVariableDeclarations1.js] +"use strict"; +exports.toString = (1).toString; +{ + let { toFixed } = 1; +} diff --git a/tests/baselines/reference/destructuringInVariableDeclarations1.symbols b/tests/baselines/reference/destructuringInVariableDeclarations1.symbols new file mode 100644 index 0000000000000..4043bcc734d4a --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations1.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations1.ts === +export let { toString } = 1; +>toString : Symbol(toString, Decl(destructuringInVariableDeclarations1.ts, 0, 12)) +{ + let { toFixed } = 1; +>toFixed : Symbol(toFixed, Decl(destructuringInVariableDeclarations1.ts, 2, 9)) +} + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations1.types b/tests/baselines/reference/destructuringInVariableDeclarations1.types new file mode 100644 index 0000000000000..84a60c844a36d --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations1.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations1.ts === +export let { toString } = 1; +>toString : (radix?: number) => string +>1 : number +{ + let { toFixed } = 1; +>toFixed : (fractionDigits?: number) => string +>1 : number +} + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations2.js b/tests/baselines/reference/destructuringInVariableDeclarations2.js new file mode 100644 index 0000000000000..9c1366bd8e05c --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations2.js @@ -0,0 +1,14 @@ +//// [destructuringInVariableDeclarations2.ts] +let { toString } = 1; +{ + let { toFixed } = 1; +} +export {}; + + +//// [destructuringInVariableDeclarations2.js] +"use strict"; +let { toString } = 1; +{ + let { toFixed } = 1; +} diff --git a/tests/baselines/reference/destructuringInVariableDeclarations2.symbols b/tests/baselines/reference/destructuringInVariableDeclarations2.symbols new file mode 100644 index 0000000000000..f05ddf0c75854 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations2.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations2.ts === +let { toString } = 1; +>toString : Symbol(toString, Decl(destructuringInVariableDeclarations2.ts, 0, 5)) +{ + let { toFixed } = 1; +>toFixed : Symbol(toFixed, Decl(destructuringInVariableDeclarations2.ts, 2, 9)) +} +export {}; + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations2.types b/tests/baselines/reference/destructuringInVariableDeclarations2.types new file mode 100644 index 0000000000000..b7456d3028509 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations2.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations2.ts === +let { toString } = 1; +>toString : (radix?: number) => string +>1 : number +{ + let { toFixed } = 1; +>toFixed : (fractionDigits?: number) => string +>1 : number +} +export {}; + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations3.js b/tests/baselines/reference/destructuringInVariableDeclarations3.js new file mode 100644 index 0000000000000..8da039fe98edc --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations3.js @@ -0,0 +1,15 @@ +//// [destructuringInVariableDeclarations3.ts] +export let { toString } = 1; +{ + let { toFixed } = 1; +} + + +//// [destructuringInVariableDeclarations3.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + exports.toString = (1).toString; + { + let { toFixed } = 1; + } +}); diff --git a/tests/baselines/reference/destructuringInVariableDeclarations3.symbols b/tests/baselines/reference/destructuringInVariableDeclarations3.symbols new file mode 100644 index 0000000000000..84b131a8ad00b --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations3.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations3.ts === +export let { toString } = 1; +>toString : Symbol(toString, Decl(destructuringInVariableDeclarations3.ts, 0, 12)) +{ + let { toFixed } = 1; +>toFixed : Symbol(toFixed, Decl(destructuringInVariableDeclarations3.ts, 2, 9)) +} + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations3.types b/tests/baselines/reference/destructuringInVariableDeclarations3.types new file mode 100644 index 0000000000000..970d6deb1edac --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations3.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations3.ts === +export let { toString } = 1; +>toString : (radix?: number) => string +>1 : number +{ + let { toFixed } = 1; +>toFixed : (fractionDigits?: number) => string +>1 : number +} + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations4.js b/tests/baselines/reference/destructuringInVariableDeclarations4.js new file mode 100644 index 0000000000000..d4b30405143b9 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations4.js @@ -0,0 +1,16 @@ +//// [destructuringInVariableDeclarations4.ts] +let { toString } = 1; +{ + let { toFixed } = 1; +} +export {}; + + +//// [destructuringInVariableDeclarations4.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + let { toString } = 1; + { + let { toFixed } = 1; + } +}); diff --git a/tests/baselines/reference/destructuringInVariableDeclarations4.symbols b/tests/baselines/reference/destructuringInVariableDeclarations4.symbols new file mode 100644 index 0000000000000..e599d7c579315 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations4.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations4.ts === +let { toString } = 1; +>toString : Symbol(toString, Decl(destructuringInVariableDeclarations4.ts, 0, 5)) +{ + let { toFixed } = 1; +>toFixed : Symbol(toFixed, Decl(destructuringInVariableDeclarations4.ts, 2, 9)) +} +export {}; + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations4.types b/tests/baselines/reference/destructuringInVariableDeclarations4.types new file mode 100644 index 0000000000000..628fe7a95620a --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations4.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations4.ts === +let { toString } = 1; +>toString : (radix?: number) => string +>1 : number +{ + let { toFixed } = 1; +>toFixed : (fractionDigits?: number) => string +>1 : number +} +export {}; + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations5.js b/tests/baselines/reference/destructuringInVariableDeclarations5.js new file mode 100644 index 0000000000000..8938757adc2d0 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations5.js @@ -0,0 +1,22 @@ +//// [destructuringInVariableDeclarations5.ts] +export let { toString } = 1; +{ + let { toFixed } = 1; +} + + +//// [destructuringInVariableDeclarations5.js] +(function (factory) { + if (typeof module === 'object' && typeof module.exports === 'object') { + var v = factory(require, exports); if (v !== undefined) module.exports = v; + } + else if (typeof define === 'function' && define.amd) { + define(["require", "exports"], factory); + } +})(function (require, exports) { + "use strict"; + exports.toString = (1).toString; + { + let { toFixed } = 1; + } +}); diff --git a/tests/baselines/reference/destructuringInVariableDeclarations5.symbols b/tests/baselines/reference/destructuringInVariableDeclarations5.symbols new file mode 100644 index 0000000000000..6071992861744 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations5.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations5.ts === +export let { toString } = 1; +>toString : Symbol(toString, Decl(destructuringInVariableDeclarations5.ts, 0, 12)) +{ + let { toFixed } = 1; +>toFixed : Symbol(toFixed, Decl(destructuringInVariableDeclarations5.ts, 2, 9)) +} + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations5.types b/tests/baselines/reference/destructuringInVariableDeclarations5.types new file mode 100644 index 0000000000000..9a890916d1772 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations5.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations5.ts === +export let { toString } = 1; +>toString : (radix?: number) => string +>1 : number +{ + let { toFixed } = 1; +>toFixed : (fractionDigits?: number) => string +>1 : number +} + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations6.js b/tests/baselines/reference/destructuringInVariableDeclarations6.js new file mode 100644 index 0000000000000..b9dddb673cf57 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations6.js @@ -0,0 +1,23 @@ +//// [destructuringInVariableDeclarations6.ts] +let { toString } = 1; +{ + let { toFixed } = 1; +} +export {}; + + +//// [destructuringInVariableDeclarations6.js] +(function (factory) { + if (typeof module === 'object' && typeof module.exports === 'object') { + var v = factory(require, exports); if (v !== undefined) module.exports = v; + } + else if (typeof define === 'function' && define.amd) { + define(["require", "exports"], factory); + } +})(function (require, exports) { + "use strict"; + let { toString } = 1; + { + let { toFixed } = 1; + } +}); diff --git a/tests/baselines/reference/destructuringInVariableDeclarations6.symbols b/tests/baselines/reference/destructuringInVariableDeclarations6.symbols new file mode 100644 index 0000000000000..71072de351e40 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations6.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations6.ts === +let { toString } = 1; +>toString : Symbol(toString, Decl(destructuringInVariableDeclarations6.ts, 0, 5)) +{ + let { toFixed } = 1; +>toFixed : Symbol(toFixed, Decl(destructuringInVariableDeclarations6.ts, 2, 9)) +} +export {}; + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations6.types b/tests/baselines/reference/destructuringInVariableDeclarations6.types new file mode 100644 index 0000000000000..cf1105b575a48 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations6.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations6.ts === +let { toString } = 1; +>toString : (radix?: number) => string +>1 : number +{ + let { toFixed } = 1; +>toFixed : (fractionDigits?: number) => string +>1 : number +} +export {}; + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations7.js b/tests/baselines/reference/destructuringInVariableDeclarations7.js new file mode 100644 index 0000000000000..129a9db8d1594 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations7.js @@ -0,0 +1,22 @@ +//// [destructuringInVariableDeclarations7.ts] +export let { toString } = 1; +{ + let { toFixed } = 1; +} + + +//// [destructuringInVariableDeclarations7.js] +System.register([], function(exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var toString; + return { + setters:[], + execute: function() { + exports_1("toString", toString = (1).toString); + { + let { toFixed } = 1; + } + } + } +}); diff --git a/tests/baselines/reference/destructuringInVariableDeclarations7.symbols b/tests/baselines/reference/destructuringInVariableDeclarations7.symbols new file mode 100644 index 0000000000000..7fde898296bbb --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations7.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations7.ts === +export let { toString } = 1; +>toString : Symbol(toString, Decl(destructuringInVariableDeclarations7.ts, 0, 12)) +{ + let { toFixed } = 1; +>toFixed : Symbol(toFixed, Decl(destructuringInVariableDeclarations7.ts, 2, 9)) +} + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations7.types b/tests/baselines/reference/destructuringInVariableDeclarations7.types new file mode 100644 index 0000000000000..c0c1b5712152d --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations7.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations7.ts === +export let { toString } = 1; +>toString : (radix?: number) => string +>1 : number +{ + let { toFixed } = 1; +>toFixed : (fractionDigits?: number) => string +>1 : number +} + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations8.js b/tests/baselines/reference/destructuringInVariableDeclarations8.js new file mode 100644 index 0000000000000..bc19fa118f697 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations8.js @@ -0,0 +1,23 @@ +//// [destructuringInVariableDeclarations8.ts] +let { toString } = 1; +{ + let { toFixed } = 1; +} +export {}; + + +//// [destructuringInVariableDeclarations8.js] +System.register([], function(exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var toString; + return { + setters:[], + execute: function() { + ({ toString } = 1); + { + let { toFixed } = 1; + } + } + } +}); diff --git a/tests/baselines/reference/destructuringInVariableDeclarations8.symbols b/tests/baselines/reference/destructuringInVariableDeclarations8.symbols new file mode 100644 index 0000000000000..887ea4ffa4cf7 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations8.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations8.ts === +let { toString } = 1; +>toString : Symbol(toString, Decl(destructuringInVariableDeclarations8.ts, 0, 5)) +{ + let { toFixed } = 1; +>toFixed : Symbol(toFixed, Decl(destructuringInVariableDeclarations8.ts, 2, 9)) +} +export {}; + diff --git a/tests/baselines/reference/destructuringInVariableDeclarations8.types b/tests/baselines/reference/destructuringInVariableDeclarations8.types new file mode 100644 index 0000000000000..ef376563551b4 --- /dev/null +++ b/tests/baselines/reference/destructuringInVariableDeclarations8.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/destructuringInVariableDeclarations8.ts === +let { toString } = 1; +>toString : (radix?: number) => string +>1 : number +{ + let { toFixed } = 1; +>toFixed : (fractionDigits?: number) => string +>1 : number +} +export {}; + diff --git a/tests/cases/compiler/destructuringInVariableDeclarations1.ts b/tests/cases/compiler/destructuringInVariableDeclarations1.ts new file mode 100644 index 0000000000000..275564c07c59d --- /dev/null +++ b/tests/cases/compiler/destructuringInVariableDeclarations1.ts @@ -0,0 +1,6 @@ +// @target: es6 +// @module: commonjs +export let { toString } = 1; +{ + let { toFixed } = 1; +} diff --git a/tests/cases/compiler/destructuringInVariableDeclarations2.ts b/tests/cases/compiler/destructuringInVariableDeclarations2.ts new file mode 100644 index 0000000000000..07190dddd5211 --- /dev/null +++ b/tests/cases/compiler/destructuringInVariableDeclarations2.ts @@ -0,0 +1,7 @@ +// @target: es6 +// @module: commonjs +let { toString } = 1; +{ + let { toFixed } = 1; +} +export {}; diff --git a/tests/cases/compiler/destructuringInVariableDeclarations3.ts b/tests/cases/compiler/destructuringInVariableDeclarations3.ts new file mode 100644 index 0000000000000..7881b3073a1aa --- /dev/null +++ b/tests/cases/compiler/destructuringInVariableDeclarations3.ts @@ -0,0 +1,6 @@ +// @target: es6 +// @module: amd +export let { toString } = 1; +{ + let { toFixed } = 1; +} diff --git a/tests/cases/compiler/destructuringInVariableDeclarations4.ts b/tests/cases/compiler/destructuringInVariableDeclarations4.ts new file mode 100644 index 0000000000000..81ed4d04c4e9f --- /dev/null +++ b/tests/cases/compiler/destructuringInVariableDeclarations4.ts @@ -0,0 +1,7 @@ +// @target: es6 +// @module: amd +let { toString } = 1; +{ + let { toFixed } = 1; +} +export {}; diff --git a/tests/cases/compiler/destructuringInVariableDeclarations5.ts b/tests/cases/compiler/destructuringInVariableDeclarations5.ts new file mode 100644 index 0000000000000..610fa8715f3d7 --- /dev/null +++ b/tests/cases/compiler/destructuringInVariableDeclarations5.ts @@ -0,0 +1,6 @@ +// @target: es6 +// @module: umd +export let { toString } = 1; +{ + let { toFixed } = 1; +} diff --git a/tests/cases/compiler/destructuringInVariableDeclarations6.ts b/tests/cases/compiler/destructuringInVariableDeclarations6.ts new file mode 100644 index 0000000000000..2e63209f4e8f1 --- /dev/null +++ b/tests/cases/compiler/destructuringInVariableDeclarations6.ts @@ -0,0 +1,7 @@ +// @target: es6 +// @module: umd +let { toString } = 1; +{ + let { toFixed } = 1; +} +export {}; diff --git a/tests/cases/compiler/destructuringInVariableDeclarations7.ts b/tests/cases/compiler/destructuringInVariableDeclarations7.ts new file mode 100644 index 0000000000000..3a2827eccc3f0 --- /dev/null +++ b/tests/cases/compiler/destructuringInVariableDeclarations7.ts @@ -0,0 +1,6 @@ +// @target: es6 +// @module: system +export let { toString } = 1; +{ + let { toFixed } = 1; +} diff --git a/tests/cases/compiler/destructuringInVariableDeclarations8.ts b/tests/cases/compiler/destructuringInVariableDeclarations8.ts new file mode 100644 index 0000000000000..4925c47d85b3f --- /dev/null +++ b/tests/cases/compiler/destructuringInVariableDeclarations8.ts @@ -0,0 +1,7 @@ +// @target: es6 +// @module: system +let { toString } = 1; +{ + let { toFixed } = 1; +} +export {};