From a576841eafce175dbed4afb2933ba62c0c25e48f Mon Sep 17 00:00:00 2001 From: lazerg Date: Sat, 7 Nov 2026 18:56:38 +0500 Subject: [PATCH 1/3] Transform class static blocks in the Babel preset --- .../react-native-babel-preset/package.json | 1 + .../src/__tests__/transform-snapshot-test.js | 34 +++++++++++++++++++ .../src/configs/main.js | 1 + 3 files changed, 36 insertions(+) diff --git a/packages/react-native-babel-preset/package.json b/packages/react-native-babel-preset/package.json index 759195dbf1c3..df72068b03f1 100644 --- a/packages/react-native-babel-preset/package.json +++ b/packages/react-native-babel-preset/package.json @@ -36,6 +36,7 @@ "@babel/plugin-transform-async-to-generator": "^7.24.7", "@babel/plugin-transform-block-scoping": "^7.25.0", "@babel/plugin-transform-class-properties": "^7.25.4", + "@babel/plugin-transform-class-static-block": "^7.26.0", "@babel/plugin-transform-classes": "^7.25.4", "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-flow-strip-types": "^7.25.2", diff --git a/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js b/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js index 6de3d2e63a27..18de6c34cdfd 100644 --- a/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js +++ b/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js @@ -568,6 +568,40 @@ describe('react-native-babel-preset transform snapshots', () => { expect(result).toContain('_classPrivateFieldLooseKey'); }); + it('transforms class static blocks without unstable_preserveClassPrivate', () => { + const code = ` + class Config { + static value = 0; + static { + Config.value = 2; + } + } + `; + const result = transformCode(code, { + dev: false, + unstable_transformProfile: 'hermes-stable', + }); + expect(result).not.toContain('static {'); + expect(result).toContain('Config.value = 2'); + }); + + it('transforms class static blocks when the profile lowers classes', () => { + const code = ` + class Config { + static value = 0; + static { + Config.value = 2; + } + } + `; + const result = transformCode(code, { + dev: false, + unstable_transformProfile: 'hermes-legacy', + }); + expect(result).not.toContain('static {'); + expect(result).toContain('Config.value = 2'); + }); + it('preserves async/await with unstable_preserveAsync', () => { const code = ` async function fetchData() { diff --git a/packages/react-native-babel-preset/src/configs/main.js b/packages/react-native-babel-preset/src/configs/main.js index 33a216fd791b..80b598972c01 100644 --- a/packages/react-native-babel-preset/src/configs/main.js +++ b/packages/react-native-babel-preset/src/configs/main.js @@ -280,6 +280,7 @@ const getPreset = (src, options, babel) => { ...(preserveClassPrivate ? [] : [ + [require('@babel/plugin-transform-class-static-block')], [require('@babel/plugin-transform-private-methods'), {loose}], [ require('@babel/plugin-transform-private-property-in-object'), From 2cb27f3d9b714171b8dbbeaf4e9580e203e90bfc Mon Sep 17 00:00:00 2001 From: lazerg Date: Sat, 7 Nov 2026 19:01:29 +0500 Subject: [PATCH 2/3] Cover unstable_preserveClassPrivate in the legacy static block test --- .../src/__tests__/transform-snapshot-test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js b/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js index 18de6c34cdfd..01d4df89031d 100644 --- a/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js +++ b/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js @@ -597,6 +597,9 @@ describe('react-native-babel-preset transform snapshots', () => { const result = transformCode(code, { dev: false, unstable_transformProfile: 'hermes-legacy', + customTransformOptions: { + unstable_preserveClassPrivate: true, + }, }); expect(result).not.toContain('static {'); expect(result).toContain('Config.value = 2'); From 59904b5bfa7f30cf7963d722d64863fa27f39eff Mon Sep 17 00:00:00 2001 From: lazerg Date: Mon, 9 Nov 2026 17:33:38 +0500 Subject: [PATCH 3/3] Test static blocks with private fields and preserveClassPrivate --- .../src/__tests__/transform-snapshot-test.js | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js b/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js index 01d4df89031d..9d9d2606b99e 100644 --- a/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js +++ b/packages/react-native-babel-preset/src/__tests__/transform-snapshot-test.js @@ -605,6 +605,47 @@ describe('react-native-babel-preset transform snapshots', () => { expect(result).toContain('Config.value = 2'); }); + it('transforms class static blocks that use private fields and super', () => { + const code = ` + class Base { + static base = 1; + } + class Config extends Base { + static #secret = 1; + static value = 0; + static { + Config.value = Config.#secret + super.base; + } + } + `; + const result = transformCode(code, { + dev: false, + unstable_transformProfile: 'hermes-stable', + }); + expect(result).not.toContain('static {'); + expect(result).not.toContain('#secret'); + }); + + it('preserves class static blocks with unstable_preserveClassPrivate', () => { + const code = ` + class Config { + static #secret = 1; + static { + Config.value = Config.#secret; + } + } + `; + const result = transformCode(code, { + dev: false, + unstable_transformProfile: 'hermes-stable', + customTransformOptions: { + unstable_preserveClassPrivate: true, + }, + }); + expect(result).toContain('static {'); + expect(result).toContain('#secret'); + }); + it('preserves async/await with unstable_preserveAsync', () => { const code = ` async function fetchData() {