Skip to content

Commit

Permalink
Add a bugfix plugin for https://crbug.com/v8/12421 (#14295)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Oct 23, 2023
1 parent 7a35330 commit 46ee461
Show file tree
Hide file tree
Showing 56 changed files with 933 additions and 3 deletions.
1 change: 1 addition & 0 deletions Gulpfile.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,7 @@ if (bool(process.env.BABEL_8_BREAKING)) {
"packages/babel-preset-typescript",
"packages/babel-helper-member-expression-to-functions",
"packages/babel-plugin-bugfix-v8-spread-parameters-in-optional-chaining",
"packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly",
"packages/babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression",
].map(src => ({
src,
Expand Down
6 changes: 6 additions & 0 deletions packages/babel-compat-data/data/overlapping-plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,11 @@
],
"proposal-optional-chaining": [
"bugfix/transform-v8-spread-parameters-in-optional-chaining"
],
"transform-class-properties": [
"bugfix/transform-v8-static-class-fields-redefine-readonly"
],
"proposal-class-properties": [
"bugfix/transform-v8-static-class-fields-redefine-readonly"
]
}
13 changes: 13 additions & 0 deletions packages/babel-compat-data/data/plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@
"opera_mobile": "75",
"electron": "24.0"
},
"bugfix/transform-v8-static-class-fields-redefine-readonly": {
"chrome": "98",
"opera": "84",
"edge": "98",
"firefox": "95",
"safari": "15",
"node": "12",
"deno": "1.18",
"ios": "15",
"samsung": "11",
"opera_mobile": "52",
"electron": "17.0"
},
"transform-class-static-block": {
"chrome": "94",
"opera": "80",
Expand Down
8 changes: 5 additions & 3 deletions packages/babel-compat-data/scripts/data/plugin-features.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,16 @@ const es2021 = {
};

const es2022 = {
"bugfix/transform-v8-static-class-fields-redefine-readonly": {
features: ["static class fields / static class fields use [[Define]]"],
replaces: "transform-class-properties",
},
"transform-class-static-block": "Class static initialization blocks",
"transform-private-property-in-object":
"Ergonomic brand checks for private fields",
"transform-class-properties": {
features: [
"static class fields / public static class fields",
"static class fields / private static class fields",
"static class fields / computed static class fields",
"static class fields",
"instance class fields / public instance class fields",
"instance class fields / private instance class fields basic support",
"instance class fields / computed instance class fields",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
src
test
*.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# @babel/plugin-bugfix-v8-static-class-fields-redefine-readonly

> Transform static class fields assignments that are affected by https://crbug.com/v8/12421
See our website [@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly](https://babeljs.io/docs/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly) for more information.

## Install

Using npm:

```sh
npm install --save-dev @babel/plugin-bugfix-v8-static-class-fields-redefine-readonly
```

or using yarn:

```sh
yarn add @babel/plugin-bugfix-v8-static-class-fields-redefine-readonly --dev
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly",
"version": "7.16.7",
"description": "Transform static class fields assignments that are affected by https://crbug.com/v8/12421",
"repository": {
"type": "git",
"url": "https://github.com/babel/babel.git",
"directory": "packages/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly"
},
"homepage": "https://babel.dev/docs/en/next/babel-plugin-bugfix-v8-static-class-fields-redefine-readonly",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"main": "./lib/index.js",
"exports": {
".": "./lib/index.js",
"./package.json": "./package.json"
},
"keywords": [
"babel-plugin",
"bugfix"
],
"dependencies": {
"@babel/helper-environment-visitor": "workspace:^",
"@babel/helper-plugin-utils": "workspace:^"
},
"peerDependencies": {
"@babel/core": "^7.0.0"
},
"devDependencies": {
"@babel/core": "workspace:^",
"@babel/helper-plugin-test-runner": "workspace:^",
"@babel/traverse": "workspace:^"
},
"engines": {
"node": ">=6.9.0"
},
"author": "The Babel Team (https://babel.dev/team)",
"conditions": {
"USE_ESM": [
{
"type": "module"
},
null
],
"BABEL_8_BREAKING": [
{
"engines": {
"node": "^16.20.0 || ^18.16.0 || >=20.0.0"
}
},
{}
]
},
"type": "commonjs"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import type { NodePath, Scope } from "@babel/traverse";
import { types as t, type PluginPass, type File } from "@babel/core";
import { declare } from "@babel/helper-plugin-utils";

import {
getPotentiallyBuggyFieldsIndexes,
getNameOrLengthStaticFieldsIndexes,
toRanges,
} from "./util.ts";

function buildFieldsReplacement(
fields: t.ClassProperty[],
scope: Scope,
file: File,
) {
return t.staticBlock(
fields.map(field => {
const key =
field.computed || !t.isIdentifier(field.key)
? field.key
: t.stringLiteral(field.key.name);

return t.expressionStatement(
t.callExpression(file.addHelper("defineProperty"), [
t.thisExpression(),
key,
field.value || scope.buildUndefinedNode(),
]),
);
}),
);
}

export default declare(api => {
api.assertVersion(7);

const setPublicClassFields = api.assumption("setPublicClassFields");

return {
name: "bugfix-v8-static-class-fields-redefine-readonly",

visitor: {
Class(this: PluginPass, path: NodePath<t.Class>) {
const ranges = toRanges(
setPublicClassFields
? getNameOrLengthStaticFieldsIndexes(path)
: getPotentiallyBuggyFieldsIndexes(path),
);

for (let i = ranges.length - 1; i >= 0; i--) {
const [start, end] = ranges[i];

const startPath = path.get("body.body")[start];

startPath.replaceWith(
buildFieldsReplacement(
path.node.body.body.slice(start, end) as t.ClassProperty[],
path.scope,
this.file,
),
);

for (let j = end - 1; j > start; j--) {
path.get("body.body")[j].remove();
}
}
},
},
};
});

0 comments on commit 46ee461

Please sign in to comment.