diff --git a/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/package.json b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/package.json index 60706cbc01ae..02d990962d5a 100644 --- a/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/package.json +++ b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/package.json @@ -22,6 +22,7 @@ "bugfix" ], "dependencies": { + "@babel/helper-environment-visitor": "workspace:^", "@babel/helper-plugin-utils": "workspace:^" }, "peerDependencies": { diff --git a/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/src/util.ts b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/src/util.ts index 7a002cc66eab..fb42451584bc 100644 --- a/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/src/util.ts +++ b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/src/util.ts @@ -1,5 +1,6 @@ import type { NodePath, Visitor } from "@babel/traverse"; import { types as t } from "@babel/core"; +import { requeueComputedKeyAndDecorators } from "@babel/helper-environment-visitor"; function isNameOrLength(key: t.Node): boolean { if (t.isIdentifier(key)) { @@ -47,10 +48,14 @@ const hasReferenceOrThisVisitor: Visitor<{ name?: string; ref: () => void }> = { } }, FunctionParent(path, state) { + if (path.isArrowFunctionExpression()) return; if (state.name && !path.scope.hasOwnBinding(state.name)) { path.traverse(hasReferenceVisitor, state); } path.skip(); + if (path.isMethod()) { + requeueComputedKeyAndDecorators(path); + } }, }; @@ -189,14 +194,16 @@ export function getNameOrLengthStaticFieldsIndexes(path: NodePath) { return indexes; } +type Range = [start: number, end: number]; + /** * Converts a sorted list of numbers into a list of (inclusive-exclusive) * ranges representing the same numbers. * * @example toRanges([1, 3, 4, 5, 8, 9]) -> [[1, 2], [3, 6], [8, 10]] */ -export function toRanges(nums: number[]): [start: number, end: number][] { - const ranges = []; +export function toRanges(nums: number[]): Range[] { + const ranges: Range[] = []; if (nums.length === 0) return ranges; diff --git a/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/fixtures/basic/nested-class-commputed/input.js b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/fixtures/basic/nested-class-commputed/input.js new file mode 100644 index 000000000000..7b089d867d5f --- /dev/null +++ b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/fixtures/basic/nested-class-commputed/input.js @@ -0,0 +1,15 @@ +class C { + static p = class { + [magic(C)](C) {} + } + static x = 2; +} + +class D { + static p = class { + x(C) { + magic(C); + } + } + static x = 2; +} \ No newline at end of file diff --git a/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/fixtures/basic/nested-class-commputed/output.js b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/fixtures/basic/nested-class-commputed/output.js new file mode 100644 index 000000000000..d239c659295b --- /dev/null +++ b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/fixtures/basic/nested-class-commputed/output.js @@ -0,0 +1,16 @@ +class C { + static { + babelHelpers.defineProperty(this, "p", class { + [magic(C)](C) {} + }); + babelHelpers.defineProperty(this, "x", 2); + } +} +class D { + static p = class { + x(C) { + magic(C); + } + }; + static x = 2; +} diff --git a/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/fixtures/basic/ref-this-in-arrow/input.js b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/fixtures/basic/ref-this-in-arrow/input.js new file mode 100644 index 000000000000..e5cd3ff96265 --- /dev/null +++ b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/fixtures/basic/ref-this-in-arrow/input.js @@ -0,0 +1,4 @@ +class C { + static p = (() => magic(this))(); + static q = 2; +} \ No newline at end of file diff --git a/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/fixtures/basic/ref-this-in-arrow/output.js b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/fixtures/basic/ref-this-in-arrow/output.js new file mode 100644 index 000000000000..bb6a4cf9563d --- /dev/null +++ b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/fixtures/basic/ref-this-in-arrow/output.js @@ -0,0 +1,6 @@ +class C { + static { + babelHelpers.defineProperty(this, "p", (() => magic(this))()); + babelHelpers.defineProperty(this, "q", 2); + } +} diff --git a/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/util.skip-bundled.js b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/util.skip-bundled.js index 4e2d36c0d02f..e2595228c3de 100644 --- a/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/util.skip-bundled.js +++ b/packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly/test/util.skip-bundled.js @@ -4,8 +4,7 @@ import { toRanges, } from "../lib/util.js"; -import babel from "@babel/core"; -const { parseSync, traverse } = babel; +import { parseSync, traverse } from "@babel/core"; function classPath(input) { let targetPath; diff --git a/yarn.lock b/yarn.lock index e8e323b3a02e..c26aaeac6c19 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1383,6 +1383,7 @@ __metadata: resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@workspace:packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly" dependencies: "@babel/core": "workspace:^" + "@babel/helper-environment-visitor": "workspace:^" "@babel/helper-plugin-test-runner": "workspace:^" "@babel/helper-plugin-utils": "workspace:^" "@babel/traverse": "workspace:^"