From 64ae71538be92e02a9e1428cb3d5062c339aac06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Thu, 12 Dec 2019 16:30:34 -0500 Subject: [PATCH 1/3] fix: add computed property support for object Ref --- .../src/index.js | 28 ++++++--- .../object-ref-computed-exec/exec.js | 20 ++++++ .../object-rest/object-ref-computed/input.js | 20 ++++++ .../object-rest/object-ref-computed/output.js | 61 +++++++++++++++++++ 4 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed-exec/exec.js create mode 100644 packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/input.js create mode 100644 packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/output.js diff --git a/packages/babel-plugin-proposal-object-rest-spread/src/index.js b/packages/babel-plugin-proposal-object-rest-spread/src/index.js index 9263fbd56d5e..7f0d2525fbed 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/src/index.js +++ b/packages/babel-plugin-proposal-object-rest-spread/src/index.js @@ -102,12 +102,12 @@ export default declare((api, opts) => { // replaces impure computed keys with new identifiers // and returns variable declarators of these new identifiers - function replaceImpureComputedKeys(path) { + function replaceImpureComputedKeys(properties, scope) { const impureComputedPropertyDeclarators = []; - for (const propPath of path.get("properties")) { + for (const propPath of properties) { const key = propPath.get("key"); if (propPath.node.computed && !key.isPure()) { - const name = path.scope.generateUidBasedOnNode(key.node); + const name = scope.generateUidBasedOnNode(key.node); const declarator = t.variableDeclarator(t.identifier(name), key.node); impureComputedPropertyDeclarators.push(declarator); key.replaceWith(t.identifier(name)); @@ -139,7 +139,10 @@ export default declare((api, opts) => { const restElement = t.cloneNode(last.node); last.remove(); - const impureComputedPropertyDeclarators = replaceImpureComputedKeys(path); + const impureComputedPropertyDeclarators = replaceImpureComputedKeys( + path.get("properties"), + path.scope, + ); const { keys, allLiteral } = extractNormalizedKeys(path); if (keys.length === 0) { @@ -265,18 +268,21 @@ export default declare((api, opts) => { path.findParent(path => { if (path.isObjectProperty()) { - refPropertyPath.unshift(path.node.key.name); + refPropertyPath.unshift(path); } else if (path.isVariableDeclarator()) { kind = path.parentPath.node.kind; return true; } }); - if (refPropertyPath.length) { - refPropertyPath.forEach(prop => { - ref = t.memberExpression(ref, t.identifier(prop)); - }); - } + const impureObjRefComputedDeclarators = replaceImpureComputedKeys( + refPropertyPath, + path.scope, + ); + refPropertyPath.forEach(prop => { + const { node } = prop; + ref = t.memberExpression(ref, t.cloneNode(node.key), node.computed); + }); const objectPatternPath = path.findParent(path => path.isObjectPattern(), @@ -296,6 +302,8 @@ export default declare((api, opts) => { insertionPath.insertBefore(impureComputedPropertyDeclarators); + insertionPath.insertBefore(impureObjRefComputedDeclarators); + insertionPath.insertAfter( t.variableDeclarator(argument, callExpression), ); diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed-exec/exec.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed-exec/exec.js new file mode 100644 index 000000000000..cfd4046522b6 --- /dev/null +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed-exec/exec.js @@ -0,0 +1,20 @@ +var key, x, y, z; +// impure +key = 1; +var { [key++]: { y, ...x } } = { 1: { a: 1, y: 1 } }; +expect(x).toEqual({ a: 1 }); +expect(key).toBe(2); +expect(y).toBe(1); + +// takes care of the order + +key = 1; +var { + [++key]: { y, ...rest_y }, + [++key]: { z, ...rest_z } +} = {2: { y: 2, z: 3 }, 3: { y: 2, z: 3 } }; +expect(y).toBe(2); +expect(rest_y).toEqual({z: 3}); +expect(z).toBe(3); +expect(rest_z).toEqual({ y: 2 }); + diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/input.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/input.js new file mode 100644 index 000000000000..cfd4046522b6 --- /dev/null +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/input.js @@ -0,0 +1,20 @@ +var key, x, y, z; +// impure +key = 1; +var { [key++]: { y, ...x } } = { 1: { a: 1, y: 1 } }; +expect(x).toEqual({ a: 1 }); +expect(key).toBe(2); +expect(y).toBe(1); + +// takes care of the order + +key = 1; +var { + [++key]: { y, ...rest_y }, + [++key]: { z, ...rest_z } +} = {2: { y: 2, z: 3 }, 3: { y: 2, z: 3 } }; +expect(y).toBe(2); +expect(rest_y).toEqual({z: 3}); +expect(z).toBe(3); +expect(rest_z).toEqual({ y: 2 }); + diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/output.js new file mode 100644 index 000000000000..ec0310aa2063 --- /dev/null +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/output.js @@ -0,0 +1,61 @@ +var key, x, y, z; // impure + +key = 1; + +var _ref = key++, + { + [_ref]: { + y + } +} = { + 1: { + a: 1, + y: 1 + } +}, + x = babelHelpers.objectWithoutProperties({ + 1: { + a: 1, + y: 1 + } +}[_ref], ["y"]); + +expect(x).toEqual({ + a: 1 +}); +expect(key).toBe(2); +expect(y).toBe(1); // takes care of the order + +key = 1; + +var _$ = { + 2: { + y: 2, + z: 3 + }, + 3: { + y: 2, + z: 3 + } +}, + _ref2 = ++key, + _ref3 = ++key, + { + [_ref3]: { + y + }, + [_ref2]: { + z + } +} = _$, + rest_y = babelHelpers.objectWithoutProperties(_$[_ref3], ["y"]), + rest_z = babelHelpers.objectWithoutProperties(_$[_ref2], ["z"]); + +expect(y).toBe(2); +expect(rest_y).toEqual({ + z: 3 +}); +expect(z).toBe(3); +expect(rest_z).toEqual({ + y: 2 +}); From 2cf050242d42d9c9ff006d426bf49a3244ced591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Wed, 18 Dec 2019 12:00:12 -0500 Subject: [PATCH 2/3] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Nicolò Ribaudo --- .../test/fixtures/object-rest/object-ref-computed-exec/exec.js | 2 +- .../test/fixtures/object-rest/object-ref-computed/input.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed-exec/exec.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed-exec/exec.js index cfd4046522b6..53012ea3f1af 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed-exec/exec.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed-exec/exec.js @@ -17,4 +17,4 @@ expect(y).toBe(2); expect(rest_y).toEqual({z: 3}); expect(z).toBe(3); expect(rest_z).toEqual({ y: 2 }); - +expect(key).toBe(3); diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/input.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/input.js index cfd4046522b6..53012ea3f1af 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/input.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/input.js @@ -17,4 +17,4 @@ expect(y).toBe(2); expect(rest_y).toEqual({z: 3}); expect(z).toBe(3); expect(rest_z).toEqual({ y: 2 }); - +expect(key).toBe(3); From 5d80067e95834a59433e3af9370c42993e7e61f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Thu, 19 Dec 2019 01:17:57 +0100 Subject: [PATCH 3/3] Update output.js --- .../test/fixtures/object-rest/object-ref-computed/output.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/output.js index ec0310aa2063..319a0fe18c55 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/output.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/object-ref-computed/output.js @@ -59,3 +59,4 @@ expect(z).toBe(3); expect(rest_z).toEqual({ y: 2 }); +expect(key).toBe(3);