diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/super-call/input.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/super-call/input.js new file mode 100644 index 000000000000..ad8de24b77d2 --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/super-call/input.js @@ -0,0 +1,6 @@ +class Bar extends Foo { + constructor() { + let f = () => super(); + f(); + } +} diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/super-call/options.json b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/super-call/options.json new file mode 100644 index 000000000000..eb924af09529 --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/super-call/options.json @@ -0,0 +1,4 @@ +{ + "plugins": ["transform-arrow-functions"], + "throws": "When using '@babel/plugin-transform-arrow-functions', it's not possible to compile `super()` in an arrow function without compiling classes.\nPlease add '@babel/plugin-transform-classes' to your Babel configuration." +} diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/super-prop/input.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/super-prop/input.js new file mode 100644 index 000000000000..c3f597bc5ca2 --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/super-prop/input.js @@ -0,0 +1,6 @@ +class Bar extends Foo { + constructor() { + let f = () => super.x; + f(); + } +} diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/super-prop/options.json b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/super-prop/options.json new file mode 100644 index 000000000000..f6a099e18a49 --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/super-prop/options.json @@ -0,0 +1,4 @@ +{ + "plugins": ["transform-arrow-functions"], + "throws": "When using '@babel/plugin-transform-arrow-functions', it's not possible to compile `super.prop` in an arrow function without compiling classes.\nPlease add '@babel/plugin-transform-classes' to your Babel configuration." +} diff --git a/packages/babel-plugin-transform-parameters/src/index.ts b/packages/babel-plugin-transform-parameters/src/index.ts index a316a0033a09..d0ec02dd7cee 100644 --- a/packages/babel-plugin-transform-parameters/src/index.ts +++ b/packages/babel-plugin-transform-parameters/src/index.ts @@ -27,7 +27,10 @@ export default declare((api, options: Options) => { .some(param => param.isRestElement() || param.isAssignmentPattern()) ) { // default/rest visitors require access to `arguments`, so it cannot be an arrow - path.arrowFunctionToExpression({ noNewArrows }); + path.arrowFunctionToExpression({ + allowInsertArrowWithRest: false, + noNewArrows, + }); // In some cases arrowFunctionToExpression replaces the function with a wrapper. // Return early; the wrapped function will be visited later in the AST traversal. diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-default-super-no-classes-plugin/input.js b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-default-super-no-classes-plugin/input.js new file mode 100644 index 000000000000..b9a3692a568c --- /dev/null +++ b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-default-super-no-classes-plugin/input.js @@ -0,0 +1,6 @@ +class Bar extends Foo { + constructor() { + let f = (x = super()) => x; + f(); + } +} diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-default-super-no-classes-plugin/options.json b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-default-super-no-classes-plugin/options.json new file mode 100644 index 000000000000..78d5c966915c --- /dev/null +++ b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-default-super-no-classes-plugin/options.json @@ -0,0 +1,4 @@ +{ + "plugins": ["transform-parameters"], + "throws": "When using '@babel/plugin-transform-parameters', it's not possible to compile `super()` in an arrow function with default or rest parameters without compiling classes.\nPlease add '@babel/plugin-transform-classes' to your Babel configuration." +} diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-rest-super-no-classes-plugin/input.js b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-rest-super-no-classes-plugin/input.js new file mode 100644 index 000000000000..df404a5f5bb4 --- /dev/null +++ b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-rest-super-no-classes-plugin/input.js @@ -0,0 +1,6 @@ +class Bar extends Foo { + constructor() { + let f = (...args) => super(...args); + f(); + } +} diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-rest-super-no-classes-plugin/options.json b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-rest-super-no-classes-plugin/options.json new file mode 100644 index 000000000000..78d5c966915c --- /dev/null +++ b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-rest-super-no-classes-plugin/options.json @@ -0,0 +1,4 @@ +{ + "plugins": ["transform-parameters"], + "throws": "When using '@babel/plugin-transform-parameters', it's not possible to compile `super()` in an arrow function with default or rest parameters without compiling classes.\nPlease add '@babel/plugin-transform-classes' to your Babel configuration." +} diff --git a/packages/babel-traverse/src/path/conversion.ts b/packages/babel-traverse/src/path/conversion.ts index eecdf85af83a..041abea0d8c1 100644 --- a/packages/babel-traverse/src/path/conversion.ts +++ b/packages/babel-traverse/src/path/conversion.ts @@ -149,12 +149,14 @@ export function arrowFunctionToExpression( this: NodePath, { allowInsertArrow = true, + allowInsertArrowWithRest = allowInsertArrow, /** @deprecated Use `noNewArrows` instead */ specCompliant = false, // TODO(Babel 8): Consider defaulting to `false` for spec compliancy noNewArrows = !specCompliant, }: { allowInsertArrow?: boolean | void; + allowInsertArrowWithRest?: boolean | void; specCompliant?: boolean | void; noNewArrows?: boolean; } = {}, @@ -169,6 +171,7 @@ export function arrowFunctionToExpression( this, noNewArrows, allowInsertArrow, + allowInsertArrowWithRest, ); // @ts-expect-error TS requires explicit fn type annotation @@ -240,6 +243,7 @@ function hoistFunctionEnvironment( // TODO(Babel 8): Consider defaulting to `false` for spec compliancy noNewArrows: boolean | void = true, allowInsertArrow: boolean | void = true, + allowInsertArrowWithRest: boolean | void = true, ): { thisBinding: string; fnPath: NodePath } { let arrowParent; let thisEnvFn: NodePath = fnPath.findParent(p => { @@ -286,7 +290,17 @@ function hoistFunctionEnvironment( if (inConstructor && superCalls.length > 0) { if (!allowInsertArrow) { throw superCalls[0].buildCodeFrameError( - "Unable to handle nested super() usage in arrow", + "When using '@babel/plugin-transform-arrow-functions', " + + "it's not possible to compile `super()` in an arrow function without compiling classes.\n" + + "Please add '@babel/plugin-transform-classes' to your Babel configuration.", + ); + } + if (!allowInsertArrowWithRest) { + // preset-env with target `since 2017` enables `transform-parameters` without `transform-classes`. + throw superCalls[0].buildCodeFrameError( + "When using '@babel/plugin-transform-parameters', " + + "it's not possible to compile `super()` in an arrow function with default or rest parameters without compiling classes.\n" + + "Please add '@babel/plugin-transform-classes' to your Babel configuration.", ); } const allSuperCalls: NodePath[] = []; @@ -345,7 +359,9 @@ function hoistFunctionEnvironment( if (superProps.length > 0) { if (!allowInsertArrow) { throw superProps[0].buildCodeFrameError( - "Unable to handle nested super.prop usage", + "When using '@babel/plugin-transform-arrow-functions', " + + "it's not possible to compile `super.prop` in an arrow function without compiling classes.\n" + + "Please add '@babel/plugin-transform-classes' to your Babel configuration.", ); }