Skip to content

Commit bbdeb7d

Browse files
OskarEichlermeta-codesync[bot]
authored andcommitted
Inline the last duplicate Platform.select key (#58249)
Summary: The React Native Babel preset statically replaces `Platform.select({...})` for the target platform. Its property scan currently stops at the first matching key, while JavaScript object-literal evaluation keeps the last duplicate definition. For example, `Platform.select({ios: 1, ios: 2})` runs as `2` but the preset compiles it to `1`. Scan the already-validated static properties from the end so compiled output matches runtime semantics while preserving O(n), allocation-free lookup. Metro has a parallel transform that can run first; companion [Metro PR https://github.com/react/react-native/issues/1889](https://github.com/react/metro/pull/1889) applies the same correction so output remains transform-order independent. ## Changelog: [GENERAL] [FIXED] - Inline the last duplicate key from static Platform.select object literals. Pull Request resolved: #58249 Test Plan: - Added a focused preset regression; pristine main emits `const value=1`, while the fix emits `const value=2`. - Full preset Jest passes: 4/4 suites, 111/111 tests, 16 snapshots. - Fresh Flow check reports 0 errors. - Targeted no-ignore ESLint, Prettier, and `git diff --check` pass. No behavior changes for object literals without duplicate static keys; no UI change. Reviewed By: christophpurrer Differential Revision: D118499490 Pulled By: vzaidman fbshipit-source-id: 3bd58c44c70415c57ed02266a5af2eea242471e4
1 parent 49bcae1 commit bbdeb7d

2 files changed

Lines changed: 7 additions & 1 deletion

File tree

packages/react-native-babel-preset/src/__tests__/inline-platform-plugin-test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,10 @@ describe('Platform.select', () => {
479479
expect(select('{ios() { return 1; }}')).toContain('function');
480480
});
481481

482+
test('uses the last definition of a duplicate key', () => {
483+
expect(select('{ios: 1, ios: 2}')).toContain('const value=2');
484+
});
485+
482486
test('does not inline computed keys', () => {
483487
expect(select('{[key]: 1, default: 2}')).toContain('Platform.select');
484488
});

packages/react-native-babel-preset/src/inline-platform-plugin.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,9 @@ module.exports = function inlinePlatformPlugin(
430430
key /*: string */,
431431
fallback /*: () => Node */,
432432
) /*: Node */ {
433-
for (const property of objectExpression.properties) {
433+
// Object literal evaluation keeps the last definition of a duplicate key.
434+
for (let i = objectExpression.properties.length - 1; i >= 0; i--) {
435+
const property = objectExpression.properties[i];
434436
if (!t.isObjectProperty(property) && !t.isObjectMethod(property)) {
435437
continue;
436438
}

0 commit comments

Comments
 (0)