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 86e5290b84..396ae6cfd3 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/src/index.js +++ b/packages/babel-plugin-proposal-object-rest-spread/src/index.js @@ -178,6 +178,20 @@ export default declare((api, opts) => { ); } else { keyExpression = t.arrayExpression(keys); + + if (!t.isProgram(path.scope.block)) { + // Hoist definition of excluded keys, so that it's not created each time. + const program = path.findParent(path => path.isProgram()); + const id = path.scope.generateUidIdentifier("excluded"); + + program.scope.push({ + id, + init: keyExpression, + kind: "const", + }); + + keyExpression = t.cloneNode(id); + } } return [ diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/assumption-pureGetters/rest-remove-unused-excluded-keys/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/assumption-pureGetters/rest-remove-unused-excluded-keys/output.js index cf80c637a3..5f1e206ceb 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/assumption-pureGetters/rest-remove-unused-excluded-keys/output.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/assumption-pureGetters/rest-remove-unused-excluded-keys/output.js @@ -1,3 +1,5 @@ +const _excluded = ["excluded", "excluded2", "used", "used2"], + _excluded2 = ["unused"]; // should not remove when destructuring into existing bindings var _c = c2; ({ @@ -12,12 +14,12 @@ function render() { used, used2: usedRenamed } = _this$props, - props = babelHelpers.objectWithoutProperties(_this$props, ["excluded", "excluded2", "used", "used2"]); + props = babelHelpers.objectWithoutProperties(_this$props, _excluded); console.log(used, usedRenamed); return React.createElement("input", props); } function smth(_ref) { - let rest = babelHelpers.objectWithoutProperties(_ref, ["unused"]); + let rest = babelHelpers.objectWithoutProperties(_ref, _excluded2); call(rest); } diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/catch-clause/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/catch-clause/output.js index 3d2528632e..f05d6aa4ec 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/catch-clause/output.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/catch-clause/output.js @@ -1,3 +1,7 @@ +const _excluded = ["a1"], + _excluded2 = ["a2", "b2"], + _excluded3 = ["c3"]; + try {} catch (_ref) { let a34 = babelHelpers.extends({}, _ref); } @@ -6,7 +10,7 @@ try {} catch (_ref2) { let { a1 } = _ref2, - b1 = babelHelpers.objectWithoutProperties(_ref2, ["a1"]); + b1 = babelHelpers.objectWithoutProperties(_ref2, _excluded); } try {} catch (_ref3) { @@ -14,7 +18,7 @@ try {} catch (_ref3) { a2, b2 } = _ref3, - c2 = babelHelpers.objectWithoutProperties(_ref3, ["a2", "b2"]); + c2 = babelHelpers.objectWithoutProperties(_ref3, _excluded2); } try {} catch (_ref4) { @@ -25,7 +29,7 @@ try {} catch (_ref4) { c3 } } = _ref4, - c4 = babelHelpers.objectWithoutProperties(_ref4.c2, ["c3"]); + c4 = babelHelpers.objectWithoutProperties(_ref4.c2, _excluded3); } // Unchanged diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/for-x-array-pattern/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/for-x-array-pattern/output.js index d4b3f61d7e..5be28644e2 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/for-x-array-pattern/output.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/for-x-array-pattern/output.js @@ -1,10 +1,14 @@ +const _excluded = ["a"], + _excluded2 = ["a"], + _excluded3 = ["a"]; + // ForXStatement for (const _ref of []) { const [_ref2] = _ref; const { a } = _ref2, - b = babelHelpers.objectWithoutProperties(_ref2, ["a"]); + b = babelHelpers.objectWithoutProperties(_ref2, _excluded); } for (var _ref3 of []) { @@ -12,7 +16,7 @@ for (var _ref3 of []) { var { a } = _ref4, - b = babelHelpers.objectWithoutProperties(_ref4, ["a"]); + b = babelHelpers.objectWithoutProperties(_ref4, _excluded2); } async function a() { @@ -21,7 +25,7 @@ async function a() { var { a } = _ref6, - b = babelHelpers.objectWithoutProperties(_ref6, ["a"]); + b = babelHelpers.objectWithoutProperties(_ref6, _excluded3); } } // skip diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/for-x-completion-record/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/for-x-completion-record/output.js index 01e54fb98a..0ab2da7d8d 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/for-x-completion-record/output.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/for-x-completion-record/output.js @@ -1,9 +1,11 @@ +const _excluded = ["a"]; + for (var _ref of []) { var _ref2 = _ref; ({ a } = _ref2); - b = babelHelpers.objectWithoutProperties(_ref2, ["a"]); + b = babelHelpers.objectWithoutProperties(_ref2, _excluded); _ref2; void 0; } diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/for-x/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/for-x/output.js index ba843ac52a..63002e70ea 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/for-x/output.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/for-x/output.js @@ -1,9 +1,13 @@ +const _excluded = ["a"], + _excluded2 = ["a"], + _excluded3 = ["a"]; + // ForXStatement for (var _ref of []) { var { a } = _ref, - b = babelHelpers.objectWithoutProperties(_ref, ["a"]); + b = babelHelpers.objectWithoutProperties(_ref, _excluded); } for (var _ref2 of []) { @@ -11,7 +15,7 @@ for (var _ref2 of []) { ({ a } = _ref3); - b = babelHelpers.objectWithoutProperties(_ref3, ["a"]); + b = babelHelpers.objectWithoutProperties(_ref3, _excluded2); _ref3; } @@ -21,7 +25,7 @@ async function a() { ({ a } = _ref5); - b = babelHelpers.objectWithoutProperties(_ref5, ["a"]); + b = babelHelpers.objectWithoutProperties(_ref5, _excluded3); _ref5; } } // skip diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/parameters-object-rest-used-in-default/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/parameters-object-rest-used-in-default/output.js index 0d44669336..ed8f957d81 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/parameters-object-rest-used-in-default/output.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/parameters-object-rest-used-in-default/output.js @@ -1,3 +1,5 @@ +const _excluded = ["X"]; + _ref => { let R = babelHelpers.extends({}, _ref); let a = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : R; @@ -7,7 +9,7 @@ _ref => { let { X: Y } = _ref2, - R = babelHelpers.objectWithoutProperties(_ref2, ["X"]); + R = babelHelpers.objectWithoutProperties(_ref2, _excluded); let { a = { Y diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/parameters/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/parameters/output.js index ba6a49ecdb..dcc89b2d48 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/parameters/output.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/parameters/output.js @@ -1,3 +1,13 @@ +const _excluded = ["a1"], + _excluded2 = ["a2", "b2"], + _excluded3 = ["a5"], + _excluded4 = ["a3"], + _excluded5 = ["ba1"], + _excluded6 = ["a3", "b2"], + _excluded7 = ["ba1"], + _excluded8 = ["a1"], + _excluded9 = ["a1"]; + function a(_ref) { let a34 = babelHelpers.extends({}, _ref); } @@ -6,7 +16,7 @@ function a2(_ref2) { let { a1 } = _ref2, - b1 = babelHelpers.objectWithoutProperties(_ref2, ["a1"]); + b1 = babelHelpers.objectWithoutProperties(_ref2, _excluded); } function a3(_ref3) { @@ -14,18 +24,18 @@ function a3(_ref3) { a2, b2 } = _ref3, - c2 = babelHelpers.objectWithoutProperties(_ref3, ["a2", "b2"]); + c2 = babelHelpers.objectWithoutProperties(_ref3, _excluded2); } function a4(_ref4, _ref5) { let { a5 } = _ref5, - c5 = babelHelpers.objectWithoutProperties(_ref5, ["a5"]); + c5 = babelHelpers.objectWithoutProperties(_ref5, _excluded3); let { a3 } = _ref4, - c3 = babelHelpers.objectWithoutProperties(_ref4, ["a3"]); + c3 = babelHelpers.objectWithoutProperties(_ref4, _excluded4); } function a5(_ref6) { @@ -35,8 +45,8 @@ function a5(_ref6) { ba1 } } = _ref6, - ba2 = babelHelpers.objectWithoutProperties(_ref6.b2, ["ba1"]), - c3 = babelHelpers.objectWithoutProperties(_ref6, ["a3", "b2"]); + ba2 = babelHelpers.objectWithoutProperties(_ref6.b2, _excluded5), + c3 = babelHelpers.objectWithoutProperties(_ref6, _excluded6); } function a6(_ref7) { @@ -46,14 +56,14 @@ function a6(_ref7) { ba1 } } = _ref7, - ba2 = babelHelpers.objectWithoutProperties(_ref7.b2, ["ba1"]); + ba2 = babelHelpers.objectWithoutProperties(_ref7.b2, _excluded7); } function a7(_ref8 = {}) { let { a1 = 1 } = _ref8, - b1 = babelHelpers.objectWithoutProperties(_ref8, ["a1"]); + b1 = babelHelpers.objectWithoutProperties(_ref8, _excluded8); } function a8([_ref9]) { @@ -64,7 +74,7 @@ function a9([_ref10]) { let { a1 } = _ref10, - a2 = babelHelpers.objectWithoutProperties(_ref10, ["a1"]); + a2 = babelHelpers.objectWithoutProperties(_ref10, _excluded9); } function a10([a1, _ref11]) { diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/remove-unused-excluded-keys-loose/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/remove-unused-excluded-keys-loose/output.js index 28c7e152b8..50e819aecd 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/remove-unused-excluded-keys-loose/output.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/object-rest/remove-unused-excluded-keys-loose/output.js @@ -1,3 +1,5 @@ +const _excluded = ["excluded", "excluded2", "used", "used2"], + _excluded2 = ["unused"]; // should not remove when destructuring into existing bindings var _c = c2; ({ @@ -13,7 +15,7 @@ class Comp extends React.Component { used, used2: usedRenamed } = _this$props, - props = babelHelpers.objectWithoutPropertiesLoose(_this$props, ["excluded", "excluded2", "used", "used2"]); + props = babelHelpers.objectWithoutPropertiesLoose(_this$props, _excluded); console.log(used, usedRenamed); return React.createElement("input", props); } @@ -21,6 +23,6 @@ class Comp extends React.Component { } function smth(_ref) { - let rest = babelHelpers.objectWithoutPropertiesLoose(_ref, ["unused"]); + let rest = babelHelpers.objectWithoutPropertiesLoose(_ref, _excluded2); call(rest); } diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/regression/gh-4904/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/regression/gh-4904/output.js index 4f44bbb1ef..2e1c2daa50 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/regression/gh-4904/output.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/regression/gh-4904/output.js @@ -1,3 +1,5 @@ +const _excluded = ["b"]; + const _foo = foo(), { s @@ -19,6 +21,6 @@ const { let { b } = _ref, - c = babelHelpers.objectWithoutProperties(_ref, ["b"]); + c = babelHelpers.objectWithoutProperties(_ref, _excluded); console.log(b, c); }); diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/regression/gh-7388/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/regression/gh-7388/output.js index 97254741cb..66d25873df 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/regression/gh-7388/output.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/regression/gh-7388/output.js @@ -1,3 +1,5 @@ +const _excluded = ["a"]; + function fn0(obj0) { const { fn1 = (obj1 = {}) => { @@ -6,7 +8,7 @@ function fn0(obj0) { const { a } = obj2, - rest = babelHelpers.objectWithoutProperties(obj2, ["a"]); + rest = babelHelpers.objectWithoutProperties(obj2, _excluded); console.log(rest); } } = obj1; diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/regression/gh-8323/output.js b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/regression/gh-8323/output.js index cc84cec34a..9bfeb84052 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/regression/gh-8323/output.js +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/regression/gh-8323/output.js @@ -1,3 +1,5 @@ +const _excluded = ["a", "b", "c"]; + const get = () => { fireTheMissiles(); return 3; @@ -8,6 +10,6 @@ const f = _ref => { a = get(), b } = _ref, - z = babelHelpers.objectWithoutPropertiesLoose(_ref, ["a", "b", "c"]); + z = babelHelpers.objectWithoutPropertiesLoose(_ref, _excluded); const v = b + 3; }; diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/output.js index c3e4c75b51..3a84971258 100644 --- a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/output.js +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/output.js @@ -1,3 +1,5 @@ +var _excluded = ["foo"]; + var _loop = function (foo, bar) { () => foo; @@ -12,7 +14,7 @@ for (var _ref of {}) { var { foo } = _ref, - bar = babelHelpers.objectWithoutPropertiesLoose(_ref, ["foo"]); + bar = babelHelpers.objectWithoutPropertiesLoose(_ref, _excluded); _loop(foo, bar); } diff --git a/packages/babel-plugin-transform-destructuring/src/index.js b/packages/babel-plugin-transform-destructuring/src/index.js index 50e0f405bc..814ff169ee 100644 --- a/packages/babel-plugin-transform-destructuring/src/index.js +++ b/packages/babel-plugin-transform-destructuring/src/index.js @@ -228,6 +228,18 @@ export default declare((api, options) => { t.memberExpression(keyExpression, t.identifier("map")), [this.addHelper("toPropertyKey")], ); + } else if (!t.isProgram(this.scope.block)) { + // Hoist definition of excluded keys, so that it's not created each time. + const program = this.scope.path.findParent(path => path.isProgram()); + const id = this.scope.generateUidIdentifier("excluded"); + + program.scope.push({ + id, + init: keyExpression, + kind: "const", + }); + + keyExpression = t.cloneNode(id); } value = t.callExpression( diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-builtins/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-builtins/output.js index 8dcd578573..db952d04e3 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-builtins/output.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-builtins/output.js @@ -1,3 +1,4 @@ +var _excluded = ["x"]; var z = {}; var _z = z, x = Object.assign({}, _z); @@ -10,7 +11,7 @@ var _z3 = z, (function (_ref) { var x = _ref.x, - y = babelHelpers.objectWithoutProperties(_ref, ["x"]); + y = babelHelpers.objectWithoutProperties(_ref, _excluded); }); var _o = o; diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-loose/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-loose/output.js index e202791b6f..9a7d04c58d 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-loose/output.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-loose/output.js @@ -1,3 +1,4 @@ +const _excluded = ["x"]; var z = {}; var _z = z, x = babelHelpers.extends({}, _z); @@ -10,7 +11,7 @@ var _z3 = z, (function (_ref) { let x = _ref.x, - y = babelHelpers.objectWithoutPropertiesLoose(_ref, ["x"]); + y = babelHelpers.objectWithoutPropertiesLoose(_ref, _excluded); }); var _o = o; diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest/output.js index c4af22047a..ffe905ba66 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest/output.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest/output.js @@ -1,3 +1,4 @@ +var _excluded = ["x"]; var z = {}; var _z = z, x = babelHelpers.extends({}, _z); @@ -10,7 +11,7 @@ var _z3 = z, (function (_ref) { var x = _ref.x, - y = babelHelpers.objectWithoutProperties(_ref, ["x"]); + y = babelHelpers.objectWithoutProperties(_ref, _excluded); }); var _o = o; diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/output.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/output.js index 1d844d9eea..c320638b28 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/output.js +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/output.js @@ -1,10 +1,12 @@ +const _excluded = ["text", "className", "id"]; + function render(_ref) { var _Component; let text = _ref.text, className = _ref.className, id = _ref.id, - props = babelHelpers.objectWithoutProperties(_ref, ["text", "className", "id"]); + props = babelHelpers.objectWithoutProperties(_ref, _excluded); // intentionally ignoring props return () => _Component || (_Component = ); } diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/output.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/output.js index db3d5e81de..7cb4583fef 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/output.js +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/output.js @@ -1,7 +1,9 @@ +const _excluded = ["text", "className", "id"]; + function render(_ref) { let text = _ref.text, className = _ref.className, id = _ref.id, - props = babelHelpers.objectWithoutProperties(_ref, ["text", "className", "id"]); + props = babelHelpers.objectWithoutProperties(_ref, _excluded); return () => ; } diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/integration/issue-12303/output.mjs b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/integration/issue-12303/output.mjs index ea732bb287..27cf74ba34 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/integration/issue-12303/output.mjs +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/integration/issue-12303/output.mjs @@ -1,9 +1,11 @@ +const _excluded = ["outsetArrows"]; + function Foo(_ref) { var _div; let { outsetArrows } = _ref, - rest = babelHelpers.objectWithoutProperties(_ref, ["outsetArrows"]); + rest = babelHelpers.objectWithoutProperties(_ref, _excluded); return useMemo(() => _div || (_div =
), [outsetArrows]); } diff --git a/packages/babel-preset-env/test/fixtures/plugins-integration/issue-11278/output.js b/packages/babel-preset-env/test/fixtures/plugins-integration/issue-11278/output.js index f9c8707938..9b6d416960 100644 --- a/packages/babel-preset-env/test/fixtures/plugins-integration/issue-11278/output.js +++ b/packages/babel-preset-env/test/fixtures/plugins-integration/issue-11278/output.js @@ -1,7 +1,9 @@ "use strict"; +var _excluded = ["a"]; + function F(_ref) { var a = _ref.a, - O = babelHelpers.objectWithoutProperties(_ref, ["a"]); + O = babelHelpers.objectWithoutProperties(_ref, _excluded); var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : O; }