From d2bba1003e88a5ad29c88ff8ac497acc55ab8b2b Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Fri, 28 Aug 2026 05:23:50 -0700 Subject: [PATCH] Cover `react/utils` with Stable API guards Summary: Classifies `react/utils:utils` as a public target under the C++ stable API three-tier visibility model. Adds `#include ` to the module's 22 exported headers and introduces the module umbrella `React/Utils.h`, wiring the guard dependency into BUCK, CMake and CocoaPods and the umbrella into BUCK, CocoaPods, the iOS prebuild header config and the Android prefab export. Consumers that opt into `RN_STRICT_API` now get an error if they include the module's headers directly, and should include `` instead; without that flag the guards are inert, so no existing build changes behaviour. Changelog: [Internal] Differential Revision: D117858212 --- .../ReactAndroid/build.gradle.kts | 1 + .../ReactCommon/react/utils/Base64.h | 2 + .../ReactCommon/react/utils/CMakeLists.txt | 1 + .../react/utils/ContextContainer.h | 2 + .../ReactCommon/react/utils/FloatComparison.h | 2 + .../ReactCommon/react/utils/MoveWrapper.h | 2 + .../ReactCommon/react/utils/OnScopeExit.h | 2 + .../ReactCommon/react/utils/PackTraits.h | 2 + .../react/utils/React-utils.podspec | 9 +++- .../ReactCommon/react/utils/React/Utils.h | 46 +++++++++++++++++++ .../ReactCommon/react/utils/RunLoopObserver.h | 2 + .../ReactCommon/react/utils/SharedFunction.h | 2 + .../react/utils/SimpleThreadSafeCache.h | 2 + .../ReactCommon/react/utils/Telemetry.h | 2 + .../react/utils/TemplateStringLiteral.h | 2 + .../ReactCommon/react/utils/Uuid.h | 2 + .../ReactCommon/react/utils/fnv1a.h | 2 + .../ReactCommon/react/utils/hash_combine.h | 2 + .../ReactCommon/react/utils/iequals.h | 2 + .../ReactCommon/react/utils/jsi-utils.h | 2 + .../android/react/utils/LowPriorityExecutor.h | 2 + .../cxx/react/utils/LowPriorityExecutor.h | 2 + .../ios/react/utils/LowPriorityExecutor.h | 2 + .../ReactCommon/react/utils/toLower.h | 2 + .../ReactCommon/react/utils/to_underlying.h | 2 + .../scripts/ios-prebuild/headers-config.js | 18 ++++++++ 26 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 packages/react-native/ReactCommon/react/utils/React/Utils.h diff --git a/packages/react-native/ReactAndroid/build.gradle.kts b/packages/react-native/ReactAndroid/build.gradle.kts index 314fc497d781..63308fdd138b 100644 --- a/packages/react-native/ReactAndroid/build.gradle.kts +++ b/packages/react-native/ReactAndroid/build.gradle.kts @@ -165,6 +165,7 @@ val preparePrefab by Pair("../ReactCommon/react/renderer/uimanager/React/", "React/"), // react_utils Pair("../ReactCommon/react/utils/", "react/utils/"), + Pair("../ReactCommon/react/utils/React/", "React/"), // rrc_image Pair( "../ReactCommon/react/renderer/components/image/", diff --git a/packages/react-native/ReactCommon/react/utils/Base64.h b/packages/react-native/ReactCommon/react/utils/Base64.h index ec879c2b62b3..ee44506a807e 100644 --- a/packages/react-native/ReactCommon/react/utils/Base64.h +++ b/packages/react-native/ReactCommon/react/utils/Base64.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/utils/CMakeLists.txt b/packages/react-native/ReactCommon/react/utils/CMakeLists.txt index 89111c32fbed..0537ddca3d95 100644 --- a/packages/react-native/ReactCommon/react/utils/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/utils/CMakeLists.txt @@ -31,6 +31,7 @@ target_link_libraries(react_utils glog glog_init jsi + react_cxxstableapi react_debug) target_compile_reactnative_options(react_utils PRIVATE) target_compile_options(react_utils PRIVATE -Wpedantic) diff --git a/packages/react-native/ReactCommon/react/utils/ContextContainer.h b/packages/react-native/ReactCommon/react/utils/ContextContainer.h index 890cff25ca73..ffc243c4f819 100644 --- a/packages/react-native/ReactCommon/react/utils/ContextContainer.h +++ b/packages/react-native/ReactCommon/react/utils/ContextContainer.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/utils/FloatComparison.h b/packages/react-native/ReactCommon/react/utils/FloatComparison.h index f53ada84bc2f..9b15f8164521 100644 --- a/packages/react-native/ReactCommon/react/utils/FloatComparison.h +++ b/packages/react-native/ReactCommon/react/utils/FloatComparison.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/utils/MoveWrapper.h b/packages/react-native/ReactCommon/react/utils/MoveWrapper.h index 22a9a0f238f4..4488c160986a 100644 --- a/packages/react-native/ReactCommon/react/utils/MoveWrapper.h +++ b/packages/react-native/ReactCommon/react/utils/MoveWrapper.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/utils/OnScopeExit.h b/packages/react-native/ReactCommon/react/utils/OnScopeExit.h index 633471daf826..ce680fe3904d 100644 --- a/packages/react-native/ReactCommon/react/utils/OnScopeExit.h +++ b/packages/react-native/ReactCommon/react/utils/OnScopeExit.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/utils/PackTraits.h b/packages/react-native/ReactCommon/react/utils/PackTraits.h index 675cdc06ed9f..099756681b4b 100644 --- a/packages/react-native/ReactCommon/react/utils/PackTraits.h +++ b/packages/react-native/ReactCommon/react/utils/PackTraits.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react::traits { diff --git a/packages/react-native/ReactCommon/react/utils/React-utils.podspec b/packages/react-native/ReactCommon/react/utils/React-utils.podspec index 430fe08f0f37..bd6502059b26 100644 --- a/packages/react-native/ReactCommon/react/utils/React-utils.podspec +++ b/packages/react-native/ReactCommon/react/utils/React-utils.podspec @@ -32,7 +32,7 @@ Pod::Spec.new do |s| s.source = source s.source_files = podspec_sources(source_files, ["*.h", "platform/ios/**/*.h"]) s.header_dir = "react/utils" - s.exclude_files = "tests" + s.exclude_files = ["tests", "React"] if ENV['USE_FRAMEWORKS'] header_search_paths = header_search_paths + ["\"$(PODS_TARGET_SRCROOT)/platform/ios\""] @@ -46,6 +46,7 @@ Pod::Spec.new do |s| "DEFINES_MODULE" => "YES" } s.dependency "React-jsi", version + s.dependency "React-cxxstableapi" if use_hermes() s.dependency "hermes-engine" @@ -55,5 +56,11 @@ Pod::Spec.new do |s| add_dependency(s, "React-debug") + s.subspec "utilsUmbrella" do |ss| + ss.source_files = "React/*.h" + ss.header_dir = "React" + ss.header_mappings_dir = "React" + end + mark_as_react_native_build(s) end diff --git a/packages/react-native/ReactCommon/react/utils/React/Utils.h b/packages/react-native/ReactCommon/react/utils/React/Utils.h new file mode 100644 index 000000000000..95803affaa27 --- /dev/null +++ b/packages/react-native/ReactCommon/react/utils/React/Utils.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +// ============================================================================= +// Umbrella header for the `react/utils` module - public entry point. +// +// #include +// +// Re-exports the module's public interface headers. React Native's own code +// should keep using the fine-grained `` includes; only outside +// consumers use this umbrella. +// ============================================================================= + +// Marks that the following headers are pulled in through the umbrella, so their +// shared guard () accepts them. Scoped to +// this block so later *direct* includes in the same TU are still caught. +#define RN_UMBRELLA_CONTEXT + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef RN_UMBRELLA_CONTEXT diff --git a/packages/react-native/ReactCommon/react/utils/RunLoopObserver.h b/packages/react-native/ReactCommon/react/utils/RunLoopObserver.h index d226bcb5ccb1..cb7a78e0cb6e 100644 --- a/packages/react-native/ReactCommon/react/utils/RunLoopObserver.h +++ b/packages/react-native/ReactCommon/react/utils/RunLoopObserver.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/utils/SharedFunction.h b/packages/react-native/ReactCommon/react/utils/SharedFunction.h index 04ea9e7f05ab..9f24022dcd2a 100644 --- a/packages/react-native/ReactCommon/react/utils/SharedFunction.h +++ b/packages/react-native/ReactCommon/react/utils/SharedFunction.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/utils/SimpleThreadSafeCache.h b/packages/react-native/ReactCommon/react/utils/SimpleThreadSafeCache.h index e5c8994b1b87..87e7cd701529 100644 --- a/packages/react-native/ReactCommon/react/utils/SimpleThreadSafeCache.h +++ b/packages/react-native/ReactCommon/react/utils/SimpleThreadSafeCache.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/utils/Telemetry.h b/packages/react-native/ReactCommon/react/utils/Telemetry.h index d7ebf2b0e82c..4168fed247e4 100644 --- a/packages/react-native/ReactCommon/react/utils/Telemetry.h +++ b/packages/react-native/ReactCommon/react/utils/Telemetry.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/utils/TemplateStringLiteral.h b/packages/react-native/ReactCommon/react/utils/TemplateStringLiteral.h index 94508ae7ed41..4dc7162ee2d6 100644 --- a/packages/react-native/ReactCommon/react/utils/TemplateStringLiteral.h +++ b/packages/react-native/ReactCommon/react/utils/TemplateStringLiteral.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/utils/Uuid.h b/packages/react-native/ReactCommon/react/utils/Uuid.h index 2ae20de419b4..07a427162cea 100644 --- a/packages/react-native/ReactCommon/react/utils/Uuid.h +++ b/packages/react-native/ReactCommon/react/utils/Uuid.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/utils/fnv1a.h b/packages/react-native/ReactCommon/react/utils/fnv1a.h index 6b5a5efbfd12..8abcb1d78848 100644 --- a/packages/react-native/ReactCommon/react/utils/fnv1a.h +++ b/packages/react-native/ReactCommon/react/utils/fnv1a.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/utils/hash_combine.h b/packages/react-native/ReactCommon/react/utils/hash_combine.h index e6ffd2983f78..ba34b2c729f5 100644 --- a/packages/react-native/ReactCommon/react/utils/hash_combine.h +++ b/packages/react-native/ReactCommon/react/utils/hash_combine.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/utils/iequals.h b/packages/react-native/ReactCommon/react/utils/iequals.h index ff1ea60733e7..54e0fcb1f091 100644 --- a/packages/react-native/ReactCommon/react/utils/iequals.h +++ b/packages/react-native/ReactCommon/react/utils/iequals.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/utils/jsi-utils.h b/packages/react-native/ReactCommon/react/utils/jsi-utils.h index d907339b42b0..22478df77613 100644 --- a/packages/react-native/ReactCommon/react/utils/jsi-utils.h +++ b/packages/react-native/ReactCommon/react/utils/jsi-utils.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/utils/platform/android/react/utils/LowPriorityExecutor.h b/packages/react-native/ReactCommon/react/utils/platform/android/react/utils/LowPriorityExecutor.h index 160efadb16a7..bbbc59d70e71 100644 --- a/packages/react-native/ReactCommon/react/utils/platform/android/react/utils/LowPriorityExecutor.h +++ b/packages/react-native/ReactCommon/react/utils/platform/android/react/utils/LowPriorityExecutor.h @@ -7,6 +7,8 @@ #pragma once +#include + namespace facebook::react::LowPriorityExecutor { void execute(std::function &&workItem); diff --git a/packages/react-native/ReactCommon/react/utils/platform/cxx/react/utils/LowPriorityExecutor.h b/packages/react-native/ReactCommon/react/utils/platform/cxx/react/utils/LowPriorityExecutor.h index d70ae6edca2e..5766b8350c73 100644 --- a/packages/react-native/ReactCommon/react/utils/platform/cxx/react/utils/LowPriorityExecutor.h +++ b/packages/react-native/ReactCommon/react/utils/platform/cxx/react/utils/LowPriorityExecutor.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react::LowPriorityExecutor { diff --git a/packages/react-native/ReactCommon/react/utils/platform/ios/react/utils/LowPriorityExecutor.h b/packages/react-native/ReactCommon/react/utils/platform/ios/react/utils/LowPriorityExecutor.h index 3517cac75101..4a61e63267ac 100644 --- a/packages/react-native/ReactCommon/react/utils/platform/ios/react/utils/LowPriorityExecutor.h +++ b/packages/react-native/ReactCommon/react/utils/platform/ios/react/utils/LowPriorityExecutor.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react::LowPriorityExecutor { diff --git a/packages/react-native/ReactCommon/react/utils/toLower.h b/packages/react-native/ReactCommon/react/utils/toLower.h index 766d8d8791ea..0a1a033d2ed2 100644 --- a/packages/react-native/ReactCommon/react/utils/toLower.h +++ b/packages/react-native/ReactCommon/react/utils/toLower.h @@ -7,6 +7,8 @@ #pragma once +#include + namespace facebook::react { /** diff --git a/packages/react-native/ReactCommon/react/utils/to_underlying.h b/packages/react-native/ReactCommon/react/utils/to_underlying.h index 2b68a2377c9f..d86eac25ae85 100644 --- a/packages/react-native/ReactCommon/react/utils/to_underlying.h +++ b/packages/react-native/ReactCommon/react/utils/to_underlying.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react { diff --git a/packages/react-native/scripts/ios-prebuild/headers-config.js b/packages/react-native/scripts/ios-prebuild/headers-config.js index 86f0430e842c..a6e67b7dc702 100644 --- a/packages/react-native/scripts/ios-prebuild/headers-config.js +++ b/packages/react-native/scripts/ios-prebuild/headers-config.js @@ -627,6 +627,24 @@ const PodspecExceptions /*: {[key: string]: PodSpecConfiguration} */ = { 'Libraries/PushNotificationIOS/React-RCTPushNotification.podspec': { disabled: true, }, + 'ReactCommon/react/utils/React-utils.podspec': { + name: 'React-utils', + headerPatterns: [], + headerDir: '', + subSpecs: [ + { + name: 'utils', + headerPatterns: ['*.h', 'platform/ios/**/*.h'], + excludePatterns: ['tests', 'React'], + headerDir: 'react/utils', + }, + { + name: 'utilsUmbrella', + headerPatterns: ['React/*.h'], + headerDir: 'React', + }, + ], + }, }; module.exports = {PodspecExceptions};