Skip to content

Commit

Permalink
avoid duplicating impure initializers in object rest destructuring
Browse files Browse the repository at this point in the history
  • Loading branch information
erikdesjardins committed Jan 18, 2017
1 parent 3871236 commit 8b6b8ee
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
24 changes: 23 additions & 1 deletion packages/babel-plugin-transform-object-rest-spread/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,30 @@ export default function ({ types: t }) {
const kind = path.parentPath.node.kind;
const nodes = [];

path.traverse({
path.get("id").traverse({
RestProperty(path) {
if (
// skip single-property case, e.g.
// const { ...x } = foo();
// since the RHS will not be duplicated
this.originalPath.node.id.properties.length > 1 &&
!t.isIdentifier(this.originalPath.node.init)
) {
// const { a, ...b } = foo();
// to avoid calling foo() twice, as a first step convert it to:
// const _foo = foo();
// const { a, ...b } = _foo;
const initRef = path.scope.generateUidIdentifierBasedOnNode(this.originalPath.node.init, "ref");
// insert const _foo = foo()
this.originalPath.parentPath.insertBefore(t.variableDeclaration(kind, [
t.variableDeclarator(initRef, this.originalPath.node.init)
]));
// replace foo() with _foo
this.originalPath.replaceWith(t.variableDeclarator(this.originalPath.node.id, initRef));

return;
}

let ref = this.originalPath.node.init;

path.findParent((path) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const { s, ...t } = foo();

const { s: { q1, ...q2 }, ...q3 } = bar();

const { a } = foo(({ b, ...c }) => {
console.log(b, c);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const _foo = foo();

const { s } = _foo;

const t = babelHelpers.objectWithoutProperties(_foo, ["s"]);

const _bar = bar();

const { s: { q1 } } = _bar;

const q2 = babelHelpers.objectWithoutProperties(_bar.s, ["q1"]);
const q3 = babelHelpers.objectWithoutProperties(_bar, ["s"]);
const { a } = foo((_ref) => {
let { b } = _ref;
let c = babelHelpers.objectWithoutProperties(_ref, ["b"]);

console.log(b, c);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"plugins": [
"transform-object-rest-spread",
"external-helpers"
]
}

0 comments on commit 8b6b8ee

Please sign in to comment.