From cd953bb41b740c7ccb627b34a8999ddc203d0260 Mon Sep 17 00:00:00 2001 From: Oskar Eichler Date: Mon, 31 Aug 2026 02:49:36 +0300 Subject: [PATCH 1/2] Preserve Platform write targets --- .../src/__tests__/inline-plugin-test.js | 18 ++++++++++ .../src/inline-plugin.js | 36 +++++++++++++++---- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/packages/metro-transform-plugins/src/__tests__/inline-plugin-test.js b/packages/metro-transform-plugins/src/__tests__/inline-plugin-test.js index a1b1010354..e9e1d39267 100644 --- a/packages/metro-transform-plugins/src/__tests__/inline-plugin-test.js +++ b/packages/metro-transform-plugins/src/__tests__/inline-plugin-test.js @@ -709,6 +709,24 @@ describe('inline constants', () => { }); }); + test("doesn't replace Platform.OS in other write targets", () => { + const code = ` + Platform.OS++; + delete Platform.OS; + [Platform.OS] = values; + ({os: Platform.OS} = value); + for (Platform.OS in object) {} + for ([Platform.OS] in nestedObject) {} + for (Platform.OS of values) {} + for ([Platform.OS] of nestedValues) {} + `; + + compare([inlinePlugin], code, code, { + inlinePlatform: true, + platform: 'ios', + }); + }); + test('replaces Platform.OS in the code if Platform is the right hand side of an assignment expression', () => { const code = ` function a() { diff --git a/packages/metro-transform-plugins/src/inline-plugin.js b/packages/metro-transform-plugins/src/inline-plugin.js index 2cc055d260..8a21273330 100644 --- a/packages/metro-transform-plugins/src/inline-plugin.js +++ b/packages/metro-transform-plugins/src/inline-plugin.js @@ -44,7 +44,6 @@ export default function inlinePlugin( options: Options, ): PluginObj { const { - isAssignmentExpression, isIdentifier, isMemberExpression, isObjectExpression, @@ -69,10 +68,35 @@ export default function inlinePlugin( return !binding || isFlowDeclared(binding); } - const isLeftHandSideOfAssignmentExpression = ( - node: Node, - parent: Node, - ): boolean => isAssignmentExpression(parent) && parent.left === node; + function isWriteTarget(path: NodePath): boolean { + let child: Node = path.node; + let parentPath = path.parentPath; + + while (parentPath != null) { + const parent = parentPath.node; + if ( + (parent.type === 'AssignmentExpression' || + parent.type === 'ForInStatement' || + parent.type === 'ForOfStatement') && + parent.left === child + ) { + return true; + } + if (parent.type === 'UpdateExpression' && parent.argument === child) { + return true; + } + if ( + parent.type === 'UnaryExpression' && + parent.operator === 'delete' && + parent.argument === child + ) { + return true; + } + child = parent; + parentPath = parentPath.parentPath; + } + return false; + } const isProcessEnvNodeEnv = (node: MemberExpression, scope: Scope): boolean => isIdentifier(node.property, nodeEnv) && @@ -138,7 +162,7 @@ export default function inlinePlugin( const scope = path.scope; const opts = state.opts; - if (!isLeftHandSideOfAssignmentExpression(node, path.parent)) { + if (!isWriteTarget(path)) { if ( opts.inlinePlatform && isPlatformNode(node, scope, !!opts.isWrapped) From 01ffb6fd716446ea9a9fe7896bf1a141e5751fe1 Mon Sep 17 00:00:00 2001 From: Oskar Eichler Date: Mon, 31 Aug 2026 16:57:37 +0700 Subject: [PATCH 2/2] Keep reads inside write targets inlineable --- .../src/__tests__/inline-plugin-test.js | 13 +++++++++++++ .../metro-transform-plugins/src/inline-plugin.js | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/packages/metro-transform-plugins/src/__tests__/inline-plugin-test.js b/packages/metro-transform-plugins/src/__tests__/inline-plugin-test.js index e9e1d39267..711781d543 100644 --- a/packages/metro-transform-plugins/src/__tests__/inline-plugin-test.js +++ b/packages/metro-transform-plugins/src/__tests__/inline-plugin-test.js @@ -727,6 +727,19 @@ describe('inline constants', () => { }); }); + test('replaces Platform.OS when it is read inside a write target', () => { + const code = ` + target[Platform.OS] = value; + [target[Platform.OS]] = values; + ({[Platform.OS]: target} = value); + `; + + compare([inlinePlugin], code, code.replaceAll('Platform.OS', '"ios"'), { + inlinePlatform: true, + platform: 'ios', + }); + }); + test('replaces Platform.OS in the code if Platform is the right hand side of an assignment expression', () => { const code = ` function a() { diff --git a/packages/metro-transform-plugins/src/inline-plugin.js b/packages/metro-transform-plugins/src/inline-plugin.js index 8a21273330..d548fcb1f5 100644 --- a/packages/metro-transform-plugins/src/inline-plugin.js +++ b/packages/metro-transform-plugins/src/inline-plugin.js @@ -92,6 +92,17 @@ export default function inlinePlugin( ) { return true; } + + const nestedWriteTarget = + parent.type === 'ArrayPattern' || + parent.type === 'ObjectPattern' || + (parent.type === 'ObjectProperty' && parent.value === child) || + (parent.type === 'RestElement' && parent.argument === child) || + (parent.type === 'AssignmentPattern' && parent.left === child); + if (!nestedWriteTarget) { + return false; + } + child = parent; parentPath = parentPath.parentPath; }