From 073b3b0536812bac7bb9d5d6363adef1dd174d07 Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Wed, 9 Nov 2022 01:29:05 +0800 Subject: [PATCH] Fix: Throw when super in arrow with default / rest --- .../package.json | 1 + .../src/index.ts | 19 +++++++++++++++++++ .../input.js | 6 ++++++ .../options.json | 4 ++++ .../input.js | 6 ++++++ .../options.json | 4 ++++ yarn.lock | 1 + 7 files changed, 41 insertions(+) create mode 100644 packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-default-super-no-classes-plugin/input.js create mode 100644 packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-default-super-no-classes-plugin/options.json create mode 100644 packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-rest-super-no-classes-plugin/input.js create mode 100644 packages/babel-plugin-transform-parameters/test/fixtures/parameters/arrow-rest-super-no-classes-plugin/options.json diff --git a/packages/babel-plugin-transform-parameters/package.json b/packages/babel-plugin-transform-parameters/package.json index 8d0ae9776eea..35f252cc8561 100644 --- a/packages/babel-plugin-transform-parameters/package.json +++ b/packages/babel-plugin-transform-parameters/package.json @@ -14,6 +14,7 @@ }, "main": "./lib/index.js", "dependencies": { + "@babel/helper-environment-visitor": "workspace:^", "@babel/helper-plugin-utils": "workspace:^" }, "keywords": [ diff --git a/packages/babel-plugin-transform-parameters/src/index.ts b/packages/babel-plugin-transform-parameters/src/index.ts index a316a0033a09..687568a8697e 100644 --- a/packages/babel-plugin-transform-parameters/src/index.ts +++ b/packages/babel-plugin-transform-parameters/src/index.ts @@ -1,8 +1,25 @@ +import { traverse } from "@babel/core"; +import environmentVisitor from "@babel/helper-environment-visitor"; import { declare } from "@babel/helper-plugin-utils"; import convertFunctionParams from "./params"; import convertFunctionRest from "./rest"; export { convertFunctionParams }; +const checkSuperCallsVisitor = traverse.visitors.merge<{}>([ + { + CallExpression(child) { + if (child.get("callee").isSuper()) { + // NOTE: this may happen in `@babel/preset-env` with target `since 2017`, or in the default setting of `create-react-app`. + throw child.buildCodeFrameError( + "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.", + ); + } + }, + }, + environmentVisitor, +]); + export interface Options { loose?: boolean; } @@ -26,6 +43,8 @@ export default declare((api, options: Options) => { .get("params") .some(param => param.isRestElement() || param.isAssignmentPattern()) ) { + path.traverse(checkSuperCallsVisitor); + // default/rest visitors require access to `arguments`, so it cannot be an arrow path.arrowFunctionToExpression({ noNewArrows }); 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..aa864ca1db7a --- /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": "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..aa864ca1db7a --- /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": "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/yarn.lock b/yarn.lock index e39c093fc9ba..30f7fab34a05 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2862,6 +2862,7 @@ __metadata: resolution: "@babel/plugin-transform-parameters@workspace:packages/babel-plugin-transform-parameters" dependencies: "@babel/core": "workspace:^" + "@babel/helper-environment-visitor": "workspace:^" "@babel/helper-plugin-test-runner": "workspace:^" "@babel/helper-plugin-utils": "workspace:^" peerDependencies: