From bd90382db2bc138c707fe94d411ca97cbbbe7fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Sat, 12 Dec 2020 16:15:18 +0100 Subject: [PATCH] Implement `newableArrowFunctions` assumption --- .../src/config/validation/options.js | 1 + .../src/index.js | 3 +- .../babel-helper-wrap-function/src/index.js | 17 ++++++++--- .../src/index.js | 2 ++ .../src/index.js | 9 ++++-- .../spec-self-referential/options.json | 7 ----- .../basic/input.js | 10 +++++++ .../basic/output.js | 29 +++++++++++++++++++ .../naming}/input.js | 0 .../naming}/output.js | 0 .../options.json | 6 ++++ .../self-referential}/exec.js | 0 .../self-referential}/input.js | 0 .../self-referential}/output.js | 0 .../newableArrowFunction-default/input.js | 1 + .../options.json | 0 .../newableArrowFunction-default/output.js | 6 ++++ .../input.js | 1 + .../options.json | 9 ++++++ .../output.js | 6 ++++ .../input.js | 1 + .../options.json | 9 ++++++ .../output.js | 3 ++ .../src/index.js | 11 ++++--- .../basic/exec.js | 0 .../basic/input.js | 1 + .../basic/options.json | 6 ++++ .../basic/output.js | 7 +++++ .../bluebird/input.js | 0 .../bluebird/options.json | 12 ++++++++ .../src/index.js | 1 + .../src/index.js | 3 +- .../src/params.js | 2 ++ .../babel-traverse/src/path/conversion.js | 17 +++++++---- .../babel-traverse/src/path/replacement.js | 2 ++ 35 files changed, 157 insertions(+), 25 deletions(-) delete mode 100644 packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-self-referential/options.json create mode 100644 packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/basic/input.js create mode 100644 packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/basic/output.js rename packages/babel-plugin-transform-arrow-functions/test/fixtures/{arrow-functions/spec-naming => assumption-newableArrowFunctions-false/naming}/input.js (100%) rename packages/babel-plugin-transform-arrow-functions/test/fixtures/{arrow-functions/spec-naming => assumption-newableArrowFunctions-false/naming}/output.js (100%) create mode 100644 packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/options.json rename packages/babel-plugin-transform-arrow-functions/test/fixtures/{arrow-functions/spec-self-referential => assumption-newableArrowFunctions-false/self-referential}/exec.js (100%) rename packages/babel-plugin-transform-arrow-functions/test/fixtures/{arrow-functions/spec-self-referential => assumption-newableArrowFunctions-false/self-referential}/input.js (100%) rename packages/babel-plugin-transform-arrow-functions/test/fixtures/{arrow-functions/spec-self-referential => assumption-newableArrowFunctions-false/self-referential}/output.js (100%) create mode 100644 packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-default/input.js rename packages/babel-plugin-transform-arrow-functions/test/fixtures/{arrow-functions/spec-naming => spec/newableArrowFunction-default}/options.json (100%) create mode 100644 packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-default/output.js create mode 100644 packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-false/input.js create mode 100644 packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-false/options.json create mode 100644 packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-false/output.js create mode 100644 packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-true/input.js create mode 100644 packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-true/options.json create mode 100644 packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-true/output.js create mode 100644 packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/exec.js create mode 100644 packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/input.js create mode 100644 packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/options.json create mode 100644 packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/output.js create mode 100644 packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/bluebird/input.js create mode 100644 packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/bluebird/options.json diff --git a/packages/babel-core/src/config/validation/options.js b/packages/babel-core/src/config/validation/options.js index 5b45a0dcbd74..af7ca3227a71 100644 --- a/packages/babel-core/src/config/validation/options.js +++ b/packages/babel-core/src/config/validation/options.js @@ -337,6 +337,7 @@ export const assumptionsNames = new Set([ "ignoreToPrimitiveHint", "iterableIsArray", "mutableTemplateObject", + "newableArrowFunctions", "noDocumentAll", "pureGetters", "setClassMethods", diff --git a/packages/babel-helper-remap-async-to-generator/src/index.js b/packages/babel-helper-remap-async-to-generator/src/index.js index ac96c9311218..7cb70342e811 100644 --- a/packages/babel-helper-remap-async-to-generator/src/index.js +++ b/packages/babel-helper-remap-async-to-generator/src/index.js @@ -31,6 +31,7 @@ const awaitVisitor = { export default function ( path: NodePath, helpers: { wrapAsync: Object, wrapAwait: Object }, + newableArrowFunctions?: boolean, ) { path.traverse(awaitVisitor, { wrapAwait: helpers.wrapAwait, @@ -41,7 +42,7 @@ export default function ( path.node.async = false; path.node.generator = true; - wrapFunction(path, t.cloneNode(helpers.wrapAsync)); + wrapFunction(path, t.cloneNode(helpers.wrapAsync), newableArrowFunctions); const isProperty = path.isObjectMethod() || diff --git a/packages/babel-helper-wrap-function/src/index.js b/packages/babel-helper-wrap-function/src/index.js index e1ff0d37ac81..24b4b4a7269d 100644 --- a/packages/babel-helper-wrap-function/src/index.js +++ b/packages/babel-helper-wrap-function/src/index.js @@ -57,7 +57,11 @@ function classOrObjectMethod(path: NodePath, callId: Object) { .unwrapFunctionEnvironment(); } -function plainFunction(path: NodePath, callId: Object) { +function plainFunction( + path: NodePath, + callId: Object, + newableArrowFunctions: boolean, +) { const node = path.node; const isDeclaration = path.isFunctionDeclaration(); const functionId = node.id; @@ -68,7 +72,7 @@ function plainFunction(path: NodePath, callId: Object) { : buildAnonymousExpressionWrapper; if (path.isArrowFunctionExpression()) { - path.arrowFunctionToExpression(); + path.arrowFunctionToExpression({ newableArrowFunctions }); } node.id = null; @@ -123,10 +127,15 @@ function plainFunction(path: NodePath, callId: Object) { } } -export default function wrapFunction(path: NodePath, callId: Object) { +export default function wrapFunction( + path: NodePath, + callId: Object, + // TODO(Babel 8): Consider defaulting to false for spec compliancy + newableArrowFunctions: boolean = true, +) { if (path.isMethod()) { classOrObjectMethod(path, callId); } else { - plainFunction(path, callId); + plainFunction(path, callId, newableArrowFunctions); } } diff --git a/packages/babel-plugin-proposal-async-generator-functions/src/index.js b/packages/babel-plugin-proposal-async-generator-functions/src/index.js index 82bfa1d32a86..d956e7c31fe4 100644 --- a/packages/babel-plugin-proposal-async-generator-functions/src/index.js +++ b/packages/babel-plugin-proposal-async-generator-functions/src/index.js @@ -70,6 +70,8 @@ export default declare(api => { path.traverse(yieldStarVisitor, state); + // We don't need to pass the newableArrowFunctions assumption, since + // async generators are never arrow functions. remapAsyncToGenerator(path, { wrapAsync: state.addHelper("wrapAsyncGenerator"), wrapAwait: state.addHelper("awaitAsyncGenerator"), diff --git a/packages/babel-plugin-transform-arrow-functions/src/index.js b/packages/babel-plugin-transform-arrow-functions/src/index.js index 3e323707a887..357b2ea6c34b 100644 --- a/packages/babel-plugin-transform-arrow-functions/src/index.js +++ b/packages/babel-plugin-transform-arrow-functions/src/index.js @@ -4,7 +4,9 @@ import type NodePath from "@babel/traverse"; export default declare((api, options) => { api.assertVersion(7); - const { spec } = options; + const newableArrowFunctions = + api.assumption("newableArrowFunctions") ?? !options.spec; + return { name: "transform-arrow-functions", @@ -20,7 +22,10 @@ export default declare((api, options) => { // While other utils may be fine inserting other arrows to make more transforms possible, // the arrow transform itself absolutely cannot insert new arrow functions. allowInsertArrow: false, - specCompliant: !!spec, + newableArrowFunctions, + + // TODO(Babel 8): This is only needed for backward compat with @babel/traverse <7.13.0 + specCompliant: !newableArrowFunctions, }); }, }, diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-self-referential/options.json b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-self-referential/options.json deleted file mode 100644 index edcdc8224cda..000000000000 --- a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-self-referential/options.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "plugins": [ - "external-helpers", - ["transform-arrow-functions", { "spec": true }], - "transform-function-name" - ] -} diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/basic/input.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/basic/input.js new file mode 100644 index 000000000000..f84ea4ed3876 --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/basic/input.js @@ -0,0 +1,10 @@ +function foo() { + arr.map(x => x * x); + var f = (x, y) => x * y; + (function () { + return () => this; + })(); + return { + g: () => this + } +} diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/basic/output.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/basic/output.js new file mode 100644 index 000000000000..6b0103c02f66 --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/basic/output.js @@ -0,0 +1,29 @@ +function foo() { + var _this = this; + + arr.map(function (x) { + babelHelpers.newArrowCheck(this, _this); + return x * x; + }.bind(this)); + + var f = function f(x, y) { + babelHelpers.newArrowCheck(this, _this); + return x * y; + }.bind(this); + + (function () { + var _this2 = this; + + return function () { + babelHelpers.newArrowCheck(this, _this2); + return this; + }.bind(this); + })(); + + return { + g: function g() { + babelHelpers.newArrowCheck(this, _this); + return this; + }.bind(this) + }; +} diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-naming/input.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/naming/input.js similarity index 100% rename from packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-naming/input.js rename to packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/naming/input.js diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-naming/output.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/naming/output.js similarity index 100% rename from packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-naming/output.js rename to packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/naming/output.js diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/options.json b/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/options.json new file mode 100644 index 000000000000..ceee60113f7f --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/options.json @@ -0,0 +1,6 @@ +{ + "plugins": ["external-helpers", "transform-arrow-functions"], + "assumptions": { + "newableArrowFunctions": false + } +} diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-self-referential/exec.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/self-referential/exec.js similarity index 100% rename from packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-self-referential/exec.js rename to packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/self-referential/exec.js diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-self-referential/input.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/self-referential/input.js similarity index 100% rename from packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-self-referential/input.js rename to packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/self-referential/input.js diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-self-referential/output.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/self-referential/output.js similarity index 100% rename from packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-self-referential/output.js rename to packages/babel-plugin-transform-arrow-functions/test/fixtures/assumption-newableArrowFunctions-false/self-referential/output.js diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-default/input.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-default/input.js new file mode 100644 index 000000000000..0f3dac36a7ce --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-default/input.js @@ -0,0 +1 @@ +let a = () => 1; diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-naming/options.json b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-default/options.json similarity index 100% rename from packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/spec-naming/options.json rename to packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-default/options.json diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-default/output.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-default/output.js new file mode 100644 index 000000000000..cee824c23a0b --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-default/output.js @@ -0,0 +1,6 @@ +var _this = this; + +let a = function a() { + babelHelpers.newArrowCheck(this, _this); + return 1; +}.bind(this); diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-false/input.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-false/input.js new file mode 100644 index 000000000000..0f3dac36a7ce --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-false/input.js @@ -0,0 +1 @@ +let a = () => 1; diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-false/options.json b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-false/options.json new file mode 100644 index 000000000000..79ad885b69f4 --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-false/options.json @@ -0,0 +1,9 @@ +{ + "plugins": [ + "external-helpers", + ["transform-arrow-functions", { "spec": false }] + ], + "assumptions": { + "newableArrowFunctions": false + } +} diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-false/output.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-false/output.js new file mode 100644 index 000000000000..cee824c23a0b --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-false/output.js @@ -0,0 +1,6 @@ +var _this = this; + +let a = function a() { + babelHelpers.newArrowCheck(this, _this); + return 1; +}.bind(this); diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-true/input.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-true/input.js new file mode 100644 index 000000000000..0f3dac36a7ce --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-true/input.js @@ -0,0 +1 @@ +let a = () => 1; diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-true/options.json b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-true/options.json new file mode 100644 index 000000000000..d8524d469bde --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-true/options.json @@ -0,0 +1,9 @@ +{ + "plugins": [ + "external-helpers", + ["transform-arrow-functions", { "spec": true }] + ], + "assumptions": { + "newableArrowFunctions": true + } +} diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-true/output.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-true/output.js new file mode 100644 index 000000000000..ccc9512d820a --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/spec/newableArrowFunction-vs-spec-true/output.js @@ -0,0 +1,3 @@ +let a = function () { + return 1; +}; diff --git a/packages/babel-plugin-transform-async-to-generator/src/index.js b/packages/babel-plugin-transform-async-to-generator/src/index.js index 55669063f13b..a685861d428b 100644 --- a/packages/babel-plugin-transform-async-to-generator/src/index.js +++ b/packages/babel-plugin-transform-async-to-generator/src/index.js @@ -7,6 +7,7 @@ export default declare((api, options) => { api.assertVersion(7); const { method, module } = options; + const newableArrowFunctions = api.assumption("newableArrowFunctions"); if (method && module) { return { @@ -23,7 +24,7 @@ export default declare((api, options) => { wrapAsync = state.methodWrapper = addNamed(path, method, module); } - remapAsyncToGenerator(path, { wrapAsync }); + remapAsyncToGenerator(path, { wrapAsync }, newableArrowFunctions); }, }, }; @@ -36,9 +37,11 @@ export default declare((api, options) => { Function(path, state) { if (!path.node.async || path.node.generator) return; - remapAsyncToGenerator(path, { - wrapAsync: state.addHelper("asyncToGenerator"), - }); + remapAsyncToGenerator( + path, + { wrapAsync: state.addHelper("asyncToGenerator") }, + newableArrowFunctions, + ); }, }, }; diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/exec.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/exec.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/input.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/input.js new file mode 100644 index 000000000000..eb65515a95bd --- /dev/null +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/input.js @@ -0,0 +1 @@ +async () => 2; diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/options.json b/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/options.json new file mode 100644 index 000000000000..020a638955b0 --- /dev/null +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/options.json @@ -0,0 +1,6 @@ +{ + "plugins": ["external-helpers", "transform-async-to-generator"], + "assumptions": { + "newableArrowFunctions": false + } +} diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/output.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/output.js new file mode 100644 index 000000000000..c0d2e6069da5 --- /dev/null +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/basic/output.js @@ -0,0 +1,7 @@ +var _this = this; + +/*#__PURE__*/ +babelHelpers.asyncToGenerator(function* () { + babelHelpers.newArrowCheck(this, _this); + return 2; +}); diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/bluebird/input.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/bluebird/input.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/bluebird/options.json b/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/bluebird/options.json new file mode 100644 index 000000000000..2c72d724c0f0 --- /dev/null +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/assumption-newableArrowFunctions-false/bluebird/options.json @@ -0,0 +1,12 @@ +{ + "plugins": [ + "external-helpers", + [ + "transform-async-to-generator", + { "module": "bluebird", "method": "coroutine" } + ] + ], + "assumptions": { + "newableArrowFunctions": true + } +} diff --git a/packages/babel-plugin-transform-classes/src/index.js b/packages/babel-plugin-transform-classes/src/index.js index 9bf8350dd33a..57d849656da3 100644 --- a/packages/babel-plugin-transform-classes/src/index.js +++ b/packages/babel-plugin-transform-classes/src/index.js @@ -68,6 +68,7 @@ export default declare((api, options) => { if (path.isCallExpression()) { annotateAsPure(path); if (path.get("callee").isArrowFunctionExpression()) { + // This is an IIFE, so we don't need to worry about the newableArrowFunctions assumption path.get("callee").arrowFunctionToExpression(); } } diff --git a/packages/babel-plugin-transform-parameters/src/index.js b/packages/babel-plugin-transform-parameters/src/index.js index 91816d56e908..06979003ac52 100644 --- a/packages/babel-plugin-transform-parameters/src/index.js +++ b/packages/babel-plugin-transform-parameters/src/index.js @@ -8,6 +8,7 @@ export default declare((api, options) => { const ignoreFunctionLength = api.assumption("ignoreFunctionLength") ?? options.loose; + const newableArrowFunctions = api.assumption("newableArrowFunctions"); return { name: "transform-parameters", @@ -21,7 +22,7 @@ export default declare((api, options) => { .some(param => param.isRestElement() || param.isAssignmentPattern()) ) { // default/rest visitors require access to `arguments`, so it cannot be an arrow - path.arrowFunctionToExpression(); + path.arrowFunctionToExpression({ newableArrowFunctions }); } const convertedRest = convertFunctionRest(path); diff --git a/packages/babel-plugin-transform-parameters/src/params.js b/packages/babel-plugin-transform-parameters/src/params.js index 58629183c35f..a24f8401b6c0 100644 --- a/packages/babel-plugin-transform-parameters/src/params.js +++ b/packages/babel-plugin-transform-parameters/src/params.js @@ -206,6 +206,8 @@ export default function convertFunctionParams( // sure that we correctly handle this and arguments. const bodyPath = path.get("body.body"); const arrowPath = bodyPath[bodyPath.length - 1].get("argument.callee"); + + // This is an IIFE, so we don't need to worry about the newableArrowFunctions assumption arrowPath.arrowFunctionToExpression(); arrowPath.node.generator = path.node.generator; diff --git a/packages/babel-traverse/src/path/conversion.js b/packages/babel-traverse/src/path/conversion.js index 2ca47297c9ab..7132d214331b 100644 --- a/packages/babel-traverse/src/path/conversion.js +++ b/packages/babel-traverse/src/path/conversion.js @@ -72,6 +72,7 @@ export function ensureBlock() { /** * Keeping this for backward-compatibility. You should use arrowFunctionToExpression() for >=7.x. */ +// TODO(Babel 8): Remove this export function arrowFunctionToShadowed() { if (!this.isArrowFunctionExpression()) return; @@ -103,7 +104,10 @@ export function unwrapFunctionEnvironment() { */ export function arrowFunctionToExpression({ allowInsertArrow = true, + /** @deprecated Use `newableArrowFunctions` instead */ specCompliant = false, + // TODO(Babel 8): Consider defaulting to `false` for spec compliancy + newableArrowFunctions = !specCompliant, } = {}) { if (!this.isArrowFunctionExpression()) { throw this.buildCodeFrameError( @@ -113,13 +117,13 @@ export function arrowFunctionToExpression({ const thisBinding = hoistFunctionEnvironment( this, - specCompliant, + newableArrowFunctions, allowInsertArrow, ); this.ensureBlock(); this.node.type = "FunctionExpression"; - if (specCompliant) { + if (!newableArrowFunctions) { const checkBinding = thisBinding ? null : this.parentPath.scope.generateUidIdentifier("arrowCheckId"); @@ -160,7 +164,8 @@ export function arrowFunctionToExpression({ */ function hoistFunctionEnvironment( fnPath, - specCompliant = false, + // TODO(Babel 8): Consider defaulting to `false` for spec compliancy + newableArrowFunctions = true, allowInsertArrow = true, ) { const thisEnvFn = fnPath.findParent(p => { @@ -298,11 +303,11 @@ function hoistFunctionEnvironment( // Convert all "this" references in the arrow to point at the alias. let thisBinding; - if (thisPaths.length > 0 || specCompliant) { + if (thisPaths.length > 0 || !newableArrowFunctions) { thisBinding = getThisBinding(thisEnvFn, inConstructor); if ( - !specCompliant || + newableArrowFunctions || // In subclass constructors, still need to rewrite because "this" can't be bound in spec mode // because it might not have been initialized yet. (inConstructor && hasSuperClass(thisEnvFn)) @@ -316,7 +321,7 @@ function hoistFunctionEnvironment( thisChild.replaceWith(thisRef); }); - if (specCompliant) thisBinding = null; + if (!newableArrowFunctions) thisBinding = null; } } diff --git a/packages/babel-traverse/src/path/replacement.js b/packages/babel-traverse/src/path/replacement.js index dc1512805172..efc8eef00886 100644 --- a/packages/babel-traverse/src/path/replacement.js +++ b/packages/babel-traverse/src/path/replacement.js @@ -260,6 +260,8 @@ export function replaceExpressionWithStatements(nodes: Array) { } const callee = this.get("callee"); + + // This is an IIFE, so we don't need to worry about the newableArrowFunctions assumption callee.arrowFunctionToExpression(); // (() => await xxx)() -> await (async () => await xxx)();