From 1172779a521ec735ecf17993520b277715dfeab5 Mon Sep 17 00:00:00 2001 From: Josh Johnston Date: Fri, 2 Jun 2017 08:11:00 +1000 Subject: [PATCH 1/2] Fix destructured exports - adds a failing test based on description in #5768 - handles ObjectPattern and ArrayPattern --- .../src/index.js | 60 +++++++++++++++---- .../interop/export-destructured/actual.js | 14 +++++ .../interop/export-destructured/expected.js | 27 +++++++++ 3 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-destructured/actual.js create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-destructured/expected.js diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index 2afc2d6fbbf2..3d51011843c7 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -73,23 +73,61 @@ export default function () { if (node[REASSIGN_REMAP_SKIP]) return; const left = path.get("left"); - if (!left.isIdentifier()) return; + if (left.isIdentifier()) { + const name = left.node.name; + const exports = this.exports[name]; + if (!exports) return; - const name = left.node.name; - const exports = this.exports[name]; - if (!exports) return; + // redeclared in this scope + if (this.scope.getBinding(name) !== path.scope.getBinding(name)) return; - // redeclared in this scope - if (this.scope.getBinding(name) !== path.scope.getBinding(name)) return; + node[REASSIGN_REMAP_SKIP] = true; - node[REASSIGN_REMAP_SKIP] = true; + for (const reid of exports) { + node = buildExportsAssignment(reid, node).expression; + } - for (const reid of exports) { - node = buildExportsAssignment(reid, node).expression; + path.replaceWith(node); + this.requeueInParent(path); } + else if (left.isObjectPattern()) { + for (const property of left.node.properties) { + const name = property.value.name; - path.replaceWith(node); - this.requeueInParent(path); + const exports = this.exports[name]; + if (!exports) continue; + + // redeclared in this scope + if (this.scope.getBinding(name) !== path.scope.getBinding(name)) return; + + node[REASSIGN_REMAP_SKIP] = true; + + path.insertAfter(t.expressionStatement(t.assignmentExpression( + "=", + t.memberExpression(t.identifier("exports"), t.identifier(name)), + t.identifier(name) + ))); + } + } + else if (left.isArrayPattern()) { + for (const element of left.node.elements) { + const name = element.name; + + const exports = this.exports[name]; + if (!exports) continue; + + // redeclared in this scope + if (this.scope.getBinding(name) !== path.scope.getBinding(name)) return; + + node[REASSIGN_REMAP_SKIP] = true; + + path.insertAfter(t.expressionStatement(t.assignmentExpression( + "=", + t.memberExpression(t.identifier("exports"), t.identifier(name)), + t.identifier(name) + ))); + } + } }, UpdateExpression(path) { diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-destructured/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-destructured/actual.js new file mode 100644 index 000000000000..09c986a2d1b5 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-destructured/actual.js @@ -0,0 +1,14 @@ +export let x = 0; +export let y = 0; + +export function f1 () { + ({x} = { x: 1 }); +} + +export function f2 () { + ({x, y} = { x: 2, y: 3 }); +} + +export function f3 () { + [x, y, z] = [3, 4, 5] +} diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-destructured/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-destructured/expected.js new file mode 100644 index 000000000000..d7015886fc41 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-destructured/expected.js @@ -0,0 +1,27 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.f1 = f1; +exports.f2 = f2; +exports.f3 = f3; +let x = exports.x = 0; +let y = exports.y = 0; + +function f1() { + ({ x } = { x: 1 }); + exports.x = x; +} + +function f2() { + ({ x, y } = { x: 2, y: 3 }); + exports.y = y; + exports.x = x; +} + +function f3() { + [x, y, z] = [3, 4, 5]; + exports.y = y; + exports.x = x; +} From 123beb53828694adb321759f9c163d77762b4704 Mon Sep 17 00:00:00 2001 From: Josh Johnston Date: Fri, 2 Jun 2017 08:28:20 +1000 Subject: [PATCH 2/2] use export assignment template --- .../src/index.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index 3d51011843c7..22e5a8167a55 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -102,11 +102,7 @@ export default function () { node[REASSIGN_REMAP_SKIP] = true; - path.insertAfter(t.expressionStatement(t.assignmentExpression( - "=", - t.memberExpression(t.identifier("exports"), t.identifier(name)), - t.identifier(name) - ))); + path.insertAfter(buildExportsAssignment(t.identifier(name), t.identifier(name))); } } else if (left.isArrayPattern()) { @@ -121,11 +117,7 @@ export default function () { node[REASSIGN_REMAP_SKIP] = true; - path.insertAfter(t.expressionStatement(t.assignmentExpression( - "=", - t.memberExpression(t.identifier("exports"), t.identifier(name)), - t.identifier(name) - ))); + path.insertAfter(buildExportsAssignment(t.identifier(name), t.identifier(name))); } } },