diff --git a/flow-typed/npm/signedsource_v1.x.x.js b/flow-typed/npm/signedsource_v1.x.x.js new file mode 100644 index 000000000000..2bebd077442d --- /dev/null +++ b/flow-typed/npm/signedsource_v1.x.x.js @@ -0,0 +1,19 @@ +/** + * (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + * + * @format + * @flow strict + */ + +declare module 'signedsource' { + declare type SignedSource = { + TokenNotFoundError: Error, + getSigningToken(): string, + isSigned(data: string): boolean, + signFile(data: string): string, + verifySignature(data: string): boolean, + [key: string]: mixed, + }; + + declare module.exports: SignedSource; +} diff --git a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm index 1668444eeb94..7e36fce8f48a 100644 --- a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm +++ b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm @@ -256,10 +256,6 @@ - (RCTScheduler *)_createScheduler { auto reactNativeConfig = _contextContainer->at>("ReactNativeConfig"); - if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_cpp_props_iterator_setter_ios")) { - CoreFeatures::enablePropIteratorSetter = true; - } - if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_granular_scroll_view_state_updates_ios")) { CoreFeatures::enableGranularScrollViewStateUpdatesIOS = true; } diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 2a5f753722af..b48958e572ec 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -1895,7 +1895,6 @@ public class com/facebook/react/config/ReactFeatureFlags { public static field enableBridgelessArchitectureNewCreateReloadDestroy Z public static field enableBridgelessArchitectureSoftExceptions Z public static field enableClonelessStateProgression Z - public static field enableCppPropsIteratorSetter Z public static field enableDefaultAsyncBatchedPriority Z public static field enableEagerRootViewAttachment Z public static field enableFabricLogs Z diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index 7d06c1b2cd59..e97d1201a588 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -99,11 +99,6 @@ public class ReactFeatureFlags { */ public static boolean enableViewRecycling = false; - /** - * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). - */ - public static boolean enableCppPropsIteratorSetter = false; - /** * Allow Differentiator.cpp and FabricMountingManager.cpp to generate a RemoveDeleteTree mega-op. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 8c356cb7eec4..580995bdad8e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<0da2d8576e351c9467058dbaa369d0b5>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -70,6 +70,12 @@ object ReactNativeFeatureFlags { @JvmStatic fun enableFixForClippedSubviewsCrash() = accessor.enableFixForClippedSubviewsCrash() + /** + * Specifies whether the iterator-style prop parsing is enabled. + */ + @JvmStatic + fun enablePropIteratorSetter() = accessor.enablePropIteratorSetter() + /** * Overrides the feature flags with the ones provided by the given provider * (generally one that extends `ReactNativeFeatureFlagsDefaults`). diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index ca5c8ff1d077..839e9e8a0b80 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5b653e8a53f557ffc0f46b3e81e99bed>> + * @generated SignedSource<<640d3ec5ef059762214db98afedc3650>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -27,6 +27,7 @@ class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccessor { private var enableSpannableBuildingUnificationCache: Boolean? = null private var enableCustomDrawOrderFabricCache: Boolean? = null private var enableFixForClippedSubviewsCrashCache: Boolean? = null + private var enablePropIteratorSetterCache: Boolean? = null override fun commonTestFlag(): Boolean { var cached = commonTestFlagCache @@ -91,6 +92,15 @@ class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccessor { return cached } + override fun enablePropIteratorSetter(): Boolean { + var cached = enablePropIteratorSetterCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enablePropIteratorSetter() + enablePropIteratorSetterCache = cached + } + return cached + } + override fun override(provider: ReactNativeFeatureFlagsProvider) = ReactNativeFeatureFlagsCxxInterop.override(provider as Any) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index f90ae279e352..735c4d4e7249 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<47be3dbe5558f720a6c61742f2c63bf8>> + * @generated SignedSource<<045ff1b11b0336f4bac5ed966ba2e379>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -42,6 +42,8 @@ object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic external fun enableFixForClippedSubviewsCrash(): Boolean + @DoNotStrip @JvmStatic external fun enablePropIteratorSetter(): Boolean + @DoNotStrip @JvmStatic external fun override(provider: Any) @DoNotStrip @JvmStatic external fun dangerouslyReset() diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index cbb9dcdabe8b..6664213af9c4 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<70c19d5bb1e0c09f52b89b4bb3645b9d>> + * @generated SignedSource<> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -36,4 +36,6 @@ open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvider { override fun enableCustomDrawOrderFabric(): Boolean = false override fun enableFixForClippedSubviewsCrash(): Boolean = false + + override fun enablePropIteratorSetter(): Boolean = false } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 15639b90d14e..20c194e504f1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7ba0cb94c10989838250252fa06768a0>> + * @generated SignedSource<<968862b7b9a763c0d78588b2bc0048b5>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -31,6 +31,7 @@ class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAccessor { private var enableSpannableBuildingUnificationCache: Boolean? = null private var enableCustomDrawOrderFabricCache: Boolean? = null private var enableFixForClippedSubviewsCrashCache: Boolean? = null + private var enablePropIteratorSetterCache: Boolean? = null override fun commonTestFlag(): Boolean { var cached = commonTestFlagCache @@ -102,6 +103,16 @@ class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAccessor { return cached } + override fun enablePropIteratorSetter(): Boolean { + var cached = enablePropIteratorSetterCache + if (cached == null) { + cached = currentProvider.enablePropIteratorSetter() + accessedFeatureFlags.add("enablePropIteratorSetter") + enablePropIteratorSetterCache = cached + } + return cached + } + override fun override(provider: ReactNativeFeatureFlagsProvider) { if (accessedFeatureFlags.isNotEmpty()) { val accessedFeatureFlagsStr = accessedFeatureFlags.joinToString(separator = ", ") { it } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 8b477054ea8e..77e83c2c3a76 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<960ab52a914f5b399c1e00daec69be94>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -36,4 +36,6 @@ interface ReactNativeFeatureFlagsProvider { @DoNotStrip fun enableCustomDrawOrderFabric(): Boolean @DoNotStrip fun enableFixForClippedSubviewsCrash(): Boolean + + @DoNotStrip fun enablePropIteratorSetter(): Boolean } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp index 3331911f0f17..1dd4b7d7c754 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp @@ -412,8 +412,6 @@ void Binding::installFabricUIManager( "CalculateTransformedFramesEnabled", getFeatureFlagValue("calculateTransformedFramesEnabled")); - CoreFeatures::enablePropIteratorSetter = - getFeatureFlagValue("enableCppPropsIteratorSetter"); CoreFeatures::enableDefaultAsyncBatchedPriority = getFeatureFlagValue("enableDefaultAsyncBatchedPriority"); CoreFeatures::enableClonelessStateProgression = diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 7419a24d36d6..90ae88f3a72c 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<3e2c80e599d0a6852be41255b6b3c4da>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -19,10 +19,78 @@ #include "JReactNativeFeatureFlagsCxxInterop.h" #include -#include namespace facebook::react { +static jni::alias_ref getReactNativeFeatureFlagsProviderJavaClass() { + static const auto jClass = facebook::jni::findClassStatic( + "com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider"); + return jClass; +} + +/** + * Implementation of ReactNativeFeatureFlagsProvider that wraps a + * ReactNativeFeatureFlagsProvider Java object. + */ +class ReactNativeFeatureFlagsProviderHolder + : public ReactNativeFeatureFlagsProvider { + public: + explicit ReactNativeFeatureFlagsProviderHolder( + jni::alias_ref javaProvider) + : javaProvider_(make_global(javaProvider)){}; + + bool commonTestFlag() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("commonTestFlag"); + return method(javaProvider_); + } + + bool useModernRuntimeScheduler() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useModernRuntimeScheduler"); + return method(javaProvider_); + } + + bool enableMicrotasks() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableMicrotasks"); + return method(javaProvider_); + } + + bool batchRenderingUpdatesInEventLoop() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("batchRenderingUpdatesInEventLoop"); + return method(javaProvider_); + } + + bool enableSpannableBuildingUnification() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableSpannableBuildingUnification"); + return method(javaProvider_); + } + + bool enableCustomDrawOrderFabric() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableCustomDrawOrderFabric"); + return method(javaProvider_); + } + + bool enableFixForClippedSubviewsCrash() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableFixForClippedSubviewsCrash"); + return method(javaProvider_); + } + + bool enablePropIteratorSetter() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enablePropIteratorSetter"); + return method(javaProvider_); + } + + private: + jni::global_ref javaProvider_; +}; + bool JReactNativeFeatureFlagsCxxInterop::commonTestFlag( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::commonTestFlag(); @@ -58,6 +126,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableFixForClippedSubviewsCrash( return ReactNativeFeatureFlags::enableFixForClippedSubviewsCrash(); } +bool JReactNativeFeatureFlagsCxxInterop::enablePropIteratorSetter( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enablePropIteratorSetter(); +} + void JReactNativeFeatureFlagsCxxInterop::override( facebook::jni::alias_ref /*unused*/, jni::alias_ref provider) { @@ -96,6 +169,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableFixForClippedSubviewsCrash", JReactNativeFeatureFlagsCxxInterop::enableFixForClippedSubviewsCrash), + makeNativeMethod( + "enablePropIteratorSetter", + JReactNativeFeatureFlagsCxxInterop::enablePropIteratorSetter), }); } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index b03aba4b813c..32387b60abbc 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<587cf9c6de40210d76ea8184fe47abe7>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -51,6 +51,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableFixForClippedSubviewsCrash( facebook::jni::alias_ref); + static bool enablePropIteratorSetter( + facebook::jni::alias_ref); + static void override( facebook::jni::alias_ref, jni::alias_ref provider); diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.cpp deleted file mode 100644 index eac87db03ee9..000000000000 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - * - * @generated SignedSource<> - */ - -/** - * IMPORTANT: Do NOT modify this file directly. - * - * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. - * - * To regenerate this code, run the following script from the repo root: - * yarn featureflags-update - */ - -#include "ReactNativeFeatureFlagsProviderHolder.h" - -namespace facebook::react { - -static jni::alias_ref getJClass() { - static const auto jClass = facebook::jni::findClassStatic( - "com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider"); - return jClass; -} - -bool ReactNativeFeatureFlagsProviderHolder::commonTestFlag() { - static const auto method = - getJClass()->getMethod("commonTestFlag"); - return method(javaProvider_); -} - -bool ReactNativeFeatureFlagsProviderHolder::useModernRuntimeScheduler() { - static const auto method = - getJClass()->getMethod("useModernRuntimeScheduler"); - return method(javaProvider_); -} - -bool ReactNativeFeatureFlagsProviderHolder::enableMicrotasks() { - static const auto method = - getJClass()->getMethod("enableMicrotasks"); - return method(javaProvider_); -} - -bool ReactNativeFeatureFlagsProviderHolder::batchRenderingUpdatesInEventLoop() { - static const auto method = - getJClass()->getMethod("batchRenderingUpdatesInEventLoop"); - return method(javaProvider_); -} - -bool ReactNativeFeatureFlagsProviderHolder::enableSpannableBuildingUnification() { - static const auto method = - getJClass()->getMethod("enableSpannableBuildingUnification"); - return method(javaProvider_); -} - -bool ReactNativeFeatureFlagsProviderHolder::enableCustomDrawOrderFabric() { - static const auto method = - getJClass()->getMethod("enableCustomDrawOrderFabric"); - return method(javaProvider_); -} - -bool ReactNativeFeatureFlagsProviderHolder::enableFixForClippedSubviewsCrash() { - static const auto method = - getJClass()->getMethod("enableFixForClippedSubviewsCrash"); - return method(javaProvider_); -} - -} // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.h deleted file mode 100644 index 2f01f8ad159f..000000000000 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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. - * - * @generated SignedSource<<879b0c096c4a2e9692a5e133bdfd8809>> - */ - -/** - * IMPORTANT: Do NOT modify this file directly. - * - * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. - * - * To regenerate this code, run the following script from the repo root: - * yarn featureflags-update - */ - -#pragma once - -#include -#include - -namespace facebook::react { - -/** - * Implementation of ReactNativeFeatureFlagsProvider that wraps a - * ReactNativeFeatureFlagsProvider Java object. - */ -class ReactNativeFeatureFlagsProviderHolder - : public ReactNativeFeatureFlagsProvider { - public: - explicit ReactNativeFeatureFlagsProviderHolder( - jni::alias_ref javaProvider) - : javaProvider_(make_global(javaProvider)){}; - - bool commonTestFlag() override; - bool useModernRuntimeScheduler() override; - bool enableMicrotasks() override; - bool batchRenderingUpdatesInEventLoop() override; - bool enableSpannableBuildingUnification() override; - bool enableCustomDrawOrderFabric() override; - bool enableFixForClippedSubviewsCrash() override; - - private: - jni::global_ref javaProvider_; -}; - -} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 9d4b4c50bb0c..861fb75c6ca9 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<6ccf42209dea35cd5c6ac9eb882c2ef7>> + * @generated SignedSource<<04a2df0fe382bdc94ea4f7df332e33c2>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -49,6 +49,10 @@ bool ReactNativeFeatureFlags::enableFixForClippedSubviewsCrash() { return getAccessor().enableFixForClippedSubviewsCrash(); } +bool ReactNativeFeatureFlags::enablePropIteratorSetter() { + return getAccessor().enablePropIteratorSetter(); +} + void ReactNativeFeatureFlags::override( std::unique_ptr provider) { getAccessor().override(std::move(provider)); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 34d88798b5ab..ba7b7f85145d 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<9de8edbaa80b92efb68c2bcd2673eb6e>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -28,7 +28,8 @@ namespace facebook::react { /** * This class provides access to internal React Native feature flags. * - * All the methods are thread-safe if you handle `override` correctly. + * All the methods are thread-safe (as long as the methods in the overridden + * provider are). */ class ReactNativeFeatureFlags { public: @@ -67,6 +68,11 @@ class ReactNativeFeatureFlags { */ static bool enableFixForClippedSubviewsCrash(); + /** + * Specifies whether the iterator-style prop parsing is enabled. + */ + static bool enablePropIteratorSetter(); + /** * Overrides the feature flags with the ones provided by the given provider * (generally one that extends `ReactNativeFeatureFlagsDefaults`). diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index ab62bb349606..0eb3ddcf787e 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,168 +4,212 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7d50752c48503e31eccfe64d66ee2e99>> + * @generated SignedSource<<092cbc7d84b35bdeea1543c95158ab2e>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update */ #include -#include #include #include +#include #include "ReactNativeFeatureFlags.h" namespace facebook::react { ReactNativeFeatureFlagsAccessor::ReactNativeFeatureFlagsAccessor() - : currentProvider_(std::make_unique()) {} + : currentProvider_(std::make_unique()), + wasOverridden_(false) {} bool ReactNativeFeatureFlagsAccessor::commonTestFlag() { - if (!commonTestFlag_.has_value()) { - // Mark the flag as accessed. - static const char* flagName = "commonTestFlag"; - if (std::find( - accessedFeatureFlags_.begin(), - accessedFeatureFlags_.end(), - flagName) == accessedFeatureFlags_.end()) { - accessedFeatureFlags_.push_back(flagName); - } + auto flagValue = commonTestFlag_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(0, "commonTestFlag"); - commonTestFlag_.emplace(currentProvider_->commonTestFlag()); + flagValue = currentProvider_->commonTestFlag(); + commonTestFlag_ = flagValue; } - return commonTestFlag_.value(); + return flagValue.value(); } bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { - if (!useModernRuntimeScheduler_.has_value()) { - // Mark the flag as accessed. - static const char* flagName = "useModernRuntimeScheduler"; - if (std::find( - accessedFeatureFlags_.begin(), - accessedFeatureFlags_.end(), - flagName) == accessedFeatureFlags_.end()) { - accessedFeatureFlags_.push_back(flagName); - } + auto flagValue = useModernRuntimeScheduler_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(1, "useModernRuntimeScheduler"); - useModernRuntimeScheduler_.emplace(currentProvider_->useModernRuntimeScheduler()); + flagValue = currentProvider_->useModernRuntimeScheduler(); + useModernRuntimeScheduler_ = flagValue; } - return useModernRuntimeScheduler_.value(); + return flagValue.value(); } bool ReactNativeFeatureFlagsAccessor::enableMicrotasks() { - if (!enableMicrotasks_.has_value()) { - // Mark the flag as accessed. - static const char* flagName = "enableMicrotasks"; - if (std::find( - accessedFeatureFlags_.begin(), - accessedFeatureFlags_.end(), - flagName) == accessedFeatureFlags_.end()) { - accessedFeatureFlags_.push_back(flagName); - } + auto flagValue = enableMicrotasks_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(2, "enableMicrotasks"); - enableMicrotasks_.emplace(currentProvider_->enableMicrotasks()); + flagValue = currentProvider_->enableMicrotasks(); + enableMicrotasks_ = flagValue; } - return enableMicrotasks_.value(); + return flagValue.value(); } bool ReactNativeFeatureFlagsAccessor::batchRenderingUpdatesInEventLoop() { - if (!batchRenderingUpdatesInEventLoop_.has_value()) { - // Mark the flag as accessed. - static const char* flagName = "batchRenderingUpdatesInEventLoop"; - if (std::find( - accessedFeatureFlags_.begin(), - accessedFeatureFlags_.end(), - flagName) == accessedFeatureFlags_.end()) { - accessedFeatureFlags_.push_back(flagName); - } + auto flagValue = batchRenderingUpdatesInEventLoop_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. - batchRenderingUpdatesInEventLoop_.emplace(currentProvider_->batchRenderingUpdatesInEventLoop()); + markFlagAsAccessed(3, "batchRenderingUpdatesInEventLoop"); + + flagValue = currentProvider_->batchRenderingUpdatesInEventLoop(); + batchRenderingUpdatesInEventLoop_ = flagValue; } - return batchRenderingUpdatesInEventLoop_.value(); + return flagValue.value(); } bool ReactNativeFeatureFlagsAccessor::enableSpannableBuildingUnification() { - if (!enableSpannableBuildingUnification_.has_value()) { - // Mark the flag as accessed. - static const char* flagName = "enableSpannableBuildingUnification"; - if (std::find( - accessedFeatureFlags_.begin(), - accessedFeatureFlags_.end(), - flagName) == accessedFeatureFlags_.end()) { - accessedFeatureFlags_.push_back(flagName); - } + auto flagValue = enableSpannableBuildingUnification_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. - enableSpannableBuildingUnification_.emplace(currentProvider_->enableSpannableBuildingUnification()); + markFlagAsAccessed(4, "enableSpannableBuildingUnification"); + + flagValue = currentProvider_->enableSpannableBuildingUnification(); + enableSpannableBuildingUnification_ = flagValue; } - return enableSpannableBuildingUnification_.value(); + return flagValue.value(); } bool ReactNativeFeatureFlagsAccessor::enableCustomDrawOrderFabric() { - if (!enableCustomDrawOrderFabric_.has_value()) { - // Mark the flag as accessed. - static const char* flagName = "enableCustomDrawOrderFabric"; - if (std::find( - accessedFeatureFlags_.begin(), - accessedFeatureFlags_.end(), - flagName) == accessedFeatureFlags_.end()) { - accessedFeatureFlags_.push_back(flagName); - } + auto flagValue = enableCustomDrawOrderFabric_.load(); - enableCustomDrawOrderFabric_.emplace(currentProvider_->enableCustomDrawOrderFabric()); + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(5, "enableCustomDrawOrderFabric"); + + flagValue = currentProvider_->enableCustomDrawOrderFabric(); + enableCustomDrawOrderFabric_ = flagValue; } - return enableCustomDrawOrderFabric_.value(); + return flagValue.value(); } bool ReactNativeFeatureFlagsAccessor::enableFixForClippedSubviewsCrash() { - if (!enableFixForClippedSubviewsCrash_.has_value()) { - // Mark the flag as accessed. - static const char* flagName = "enableFixForClippedSubviewsCrash"; - if (std::find( - accessedFeatureFlags_.begin(), - accessedFeatureFlags_.end(), - flagName) == accessedFeatureFlags_.end()) { - accessedFeatureFlags_.push_back(flagName); - } + auto flagValue = enableFixForClippedSubviewsCrash_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(6, "enableFixForClippedSubviewsCrash"); - enableFixForClippedSubviewsCrash_.emplace(currentProvider_->enableFixForClippedSubviewsCrash()); + flagValue = currentProvider_->enableFixForClippedSubviewsCrash(); + enableFixForClippedSubviewsCrash_ = flagValue; } - return enableFixForClippedSubviewsCrash_.value(); + return flagValue.value(); +} + +bool ReactNativeFeatureFlagsAccessor::enablePropIteratorSetter() { + auto flagValue = enablePropIteratorSetter_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(7, "enablePropIteratorSetter"); + + flagValue = currentProvider_->enablePropIteratorSetter(); + enablePropIteratorSetter_ = flagValue; + } + + return flagValue.value(); } void ReactNativeFeatureFlagsAccessor::override( std::unique_ptr provider) { - if (!accessedFeatureFlags_.empty()) { - std::ostringstream featureFlagListBuilder; - for (const auto& featureFlagName : accessedFeatureFlags_) { + if (wasOverridden_) { + throw std::runtime_error( + "Feature flags cannot be overridden more than once"); + } + + ensureFlagsNotAccessed(); + wasOverridden_ = true; + currentProvider_ = std::move(provider); +} + +void ReactNativeFeatureFlagsAccessor::markFlagAsAccessed( + int position, + const char* flagName) { + accessedFeatureFlags_[position] = flagName; +} + +void ReactNativeFeatureFlagsAccessor::ensureFlagsNotAccessed() { + std::ostringstream featureFlagListBuilder; + for (const auto& featureFlagName : accessedFeatureFlags_) { + if (featureFlagName != nullptr) { featureFlagListBuilder << featureFlagName << ", "; } - std::string accessedFeatureFlagNames = featureFlagListBuilder.str(); - if (!accessedFeatureFlagNames.empty()) { - accessedFeatureFlagNames = accessedFeatureFlagNames.substr( - 0, accessedFeatureFlagNames.size() - 2); - } + } + + std::string accessedFeatureFlagNames = featureFlagListBuilder.str(); + if (!accessedFeatureFlagNames.empty()) { + accessedFeatureFlagNames = + accessedFeatureFlagNames.substr(0, accessedFeatureFlagNames.size() - 2); + } + if (!accessedFeatureFlagNames.empty()) { throw std::runtime_error( "Feature flags were accessed before being overridden: " + accessedFeatureFlagNames); } - - currentProvider_ = std::move(provider); } } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index bd3fbaee40fe..0b035a7d27ac 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<1514c04fb9d175308e106b84a14bc89d>> + * @generated SignedSource<> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -20,9 +20,10 @@ #pragma once #include +#include +#include #include #include -#include namespace facebook::react { @@ -37,20 +38,27 @@ class ReactNativeFeatureFlagsAccessor { bool enableSpannableBuildingUnification(); bool enableCustomDrawOrderFabric(); bool enableFixForClippedSubviewsCrash(); + bool enablePropIteratorSetter(); void override(std::unique_ptr provider); private: + void markFlagAsAccessed(int position, const char* flagName); + void ensureFlagsNotAccessed(); + std::unique_ptr currentProvider_; - std::vector accessedFeatureFlags_; - - std::optional commonTestFlag_; - std::optional useModernRuntimeScheduler_; - std::optional enableMicrotasks_; - std::optional batchRenderingUpdatesInEventLoop_; - std::optional enableSpannableBuildingUnification_; - std::optional enableCustomDrawOrderFabric_; - std::optional enableFixForClippedSubviewsCrash_; + bool wasOverridden_; + + std::array, 8> accessedFeatureFlags_; + + std::atomic> commonTestFlag_; + std::atomic> useModernRuntimeScheduler_; + std::atomic> enableMicrotasks_; + std::atomic> batchRenderingUpdatesInEventLoop_; + std::atomic> enableSpannableBuildingUnification_; + std::atomic> enableCustomDrawOrderFabric_; + std::atomic> enableFixForClippedSubviewsCrash_; + std::atomic> enablePropIteratorSetter_; }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 28f5b0d55bd1..9179aec29e80 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<2aa53f9149ce7321c1b8eec4ce510c4b>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -54,6 +54,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { bool enableFixForClippedSubviewsCrash() override { return false; } + + bool enablePropIteratorSetter() override { + return false; + } }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 7a252cfa02ff..e3e7654d25df 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<72abac7cc75e65bf1ded596033637050>> + * @generated SignedSource<> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -32,6 +32,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableSpannableBuildingUnification() = 0; virtual bool enableCustomDrawOrderFabric() = 0; virtual bool enableFixForClippedSubviewsCrash() = 0; + virtual bool enablePropIteratorSetter() = 0; }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/featureflags/tests/ReactNativeFeatureFlagsTest.cpp b/packages/react-native/ReactCommon/react/featureflags/tests/ReactNativeFeatureFlagsTest.cpp index ddcefef18e62..2047767dbdef 100644 --- a/packages/react-native/ReactCommon/react/featureflags/tests/ReactNativeFeatureFlagsTest.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/tests/ReactNativeFeatureFlagsTest.cpp @@ -63,6 +63,25 @@ TEST_F(ReactNativeFeatureFlagsTest, preventsOverridingAfterAccess) { EXPECT_EQ(ReactNativeFeatureFlags::commonTestFlag(), false); } +TEST_F(ReactNativeFeatureFlagsTest, preventsOverridingAfterOverride) { + ReactNativeFeatureFlags::override( + std::make_unique()); + + EXPECT_EQ(ReactNativeFeatureFlags::commonTestFlag(), true); + + try { + ReactNativeFeatureFlags::override( + std::make_unique()); + FAIL() + << "Expected ReactNativeFeatureFlags::override() to throw an exception"; + } catch (const std::runtime_error& e) { + EXPECT_STREQ("Feature flags cannot be overridden more than once", e.what()); + } + + // Original overrides should still work + EXPECT_EQ(ReactNativeFeatureFlags::commonTestFlag(), true); +} + TEST_F(ReactNativeFeatureFlagsTest, cachesValuesFromOverride) { ReactNativeFeatureFlags::override( std::make_unique()); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 2a381896ace5..cbc66ddf9f43 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<64ea070fb82bd703eb617dcf64c6a7d1>> + * @generated SignedSource<<359f833799694c092a15196afe5ce442>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -70,4 +70,9 @@ bool NativeReactNativeFeatureFlags::enableFixForClippedSubviewsCrash( return ReactNativeFeatureFlags::enableFixForClippedSubviewsCrash(); } +bool NativeReactNativeFeatureFlags::enablePropIteratorSetter( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enablePropIteratorSetter(); +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 9a419a94a245..197929accf03 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,14 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<994628655312f57c8ab774e9f119eb18>> + * @generated SignedSource<<80b7097b16e48717e9e9d867bee3e369>> */ /** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -43,6 +43,8 @@ class NativeReactNativeFeatureFlags bool enableCustomDrawOrderFabric(jsi::Runtime& runtime); bool enableFixForClippedSubviewsCrash(jsi::Runtime& runtime); + + bool enablePropIteratorSetter(jsi::Runtime& runtime); }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/image/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/components/image/CMakeLists.txt index 9dbe78d706df..408858d4e95e 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/image/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/components/image/CMakeLists.txt @@ -26,6 +26,7 @@ target_link_libraries(rrc_image jsi react_debug react_utils + react_featureflags react_render_core react_render_debug react_render_graphics diff --git a/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp index 7f660904ae83..e0f826db7e2c 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp @@ -5,10 +5,10 @@ * LICENSE file in the root directory of this source tree. */ +#include #include #include #include -#include namespace facebook::react { @@ -18,15 +18,16 @@ ImageProps::ImageProps( const RawProps& rawProps) : ViewProps(context, sourceProps, rawProps), sources( - CoreFeatures::enablePropIteratorSetter ? sourceProps.sources - : convertRawProp( - context, - rawProps, - "source", - sourceProps.sources, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.sources + : convertRawProp( + context, + rawProps, + "source", + sourceProps.sources, + {})), defaultSources( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.defaultSources : convertRawProp( context, @@ -35,7 +36,7 @@ ImageProps::ImageProps( sourceProps.defaultSources, {})), resizeMode( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.resizeMode : convertRawProp( context, @@ -44,31 +45,34 @@ ImageProps::ImageProps( sourceProps.resizeMode, ImageResizeMode::Stretch)), blurRadius( - CoreFeatures::enablePropIteratorSetter ? sourceProps.blurRadius - : convertRawProp( - context, - rawProps, - "blurRadius", - sourceProps.blurRadius, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.blurRadius + : convertRawProp( + context, + rawProps, + "blurRadius", + sourceProps.blurRadius, + {})), capInsets( - CoreFeatures::enablePropIteratorSetter ? sourceProps.capInsets - : convertRawProp( - context, - rawProps, - "capInsets", - sourceProps.capInsets, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.capInsets + : convertRawProp( + context, + rawProps, + "capInsets", + sourceProps.capInsets, + {})), tintColor( - CoreFeatures::enablePropIteratorSetter ? sourceProps.tintColor - : convertRawProp( - context, - rawProps, - "tintColor", - sourceProps.tintColor, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.tintColor + : convertRawProp( + context, + rawProps, + "tintColor", + sourceProps.tintColor, + {})), internal_analyticTag( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.internal_analyticTag : convertRawProp( context, diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/components/scrollview/CMakeLists.txt index 4e58b4d1c90c..3966bdcf2ab9 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/CMakeLists.txt @@ -25,6 +25,7 @@ target_link_libraries(rrc_scrollview glog_init jsi react_debug + react_featureflags react_render_core react_render_debug react_render_graphics diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp index 4bf5b3c038c2..b85d9e9f6538 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp @@ -7,10 +7,10 @@ #include "ScrollViewProps.h" +#include #include #include #include -#include #include @@ -22,7 +22,7 @@ ScrollViewProps::ScrollViewProps( const RawProps& rawProps) : ViewProps(context, sourceProps, rawProps), alwaysBounceHorizontal( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.alwaysBounceHorizontal : convertRawProp( context, @@ -31,7 +31,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.alwaysBounceHorizontal, {})), alwaysBounceVertical( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.alwaysBounceVertical : convertRawProp( context, @@ -40,23 +40,25 @@ ScrollViewProps::ScrollViewProps( sourceProps.alwaysBounceVertical, {})), bounces( - CoreFeatures::enablePropIteratorSetter ? sourceProps.bounces - : convertRawProp( - context, - rawProps, - "bounces", - sourceProps.bounces, - true)), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.bounces + : convertRawProp( + context, + rawProps, + "bounces", + sourceProps.bounces, + true)), bouncesZoom( - CoreFeatures::enablePropIteratorSetter ? sourceProps.bouncesZoom - : convertRawProp( - context, - rawProps, - "bouncesZoom", - sourceProps.bouncesZoom, - true)), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.bouncesZoom + : convertRawProp( + context, + rawProps, + "bouncesZoom", + sourceProps.bouncesZoom, + true)), canCancelContentTouches( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.canCancelContentTouches : convertRawProp( context, @@ -65,7 +67,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.canCancelContentTouches, true)), centerContent( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.centerContent : convertRawProp( context, @@ -74,7 +76,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.centerContent, {})), automaticallyAdjustContentInsets( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.automaticallyAdjustContentInsets : convertRawProp( context, @@ -83,7 +85,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.automaticallyAdjustContentInsets, {})), automaticallyAdjustsScrollIndicatorInsets( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.automaticallyAdjustsScrollIndicatorInsets : convertRawProp( context, @@ -92,7 +94,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.automaticallyAdjustsScrollIndicatorInsets, true)), decelerationRate( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.decelerationRate : convertRawProp( context, @@ -101,7 +103,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.decelerationRate, (Float)0.998)), directionalLockEnabled( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.directionalLockEnabled : convertRawProp( context, @@ -110,7 +112,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.directionalLockEnabled, {})), indicatorStyle( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.indicatorStyle : convertRawProp( context, @@ -119,7 +121,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.indicatorStyle, {})), keyboardDismissMode( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.keyboardDismissMode : convertRawProp( context, @@ -128,7 +130,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.keyboardDismissMode, {})), maintainVisibleContentPosition( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.maintainVisibleContentPosition : convertRawProp( context, @@ -137,7 +139,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.maintainVisibleContentPosition, {})), maximumZoomScale( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.maximumZoomScale : convertRawProp( context, @@ -146,7 +148,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.maximumZoomScale, (Float)1.0)), minimumZoomScale( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.minimumZoomScale : convertRawProp( context, @@ -155,7 +157,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.minimumZoomScale, (Float)1.0)), scrollEnabled( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.scrollEnabled : convertRawProp( context, @@ -164,7 +166,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.scrollEnabled, true)), pagingEnabled( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.pagingEnabled : convertRawProp( context, @@ -173,7 +175,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.pagingEnabled, {})), pinchGestureEnabled( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.pinchGestureEnabled : convertRawProp( context, @@ -182,15 +184,16 @@ ScrollViewProps::ScrollViewProps( sourceProps.pinchGestureEnabled, true)), scrollsToTop( - CoreFeatures::enablePropIteratorSetter ? sourceProps.scrollsToTop - : convertRawProp( - context, - rawProps, - "scrollsToTop", - sourceProps.scrollsToTop, - true)), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.scrollsToTop + : convertRawProp( + context, + rawProps, + "scrollsToTop", + sourceProps.scrollsToTop, + true)), showsHorizontalScrollIndicator( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.showsHorizontalScrollIndicator : convertRawProp( context, @@ -199,7 +202,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.showsHorizontalScrollIndicator, true)), showsVerticalScrollIndicator( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.showsVerticalScrollIndicator : convertRawProp( context, @@ -208,7 +211,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.showsVerticalScrollIndicator, true)), scrollEventThrottle( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.scrollEventThrottle : convertRawProp( context, @@ -217,23 +220,25 @@ ScrollViewProps::ScrollViewProps( sourceProps.scrollEventThrottle, {})), zoomScale( - CoreFeatures::enablePropIteratorSetter ? sourceProps.zoomScale - : convertRawProp( - context, - rawProps, - "zoomScale", - sourceProps.zoomScale, - (Float)1.0)), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.zoomScale + : convertRawProp( + context, + rawProps, + "zoomScale", + sourceProps.zoomScale, + (Float)1.0)), contentInset( - CoreFeatures::enablePropIteratorSetter ? sourceProps.contentInset - : convertRawProp( - context, - rawProps, - "contentInset", - sourceProps.contentInset, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.contentInset + : convertRawProp( + context, + rawProps, + "contentInset", + sourceProps.contentInset, + {})), contentOffset( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.contentOffset : convertRawProp( context, @@ -242,7 +247,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.contentOffset, {})), scrollIndicatorInsets( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.scrollIndicatorInsets : convertRawProp( context, @@ -251,7 +256,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.scrollIndicatorInsets, {})), snapToInterval( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.snapToInterval : convertRawProp( context, @@ -260,7 +265,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.snapToInterval, {})), snapToAlignment( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.snapToAlignment : convertRawProp( context, @@ -269,7 +274,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.snapToAlignment, {})), disableIntervalMomentum( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.disableIntervalMomentum : convertRawProp( context, @@ -278,7 +283,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.disableIntervalMomentum, {})), snapToOffsets( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.snapToOffsets : convertRawProp( context, @@ -287,23 +292,25 @@ ScrollViewProps::ScrollViewProps( sourceProps.snapToOffsets, {})), snapToStart( - CoreFeatures::enablePropIteratorSetter ? sourceProps.snapToStart - : convertRawProp( - context, - rawProps, - "snapToStart", - sourceProps.snapToStart, - true)), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.snapToStart + : convertRawProp( + context, + rawProps, + "snapToStart", + sourceProps.snapToStart, + true)), snapToEnd( - CoreFeatures::enablePropIteratorSetter ? sourceProps.snapToEnd - : convertRawProp( - context, - rawProps, - "snapToEnd", - sourceProps.snapToEnd, - true)), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.snapToEnd + : convertRawProp( + context, + rawProps, + "snapToEnd", + sourceProps.snapToEnd, + true)), contentInsetAdjustmentBehavior( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.contentInsetAdjustmentBehavior : convertRawProp( context, @@ -312,7 +319,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.contentInsetAdjustmentBehavior, {ContentInsetAdjustmentBehavior::Never})), scrollToOverflowEnabled( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.scrollToOverflowEnabled : convertRawProp( context, @@ -321,7 +328,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.scrollToOverflowEnabled, {})), isInvertedVirtualizedList( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.isInvertedVirtualizedList : convertRawProp( context, diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp index cb5a93b703f8..fce05ca8d450 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp @@ -7,11 +7,11 @@ #include "BaseTextProps.h" +#include #include #include #include #include -#include namespace facebook::react { @@ -218,7 +218,7 @@ BaseTextProps::BaseTextProps( const BaseTextProps& sourceProps, const RawProps& rawProps) : textAttributes( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.textAttributes : convertRawProp( context, diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/components/text/CMakeLists.txt index 394d72d7de52..1d5cbf7914a5 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/components/text/CMakeLists.txt @@ -25,6 +25,7 @@ target_link_libraries(rrc_text glog_init jsi react_debug + react_featureflags react_render_attributedstring react_render_core react_render_debug diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphProps.cpp index 4011bbf2dc8f..173c822e3580 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphProps.cpp @@ -7,13 +7,11 @@ #include "ParagraphProps.h" +#include #include #include #include #include -#include - -#include namespace facebook::react { @@ -24,7 +22,7 @@ ParagraphProps::ParagraphProps( : ViewProps(context, sourceProps, rawProps), BaseTextProps(context, sourceProps, rawProps), paragraphAttributes( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.paragraphAttributes : convertRawProp( context, @@ -32,21 +30,23 @@ ParagraphProps::ParagraphProps( sourceProps.paragraphAttributes, {})), isSelectable( - CoreFeatures::enablePropIteratorSetter ? sourceProps.isSelectable - : convertRawProp( - context, - rawProps, - "selectable", - sourceProps.isSelectable, - false)), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.isSelectable + : convertRawProp( + context, + rawProps, + "selectable", + sourceProps.isSelectable, + false)), onTextLayout( - CoreFeatures::enablePropIteratorSetter ? sourceProps.onTextLayout - : convertRawProp( - context, - rawProps, - "onTextLayout", - sourceProps.onTextLayout, - {})) { + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.onTextLayout + : convertRawProp( + context, + rawProps, + "onTextLayout", + sourceProps.onTextLayout, + {})) { /* * These props are applied to `View`, therefore they must not be a part of * base text attributes. diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/components/textinput/CMakeLists.txt index e8d12d59df91..1ac61dd16eef 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/CMakeLists.txt @@ -28,6 +28,7 @@ target_link_libraries(rrc_textinput glog_init jsi react_debug + react_featureflags react_render_attributedstring react_render_componentregistry react_render_core diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp index ea0fb6a1674e..2b587ad4cf31 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp @@ -6,10 +6,10 @@ */ #include "AndroidTextInputProps.h" +#include #include #include #include -#include namespace facebook::react { @@ -38,209 +38,209 @@ AndroidTextInputProps::AndroidTextInputProps( const RawProps &rawProps) : ViewProps(context, sourceProps, rawProps), BaseTextProps(context, sourceProps, rawProps), - autoComplete(CoreFeatures::enablePropIteratorSetter? sourceProps.autoComplete : convertRawProp( + autoComplete(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.autoComplete : convertRawProp( context, rawProps, "autoComplete", sourceProps.autoComplete, {})), - returnKeyLabel(CoreFeatures::enablePropIteratorSetter? sourceProps.autoComplete : convertRawProp(context, rawProps, + returnKeyLabel(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.autoComplete : convertRawProp(context, rawProps, "returnKeyLabel", sourceProps.returnKeyLabel, {})), - numberOfLines(CoreFeatures::enablePropIteratorSetter? sourceProps.numberOfLines : convertRawProp(context, rawProps, + numberOfLines(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.numberOfLines : convertRawProp(context, rawProps, "numberOfLines", sourceProps.numberOfLines, {0})), - disableFullscreenUI(CoreFeatures::enablePropIteratorSetter? sourceProps.disableFullscreenUI : convertRawProp(context, rawProps, + disableFullscreenUI(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.disableFullscreenUI : convertRawProp(context, rawProps, "disableFullscreenUI", sourceProps.disableFullscreenUI, {false})), - textBreakStrategy(CoreFeatures::enablePropIteratorSetter? sourceProps.textBreakStrategy : convertRawProp(context, rawProps, + textBreakStrategy(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.textBreakStrategy : convertRawProp(context, rawProps, "textBreakStrategy", sourceProps.textBreakStrategy, {})), - underlineColorAndroid(CoreFeatures::enablePropIteratorSetter? sourceProps.underlineColorAndroid : convertRawProp(context, rawProps, + underlineColorAndroid(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.underlineColorAndroid : convertRawProp(context, rawProps, "underlineColorAndroid", sourceProps.underlineColorAndroid, {})), - inlineImageLeft(CoreFeatures::enablePropIteratorSetter? sourceProps.inlineImageLeft : convertRawProp(context, rawProps, + inlineImageLeft(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.inlineImageLeft : convertRawProp(context, rawProps, "inlineImageLeft", sourceProps.inlineImageLeft, {})), - inlineImagePadding(CoreFeatures::enablePropIteratorSetter? sourceProps.inlineImagePadding : convertRawProp(context, rawProps, + inlineImagePadding(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.inlineImagePadding : convertRawProp(context, rawProps, "inlineImagePadding", sourceProps.inlineImagePadding, {0})), - importantForAutofill(CoreFeatures::enablePropIteratorSetter? sourceProps.importantForAutofill : convertRawProp(context, rawProps, + importantForAutofill(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.importantForAutofill : convertRawProp(context, rawProps, "importantForAutofill", sourceProps.importantForAutofill, {})), - showSoftInputOnFocus(CoreFeatures::enablePropIteratorSetter? sourceProps.showSoftInputOnFocus : convertRawProp(context, rawProps, + showSoftInputOnFocus(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.showSoftInputOnFocus : convertRawProp(context, rawProps, "showSoftInputOnFocus", sourceProps.showSoftInputOnFocus, {false})), - autoCapitalize(CoreFeatures::enablePropIteratorSetter? sourceProps.autoCapitalize : convertRawProp(context, rawProps, + autoCapitalize(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.autoCapitalize : convertRawProp(context, rawProps, "autoCapitalize", sourceProps.autoCapitalize, {})), - autoCorrect(CoreFeatures::enablePropIteratorSetter? sourceProps.autoCorrect : convertRawProp(context, rawProps, + autoCorrect(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.autoCorrect : convertRawProp(context, rawProps, "autoCorrect", sourceProps.autoCorrect, {false})), - autoFocus(CoreFeatures::enablePropIteratorSetter? sourceProps.autoFocus : convertRawProp(context, rawProps, + autoFocus(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.autoFocus : convertRawProp(context, rawProps, "autoFocus", sourceProps.autoFocus, {false})), - allowFontScaling(CoreFeatures::enablePropIteratorSetter? sourceProps.allowFontScaling : convertRawProp(context, rawProps, + allowFontScaling(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.allowFontScaling : convertRawProp(context, rawProps, "allowFontScaling", sourceProps.allowFontScaling, {false})), - maxFontSizeMultiplier(CoreFeatures::enablePropIteratorSetter? sourceProps.maxFontSizeMultiplier : convertRawProp(context, rawProps, + maxFontSizeMultiplier(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.maxFontSizeMultiplier : convertRawProp(context, rawProps, "maxFontSizeMultiplier", sourceProps.maxFontSizeMultiplier, {0.0})), - editable(CoreFeatures::enablePropIteratorSetter? sourceProps.editable : + editable(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.editable : convertRawProp(context, rawProps, "editable", sourceProps.editable, {false})), - keyboardType(CoreFeatures::enablePropIteratorSetter? sourceProps.keyboardType : convertRawProp(context, rawProps, + keyboardType(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.keyboardType : convertRawProp(context, rawProps, "keyboardType", sourceProps.keyboardType, {})), - returnKeyType(CoreFeatures::enablePropIteratorSetter? sourceProps.returnKeyType : convertRawProp(context, rawProps, + returnKeyType(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.returnKeyType : convertRawProp(context, rawProps, "returnKeyType", sourceProps.returnKeyType, {})), - maxLength(CoreFeatures::enablePropIteratorSetter? sourceProps.maxLength : + maxLength(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.maxLength : convertRawProp(context, rawProps, "maxLength", sourceProps.maxLength, {0})), - multiline(CoreFeatures::enablePropIteratorSetter? sourceProps.multiline : convertRawProp(context, rawProps, + multiline(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.multiline : convertRawProp(context, rawProps, "multiline", sourceProps.multiline, {false})), - placeholder(CoreFeatures::enablePropIteratorSetter? sourceProps.placeholder : + placeholder(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.placeholder : convertRawProp(context, rawProps, "placeholder", sourceProps.placeholder, {})), - placeholderTextColor(CoreFeatures::enablePropIteratorSetter? sourceProps.placeholderTextColor : convertRawProp(context, rawProps, + placeholderTextColor(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.placeholderTextColor : convertRawProp(context, rawProps, "placeholderTextColor", sourceProps.placeholderTextColor, {})), - secureTextEntry(CoreFeatures::enablePropIteratorSetter? sourceProps.secureTextEntry : convertRawProp(context, rawProps, + secureTextEntry(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.secureTextEntry : convertRawProp(context, rawProps, "secureTextEntry", sourceProps.secureTextEntry, {false})), - selectionColor(CoreFeatures::enablePropIteratorSetter? sourceProps.selectionColor : convertRawProp(context, rawProps, + selectionColor(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.selectionColor : convertRawProp(context, rawProps, "selectionColor", sourceProps.selectionColor, {})), - selectionHandleColor(CoreFeatures::enablePropIteratorSetter? sourceProps.selectionHandleColor : convertRawProp(context, rawProps, + selectionHandleColor(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.selectionHandleColor : convertRawProp(context, rawProps, "selectionHandleColor", sourceProps.selectionHandleColor, {})), - value(CoreFeatures::enablePropIteratorSetter? sourceProps.value : convertRawProp(context, rawProps, "value", sourceProps.value, {})), - defaultValue(CoreFeatures::enablePropIteratorSetter? sourceProps.defaultValue : convertRawProp(context, rawProps, + value(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.value : convertRawProp(context, rawProps, "value", sourceProps.value, {})), + defaultValue(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.defaultValue : convertRawProp(context, rawProps, "defaultValue", sourceProps.defaultValue, {})), - selectTextOnFocus(CoreFeatures::enablePropIteratorSetter? sourceProps.selectTextOnFocus : convertRawProp(context, rawProps, + selectTextOnFocus(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.selectTextOnFocus : convertRawProp(context, rawProps, "selectTextOnFocus", sourceProps.selectTextOnFocus, {false})), - submitBehavior(CoreFeatures::enablePropIteratorSetter? sourceProps.submitBehavior : convertRawProp(context, rawProps, + submitBehavior(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.submitBehavior : convertRawProp(context, rawProps, "submitBehavior", sourceProps.submitBehavior, {})), - caretHidden(CoreFeatures::enablePropIteratorSetter? sourceProps.caretHidden : convertRawProp(context, rawProps, + caretHidden(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.caretHidden : convertRawProp(context, rawProps, "caretHidden", sourceProps.caretHidden, {false})), - contextMenuHidden(CoreFeatures::enablePropIteratorSetter? sourceProps.contextMenuHidden : convertRawProp(context, rawProps, + contextMenuHidden(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.contextMenuHidden : convertRawProp(context, rawProps, "contextMenuHidden", sourceProps.contextMenuHidden, {false})), - textShadowColor(CoreFeatures::enablePropIteratorSetter? sourceProps.textShadowColor : convertRawProp(context, rawProps, + textShadowColor(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.textShadowColor : convertRawProp(context, rawProps, "textShadowColor", sourceProps.textShadowColor, {})), - textShadowRadius(CoreFeatures::enablePropIteratorSetter? sourceProps.textShadowRadius : convertRawProp(context, rawProps, + textShadowRadius(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.textShadowRadius : convertRawProp(context, rawProps, "textShadowRadius", sourceProps.textShadowRadius, {0.0})), - textDecorationLine(CoreFeatures::enablePropIteratorSetter? sourceProps.textDecorationLine : convertRawProp(context, rawProps, + textDecorationLine(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.textDecorationLine : convertRawProp(context, rawProps, "textDecorationLine", sourceProps.textDecorationLine, {})), - fontStyle(CoreFeatures::enablePropIteratorSetter? sourceProps.fontStyle : + fontStyle(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.fontStyle : convertRawProp(context, rawProps, "fontStyle", sourceProps.fontStyle, {})), - textShadowOffset(CoreFeatures::enablePropIteratorSetter? sourceProps.textShadowOffset : convertRawProp(context, rawProps, + textShadowOffset(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.textShadowOffset : convertRawProp(context, rawProps, "textShadowOffset", sourceProps.textShadowOffset, {})), - lineHeight(CoreFeatures::enablePropIteratorSetter? sourceProps.lineHeight : convertRawProp(context, rawProps, + lineHeight(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.lineHeight : convertRawProp(context, rawProps, "lineHeight", sourceProps.lineHeight, {0.0})), - textTransform(CoreFeatures::enablePropIteratorSetter? sourceProps.textTransform : convertRawProp(context, rawProps, + textTransform(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.textTransform : convertRawProp(context, rawProps, "textTransform", sourceProps.textTransform, {})), color(0 /*convertRawProp(context, rawProps, "color", sourceProps.color, {0})*/), - letterSpacing(CoreFeatures::enablePropIteratorSetter? sourceProps.letterSpacing : convertRawProp(context, rawProps, + letterSpacing(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.letterSpacing : convertRawProp(context, rawProps, "letterSpacing", sourceProps.letterSpacing, {0.0})), - fontSize(CoreFeatures::enablePropIteratorSetter? sourceProps.fontSize : + fontSize(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.fontSize : convertRawProp(context, rawProps, "fontSize", sourceProps.fontSize, {0.0})), - textAlign(CoreFeatures::enablePropIteratorSetter? sourceProps.textAlign : + textAlign(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.textAlign : convertRawProp(context, rawProps, "textAlign", sourceProps.textAlign, {})), - includeFontPadding(CoreFeatures::enablePropIteratorSetter? sourceProps.includeFontPadding : convertRawProp(context, rawProps, + includeFontPadding(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.includeFontPadding : convertRawProp(context, rawProps, "includeFontPadding", sourceProps.includeFontPadding, {false})), - fontWeight(CoreFeatures::enablePropIteratorSetter? sourceProps.fontWeight : + fontWeight(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.fontWeight : convertRawProp(context, rawProps, "fontWeight", sourceProps.fontWeight, {})), - fontFamily(CoreFeatures::enablePropIteratorSetter? sourceProps.fontFamily : + fontFamily(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.fontFamily : convertRawProp(context, rawProps, "fontFamily", sourceProps.fontFamily, {})), - textAlignVertical(CoreFeatures::enablePropIteratorSetter? sourceProps.textAlignVertical : convertRawProp(context, rawProps, + textAlignVertical(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.textAlignVertical : convertRawProp(context, rawProps, "textAlignVertical", sourceProps.textAlignVertical, {})), - cursorColor(CoreFeatures::enablePropIteratorSetter? sourceProps.cursorColor : + cursorColor(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.cursorColor : convertRawProp(context, rawProps, "cursorColor", sourceProps.cursorColor, {})), - mostRecentEventCount(CoreFeatures::enablePropIteratorSetter? sourceProps.mostRecentEventCount : convertRawProp(context, rawProps, + mostRecentEventCount(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.mostRecentEventCount : convertRawProp(context, rawProps, "mostRecentEventCount", sourceProps.mostRecentEventCount, {0})), - text(CoreFeatures::enablePropIteratorSetter? sourceProps.text : convertRawProp(context, rawProps, "text", sourceProps.text, {})), - paragraphAttributes(CoreFeatures::enablePropIteratorSetter? sourceProps.paragraphAttributes : + text(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.text : convertRawProp(context, rawProps, "text", sourceProps.text, {})), + paragraphAttributes(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.paragraphAttributes : convertRawProp(context, rawProps, sourceProps.paragraphAttributes, {})), // See AndroidTextInputComponentDescriptor for usage // TODO T63008435: can these, and this feature, be removed entirely? - hasPadding(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPadding : hasValue(rawProps, sourceProps.hasPadding, "padding")), - hasPaddingHorizontal(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingHorizontal : hasValue( + hasPadding(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.hasPadding : hasValue(rawProps, sourceProps.hasPadding, "padding")), + hasPaddingHorizontal(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.hasPaddingHorizontal : hasValue( rawProps, sourceProps.hasPaddingHorizontal, "paddingHorizontal")), - hasPaddingVertical(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingVertical : hasValue( + hasPaddingVertical(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.hasPaddingVertical : hasValue( rawProps, sourceProps.hasPaddingVertical, "paddingVertical")), - hasPaddingLeft(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingLeft : hasValue( + hasPaddingLeft(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.hasPaddingLeft : hasValue( rawProps, sourceProps.hasPaddingLeft, "paddingLeft")), - hasPaddingTop(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingTop : + hasPaddingTop(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.hasPaddingTop : hasValue(rawProps, sourceProps.hasPaddingTop, "paddingTop")), - hasPaddingRight(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingRight : hasValue( + hasPaddingRight(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.hasPaddingRight : hasValue( rawProps, sourceProps.hasPaddingRight, "paddingRight")), - hasPaddingBottom(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingBottom : hasValue( + hasPaddingBottom(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.hasPaddingBottom : hasValue( rawProps, sourceProps.hasPaddingBottom, "paddingBottom")), - hasPaddingStart(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingStart : hasValue( + hasPaddingStart(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.hasPaddingStart : hasValue( rawProps, sourceProps.hasPaddingStart, "paddingStart")), - hasPaddingEnd(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingEnd : + hasPaddingEnd(ReactNativeFeatureFlags::enablePropIteratorSetter()? sourceProps.hasPaddingEnd : hasValue(rawProps, sourceProps.hasPaddingEnd, "paddingEnd")) { } diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityProps.cpp index bb5e7a6f288a..13a9b28eb04d 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityProps.cpp @@ -7,11 +7,11 @@ #include "AccessibilityProps.h" +#include #include #include #include #include -#include namespace facebook::react { @@ -20,15 +20,16 @@ AccessibilityProps::AccessibilityProps( const AccessibilityProps& sourceProps, const RawProps& rawProps) : accessible( - CoreFeatures::enablePropIteratorSetter ? sourceProps.accessible - : convertRawProp( - context, - rawProps, - "accessible", - sourceProps.accessible, - false)), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.accessible + : convertRawProp( + context, + rawProps, + "accessible", + sourceProps.accessible, + false)), accessibilityState( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.accessibilityState : convertRawProp( context, @@ -37,7 +38,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityState, {})), accessibilityLabel( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.accessibilityLabel : convertRawProp( context, @@ -46,7 +47,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityLabel, "")), accessibilityLabelledBy( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.accessibilityLabelledBy : convertRawProp( context, @@ -55,7 +56,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityLabelledBy, {})), accessibilityLiveRegion( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.accessibilityLiveRegion : convertRawProp( context, @@ -64,7 +65,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityLiveRegion, AccessibilityLiveRegion::None)), accessibilityHint( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.accessibilityHint : convertRawProp( context, @@ -73,7 +74,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityHint, "")), accessibilityLanguage( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.accessibilityLanguage : convertRawProp( context, @@ -82,7 +83,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityLanguage, "")), accessibilityValue( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.accessibilityValue : convertRawProp( context, @@ -91,7 +92,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityValue, {})), accessibilityActions( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.accessibilityActions : convertRawProp( context, @@ -100,7 +101,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityActions, {})), accessibilityViewIsModal( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.accessibilityViewIsModal : convertRawProp( context, @@ -109,7 +110,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityViewIsModal, false)), accessibilityElementsHidden( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.accessibilityElementsHidden : convertRawProp( context, @@ -118,7 +119,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityElementsHidden, false)), accessibilityIgnoresInvertColors( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.accessibilityIgnoresInvertColors : convertRawProp( context, @@ -127,7 +128,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityIgnoresInvertColors, false)), onAccessibilityTap( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.onAccessibilityTap : convertRawProp( context, @@ -136,7 +137,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.onAccessibilityTap, {})), onAccessibilityMagicTap( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.onAccessibilityMagicTap : convertRawProp( context, @@ -145,7 +146,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.onAccessibilityMagicTap, {})), onAccessibilityEscape( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.onAccessibilityEscape : convertRawProp( context, @@ -154,7 +155,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.onAccessibilityEscape, {})), onAccessibilityAction( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.onAccessibilityAction : convertRawProp( context, @@ -163,7 +164,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.onAccessibilityAction, {})), importantForAccessibility( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.importantForAccessibility : convertRawProp( context, @@ -172,13 +173,14 @@ AccessibilityProps::AccessibilityProps( sourceProps.importantForAccessibility, ImportantForAccessibility::Auto)), testId( - CoreFeatures::enablePropIteratorSetter ? sourceProps.testId - : convertRawProp( - context, - rawProps, - "testID", - sourceProps.testId, - "")) { + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.testId + : convertRawProp( + context, + rawProps, + "testID", + sourceProps.testId, + "")) { // It is a (severe!) perf deoptimization to request props out-of-order. // Thus, since we need to request the same prop twice here // (accessibilityRole) we "must" do them subsequently here to prevent @@ -186,7 +188,7 @@ AccessibilityProps::AccessibilityProps( // it probably can, but this is a fairly rare edge-case that (1) is easy-ish // to work around here, and (2) would require very careful work to address // this case and not regress the more common cases. - if (!CoreFeatures::enablePropIteratorSetter) { + if (!ReactNativeFeatureFlags::enablePropIteratorSetter()) { auto* accessibilityRoleValue = rawProps.at("accessibilityRole", nullptr, nullptr); auto* roleValue = rawProps.at("role", nullptr, nullptr); diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp index 3d55f25c38cb..71b6d7cacae4 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp @@ -9,12 +9,12 @@ #include +#include #include #include #include #include #include -#include namespace facebook::react { @@ -55,15 +55,16 @@ BaseViewProps::BaseViewProps( : YogaStylableProps(context, sourceProps, rawProps), AccessibilityProps(context, sourceProps, rawProps), opacity( - CoreFeatures::enablePropIteratorSetter ? sourceProps.opacity - : convertRawProp( - context, - rawProps, - "opacity", - sourceProps.opacity, - (Float)1.0)), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.opacity + : convertRawProp( + context, + rawProps, + "opacity", + sourceProps.opacity, + (Float)1.0)), backgroundColor( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.backgroundColor : convertRawProp( context, @@ -72,59 +73,65 @@ BaseViewProps::BaseViewProps( sourceProps.backgroundColor, {})), borderRadii( - CoreFeatures::enablePropIteratorSetter ? sourceProps.borderRadii - : convertRawProp( - context, - rawProps, - "border", - "Radius", - sourceProps.borderRadii, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.borderRadii + : convertRawProp( + context, + rawProps, + "border", + "Radius", + sourceProps.borderRadii, + {})), borderColors( - CoreFeatures::enablePropIteratorSetter ? sourceProps.borderColors - : convertRawProp( - context, - rawProps, - "border", - "Color", - sourceProps.borderColors, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.borderColors + : convertRawProp( + context, + rawProps, + "border", + "Color", + sourceProps.borderColors, + {})), borderCurves( - CoreFeatures::enablePropIteratorSetter ? sourceProps.borderCurves - : convertRawProp( - context, - rawProps, - "border", - "Curve", - sourceProps.borderCurves, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.borderCurves + : convertRawProp( + context, + rawProps, + "border", + "Curve", + sourceProps.borderCurves, + {})), borderStyles( - CoreFeatures::enablePropIteratorSetter ? sourceProps.borderStyles - : convertRawProp( - context, - rawProps, - "border", - "Style", - sourceProps.borderStyles, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.borderStyles + : convertRawProp( + context, + rawProps, + "border", + "Style", + sourceProps.borderStyles, + {})), shadowColor( - CoreFeatures::enablePropIteratorSetter ? sourceProps.shadowColor - : convertRawProp( - context, - rawProps, - "shadowColor", - sourceProps.shadowColor, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.shadowColor + : convertRawProp( + context, + rawProps, + "shadowColor", + sourceProps.shadowColor, + {})), shadowOffset( - CoreFeatures::enablePropIteratorSetter ? sourceProps.shadowOffset - : convertRawProp( - context, - rawProps, - "shadowOffset", - sourceProps.shadowOffset, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.shadowOffset + : convertRawProp( + context, + rawProps, + "shadowOffset", + sourceProps.shadowOffset, + {})), shadowOpacity( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.shadowOpacity : convertRawProp( context, @@ -133,23 +140,25 @@ BaseViewProps::BaseViewProps( sourceProps.shadowOpacity, {})), shadowRadius( - CoreFeatures::enablePropIteratorSetter ? sourceProps.shadowRadius - : convertRawProp( - context, - rawProps, - "shadowRadius", - sourceProps.shadowRadius, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.shadowRadius + : convertRawProp( + context, + rawProps, + "shadowRadius", + sourceProps.shadowRadius, + {})), transform( - CoreFeatures::enablePropIteratorSetter ? sourceProps.transform - : convertRawProp( - context, - rawProps, - "transform", - sourceProps.transform, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.transform + : convertRawProp( + context, + rawProps, + "transform", + sourceProps.transform, + {})), transformOrigin( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.transformOrigin : convertRawProp( context, @@ -158,7 +167,7 @@ BaseViewProps::BaseViewProps( sourceProps.transformOrigin, {})), backfaceVisibility( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.backfaceVisibility : convertRawProp( context, @@ -167,7 +176,7 @@ BaseViewProps::BaseViewProps( sourceProps.backfaceVisibility, {})), shouldRasterize( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.shouldRasterize : convertRawProp( context, @@ -176,15 +185,16 @@ BaseViewProps::BaseViewProps( sourceProps.shouldRasterize, {})), zIndex( - CoreFeatures::enablePropIteratorSetter ? sourceProps.zIndex - : convertRawProp( - context, - rawProps, - "zIndex", - sourceProps.zIndex, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.zIndex + : convertRawProp( + context, + rawProps, + "zIndex", + sourceProps.zIndex, + {})), pointerEvents( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.pointerEvents : convertRawProp( context, @@ -193,35 +203,38 @@ BaseViewProps::BaseViewProps( sourceProps.pointerEvents, {})), hitSlop( - CoreFeatures::enablePropIteratorSetter ? sourceProps.hitSlop - : convertRawProp( - context, - rawProps, - "hitSlop", - sourceProps.hitSlop, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.hitSlop + : convertRawProp( + context, + rawProps, + "hitSlop", + sourceProps.hitSlop, + {})), onLayout( - CoreFeatures::enablePropIteratorSetter ? sourceProps.onLayout - : convertRawProp( - context, - rawProps, - "onLayout", - sourceProps.onLayout, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.onLayout + : convertRawProp( + context, + rawProps, + "onLayout", + sourceProps.onLayout, + {})), events( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.events : convertRawProp(context, rawProps, sourceProps.events, {})), collapsable( - CoreFeatures::enablePropIteratorSetter ? sourceProps.collapsable - : convertRawProp( - context, - rawProps, - "collapsable", - sourceProps.collapsable, - true)), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.collapsable + : convertRawProp( + context, + rawProps, + "collapsable", + sourceProps.collapsable, + true)), removeClippedSubviews( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.removeClippedSubviews : convertRawProp( context, @@ -230,7 +243,7 @@ BaseViewProps::BaseViewProps( sourceProps.removeClippedSubviews, false)), experimental_layoutConformance( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.experimental_layoutConformance : convertRawProp( context, diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/components/view/CMakeLists.txt index 2cf299bcbb4b..cdff5d2f51c4 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/components/view/CMakeLists.txt @@ -33,6 +33,7 @@ target_link_libraries(rrc_view jsi logger react_debug + react_featureflags react_render_core react_render_debug react_render_graphics diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp index 508e3aeb6cac..d40bbdf66ad8 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp @@ -7,11 +7,11 @@ #include "YogaStylableProps.h" +#include #include #include #include #include -#include #include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp index 021268bfdac6..7251b9caa56d 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp @@ -7,13 +7,11 @@ #include "HostPlatformViewProps.h" -#include - +#include #include #include #include #include -#include namespace facebook::react { @@ -23,15 +21,16 @@ HostPlatformViewProps::HostPlatformViewProps( const RawProps& rawProps) : BaseViewProps(context, sourceProps, rawProps), elevation( - CoreFeatures::enablePropIteratorSetter ? sourceProps.elevation - : convertRawProp( - context, - rawProps, - "elevation", - sourceProps.elevation, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.elevation + : convertRawProp( + context, + rawProps, + "elevation", + sourceProps.elevation, + {})), nativeBackground( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.nativeBackground : convertRawProp( context, @@ -40,7 +39,7 @@ HostPlatformViewProps::HostPlatformViewProps( sourceProps.nativeBackground, {})), nativeForeground( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.nativeForeground : convertRawProp( context, @@ -49,15 +48,16 @@ HostPlatformViewProps::HostPlatformViewProps( sourceProps.nativeForeground, {})), focusable( - CoreFeatures::enablePropIteratorSetter ? sourceProps.focusable - : convertRawProp( - context, - rawProps, - "focusable", - sourceProps.focusable, - {})), + ReactNativeFeatureFlags::enablePropIteratorSetter() + ? sourceProps.focusable + : convertRawProp( + context, + rawProps, + "focusable", + sourceProps.focusable, + {})), hasTVPreferredFocus( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.hasTVPreferredFocus : convertRawProp( context, @@ -66,7 +66,7 @@ HostPlatformViewProps::HostPlatformViewProps( sourceProps.hasTVPreferredFocus, {})), needsOffscreenAlphaCompositing( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.needsOffscreenAlphaCompositing : convertRawProp( context, @@ -75,7 +75,7 @@ HostPlatformViewProps::HostPlatformViewProps( sourceProps.needsOffscreenAlphaCompositing, {})), renderToHardwareTextureAndroid( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.renderToHardwareTextureAndroid : convertRawProp( context, diff --git a/packages/react-native/ReactCommon/react/renderer/core/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/core/CMakeLists.txt index 7e24d29f97bb..bb8043d541a8 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/core/CMakeLists.txt @@ -25,6 +25,7 @@ target_link_libraries(react_render_core logger react_config react_debug + react_featureflags react_render_debug react_render_graphics react_render_mapbuffer diff --git a/packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h b/packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h index 653f7700efa2..877d2068ad57 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h +++ b/packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -117,7 +118,7 @@ class ConcreteComponentDescriptor : public ComponentDescriptor { // Use the new-style iterator // Note that we just check if `Props` has this flag set, no matter // the type of ShadowNode; it acts as the single global flag. - if (CoreFeatures::enablePropIteratorSetter) { + if (ReactNativeFeatureFlags::enablePropIteratorSetter()) { rawProps.iterateOverValues([&](RawPropsPropNameHash hash, const char* propName, const RawValue& fn) { diff --git a/packages/react-native/ReactCommon/react/renderer/core/Props.cpp b/packages/react-native/ReactCommon/react/renderer/core/Props.cpp index df133e8078e5..3f19610cac9d 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/Props.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/Props.cpp @@ -8,8 +8,8 @@ #include "Props.h" #include +#include #include -#include namespace facebook::react { @@ -24,7 +24,7 @@ void Props::initialize( const PropsParserContext& context, const Props& sourceProps, const RawProps& rawProps) { - nativeId = CoreFeatures::enablePropIteratorSetter + nativeId = ReactNativeFeatureFlags::enablePropIteratorSetter() ? sourceProps.nativeId : convertRawProp(context, rawProps, "nativeID", sourceProps.nativeId, {}); #ifdef ANDROID diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp index cfa5c7319cf6..2ffa15cf212e 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp @@ -9,7 +9,6 @@ namespace facebook::react { -bool CoreFeatures::enablePropIteratorSetter = false; bool CoreFeatures::cacheLastTextMeasurement = false; bool CoreFeatures::enableGranularScrollViewStateUpdatesIOS = false; bool CoreFeatures::enableMountHooks = false; diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h index 9f0a3d630c3d..cdf7ecd84944 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h @@ -16,9 +16,6 @@ namespace facebook::react { */ class CoreFeatures { public: - // Specifies whether the iterator-style prop parsing is enabled. - static bool enablePropIteratorSetter; - // Yoga might measure multiple times the same Text with the same constraints // This flag enables a caching mechanism to avoid subsequents measurements // of the same Text with the same constrainst. diff --git a/packages/react-native/package.json b/packages/react-native/package.json index 86db951b093f..cdaf0dcb1a3b 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -90,8 +90,8 @@ ], "scripts": { "prepack": "cp ../../README.md .", - "featureflags-check": "node ./scripts/featureflags/update.js --verify-unchanged", - "featureflags-update": "node ./scripts/featureflags/update.js" + "featureflags-check": "node ./scripts/featureflags/index.js --verify-unchanged", + "featureflags-update": "node ./scripts/featureflags/index.js" }, "peerDependencies": { "react": "18.2.0" diff --git a/packages/react-native/scripts/featureflags/README.md b/packages/react-native/scripts/featureflags/README.md index 42e18adba8e7..7cb68fec0811 100644 --- a/packages/react-native/scripts/featureflags/README.md +++ b/packages/react-native/scripts/featureflags/README.md @@ -11,46 +11,43 @@ everywhere. ## Definition -The source of truth for the definition of the flags is the file `ReactNativeFeatureFlags.json` -in this directory. That JSON file should have the following structure: +The source of truth for the definition of the flags is the file +`ReactNativeFeatureFlags.config.js` in this directory. -```flow -type Config = { - common: FeatureFlagsList, - jsOnly: FeatureFlagsList, -}; - -type FeatureFlagsList = { - [flagName: string]: { - description: string, - defaultValue: boolean | number | string, - }, -}; -``` - -Example: -```json -{ - "common": { - "enableMicrotasks": { - "description": "Enable the use of microtasks in the JS runtime.", - "defaultValue": false +Example contents: +```javascript +module.exports = { + common: { + enableMicrotasks: { + description: 'Enable the use of microtasks in the JS runtime.', + defaultValue: false } }, - "jsOnly": { - "enableAccessToHostTreeInFabric": { - "description": "Enables access to the host tree in Fabric using DOM-compatible APIs.", - "defaultValue": false + jsOnly: { + enableAccessToHostTreeInFabric: { + description: 'Enables access to the host tree in Fabric using DOM-compatible APIs.', + defaultValue: false } } -} +}; ``` After any changes to this definitions, the code that provides access to them -must be regenerated executing the `update` script in this directory. +must be regenerated running `yarn featureflags-update` from the `react-native` +repository. ## Access +You can access the common feature flags from anywhere in your application using +the `ReactNativeFeatureFlags` interface (available in C++/Objective-C++, +Kotlin/Java and JavaScript). JS-only feature flags can only be accessed from +JavaScript. + +**Accessing feature flags should be considered fast for all use cases**. +Feature flags are cached at every layer, which prevents having to go through JNI +when accessing the values from Kotlin and through JSI when accessing the values +from JavaScript. + ### C++ / Objective-C ```c++ @@ -89,6 +86,15 @@ if (ReactNativeFeatureFlags.enableAccessToHostTreeInFabric()) { ## Customization +Feature flags provide the default values defined in the configuration unless +overrides are applied at the application level. Overrides for common feature +flags can only be defined in native, while overrides for JS-ony flags can only +be defined in JavaScript. + +Overrides must be applied before any of the available feature flags has been +accessed. This prevents having inconsistent behavior during the lifecycle of the +application. + ### C++/Objective-C ```c++ diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js new file mode 100644 index 000000000000..5156c996880d --- /dev/null +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -0,0 +1,102 @@ +/** + * 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. + * + * @flow strict + * @format + */ + +import type {FeatureFlagDefinitions} from './types'; + +const definitions: FeatureFlagDefinitions = { + common: { + // This is only used in unit tests for the feature flags system. + commonTestFlag: { + description: 'Common flag for testing. Do NOT modify.', + defaultValue: false, + }, + + useModernRuntimeScheduler: { + description: + 'When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread.', + defaultValue: false, + }, + enableMicrotasks: { + description: + 'Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).', + defaultValue: false, + }, + batchRenderingUpdatesInEventLoop: { + description: + 'When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.', + defaultValue: false, + }, + enableSpannableBuildingUnification: { + description: + 'Uses new, deduplicated logic for constructing Android Spannables from text fragments', + defaultValue: false, + }, + enableCustomDrawOrderFabric: { + description: + 'When enabled, Fabric will use customDrawOrder in ReactViewGroup (similar to old architecture).', + defaultValue: false, + }, + enableFixForClippedSubviewsCrash: { + description: + 'Attempt at fixing a crash related to subview clipping on Android. This is a kill switch for the fix', + defaultValue: false, + }, + enablePropIteratorSetter: { + description: + 'Specifies whether the iterator-style prop parsing is enabled.', + defaultValue: false, + }, + }, + + jsOnly: { + // This is only used in unit tests for the feature flags system. + jsOnlyTestFlag: { + description: 'JS-only flag for testing. Do NOT modify.', + defaultValue: false, + }, + + isLayoutAnimationEnabled: { + description: + 'Function used to enable / disabled Layout Animations in React Native.', + defaultValue: true, + }, + animatedShouldDebounceQueueFlush: { + description: + 'Enables an experimental flush-queue debouncing in Animated.js.', + defaultValue: false, + }, + animatedShouldUseSingleOp: { + description: + 'Enables an experimental mega-operation for Animated.js that replaces many calls to native with a single call into native, to reduce JSI/JNI traffic.', + defaultValue: false, + }, + enableAccessToHostTreeInFabric: { + description: + 'Enables access to the host tree in Fabric using DOM-compatible APIs.', + defaultValue: false, + }, + shouldUseAnimatedObjectForTransform: { + description: + 'Enables use of AnimatedObject for animating transform values.', + defaultValue: false, + }, + shouldUseSetNativePropsInFabric: { + description: 'Enables use of setNativeProps in JS driven animations.', + defaultValue: true, + }, + shouldUseRemoveClippedSubviewsAsDefaultOnIOS: { + description: + 'removeClippedSubviews prop will be used as the default in FlatList on iOS to match Android', + defaultValue: false, + }, + }, +}; + +export default definitions; diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json deleted file mode 100644 index 95a4df931b47..000000000000 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "common": { - "commonTestFlag": { - "description": "Common flag for testing. Do NOT modify.", - "defaultValue": false - }, - "useModernRuntimeScheduler": { - "description": "When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread.", - "defaultValue": false - }, - "enableMicrotasks": { - "description": "Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).", - "defaultValue": false - }, - "batchRenderingUpdatesInEventLoop": { - "description": "When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.", - "defaultValue": false - }, - "enableSpannableBuildingUnification": { - "description": "Uses new, deduplicated logic for constructing Android Spannables from text fragments", - "defaultValue": false - }, - "enableCustomDrawOrderFabric": { - "description": "When enabled, Fabric will use customDrawOrder in ReactViewGroup (similar to old architecture).", - "defaultValue": false - }, - "enableFixForClippedSubviewsCrash": { - "description": "Attempt at fixing a crash related to subview clipping on Android. This is a kill switch for the fix", - "defaultValue": false - } - }, - "jsOnly": { - "jsOnlyTestFlag": { - "description": "JS-only flag for testing. Do NOT modify.", - "defaultValue": false - }, - "isLayoutAnimationEnabled": { - "description": "Function used to enable / disabled Layout Animations in React Native.", - "defaultValue": true - }, - "animatedShouldDebounceQueueFlush": { - "description": "Enables an experimental flush-queue debouncing in Animated.js.", - "defaultValue": false - }, - "animatedShouldUseSingleOp": { - "description": "Enables an experimental mega-operation for Animated.js that replaces many calls to native with a single call into native, to reduce JSI/JNI traffic.", - "defaultValue": false - }, - "enableAccessToHostTreeInFabric": { - "description": "Enables access to the host tree in Fabric using DOM-compatible APIs.", - "defaultValue": false - }, - "shouldUseAnimatedObjectForTransform": { - "description": "Enables use of AnimatedObject for animating transform values.", - "defaultValue": false - }, - "shouldUseSetNativePropsInFabric": { - "description": "Enables use of setNativeProps in JS driven animations.", - "defaultValue": true - }, - "shouldUseRemoveClippedSubviewsAsDefaultOnIOS": { - "description": "removeClippedSubviews prop will be used as the default in FlatList on iOS to match Android", - "defaultValue": false - } - } -} diff --git a/packages/react-native/scripts/featureflags/generateAndroidModules.js b/packages/react-native/scripts/featureflags/generateAndroidModules.js index edf0ce966a2e..4631fbfa366d 100644 --- a/packages/react-native/scripts/featureflags/generateAndroidModules.js +++ b/packages/react-native/scripts/featureflags/generateAndroidModules.js @@ -4,65 +4,43 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {GeneratorConfig, GeneratorResult} from './types'; -const JReactNativeFeatureFlagsCxxInteropCPP = require('./templates/android/JReactNativeFeatureFlagsCxxInterop.cpp-template'); -const JReactNativeFeatureFlagsCxxInteropH = require('./templates/android/JReactNativeFeatureFlagsCxxInterop.h-template'); -const ReactNativeFeatureFlagsKt = require('./templates/android/ReactNativeFeatureFlags.kt-template'); -const ReactNativeFeatureFlagsCxxAccessorKt = require('./templates/android/ReactNativeFeatureFlagsCxxAccessor.kt-template'); -const ReactNativeFeatureFlagsCxxInteropKt = require('./templates/android/ReactNativeFeatureFlagsCxxInterop.kt-template'); -const ReactNativeFeatureFlagsDefaultsKt = require('./templates/android/ReactNativeFeatureFlagsDefaults.kt-template'); -const ReactNativeFeatureFlagsLocalAccessorKt = require('./templates/android/ReactNativeFeatureFlagsLocalAccessor.kt-template'); -const ReactNativeFeatureFlagsProviderKt = require('./templates/android/ReactNativeFeatureFlagsProvider.kt-template'); -const ReactNativeFeatureFlagsProviderHolderCPP = require('./templates/android/ReactNativeFeatureFlagsProviderHolder.cpp-template'); -const ReactNativeFeatureFlagsProviderHolderH = require('./templates/android/ReactNativeFeatureFlagsProviderHolder.h-template'); -const path = require('path'); +import JReactNativeFeatureFlagsCxxInteropCPP from './templates/android/JReactNativeFeatureFlagsCxxInterop.cpp-template'; +import JReactNativeFeatureFlagsCxxInteropH from './templates/android/JReactNativeFeatureFlagsCxxInterop.h-template'; +import ReactNativeFeatureFlagsKt from './templates/android/ReactNativeFeatureFlags.kt-template'; +import ReactNativeFeatureFlagsCxxAccessorKt from './templates/android/ReactNativeFeatureFlagsCxxAccessor.kt-template'; +import ReactNativeFeatureFlagsCxxInteropKt from './templates/android/ReactNativeFeatureFlagsCxxInterop.kt-template'; +import ReactNativeFeatureFlagsDefaultsKt from './templates/android/ReactNativeFeatureFlagsDefaults.kt-template'; +import ReactNativeFeatureFlagsLocalAccessorKt from './templates/android/ReactNativeFeatureFlagsLocalAccessor.kt-template'; +import ReactNativeFeatureFlagsProviderKt from './templates/android/ReactNativeFeatureFlagsProvider.kt-template'; +import path from 'path'; + +export default function generateAndroidModules( + generatorConfig: GeneratorConfig, +): GeneratorResult { + const {androidPath, androidJniPath, featureFlagDefinitions} = generatorConfig; -module.exports = function generateandroidModules( - generatorConfig, - featureFlagsConfig, -) { return { - [path.join(generatorConfig.androidPath, 'ReactNativeFeatureFlags.kt')]: - ReactNativeFeatureFlagsKt(featureFlagsConfig), - [path.join( - generatorConfig.androidPath, - 'ReactNativeFeatureFlagsCxxAccessor.kt', - )]: ReactNativeFeatureFlagsCxxAccessorKt(featureFlagsConfig), - [path.join( - generatorConfig.androidPath, - 'ReactNativeFeatureFlagsLocalAccessor.kt', - )]: ReactNativeFeatureFlagsLocalAccessorKt(featureFlagsConfig), - [path.join( - generatorConfig.androidPath, - 'ReactNativeFeatureFlagsCxxInterop.kt', - )]: ReactNativeFeatureFlagsCxxInteropKt(featureFlagsConfig), - [path.join( - generatorConfig.androidPath, - 'ReactNativeFeatureFlagsDefaults.kt', - )]: ReactNativeFeatureFlagsDefaultsKt(featureFlagsConfig), - [path.join( - generatorConfig.androidPath, - 'ReactNativeFeatureFlagsProvider.kt', - )]: ReactNativeFeatureFlagsProviderKt(featureFlagsConfig), - [path.join( - generatorConfig.androidJniPath, - 'ReactNativeFeatureFlagsProviderHolder.h', - )]: ReactNativeFeatureFlagsProviderHolderH(featureFlagsConfig), - [path.join( - generatorConfig.androidJniPath, - 'ReactNativeFeatureFlagsProviderHolder.cpp', - )]: ReactNativeFeatureFlagsProviderHolderCPP(featureFlagsConfig), - [path.join( - generatorConfig.androidJniPath, - 'JReactNativeFeatureFlagsCxxInterop.h', - )]: JReactNativeFeatureFlagsCxxInteropH(featureFlagsConfig), - [path.join( - generatorConfig.androidJniPath, - 'JReactNativeFeatureFlagsCxxInterop.cpp', - )]: JReactNativeFeatureFlagsCxxInteropCPP(featureFlagsConfig), + [path.join(androidPath, 'ReactNativeFeatureFlags.kt')]: + ReactNativeFeatureFlagsKt(featureFlagDefinitions), + [path.join(androidPath, 'ReactNativeFeatureFlagsCxxAccessor.kt')]: + ReactNativeFeatureFlagsCxxAccessorKt(featureFlagDefinitions), + [path.join(androidPath, 'ReactNativeFeatureFlagsLocalAccessor.kt')]: + ReactNativeFeatureFlagsLocalAccessorKt(featureFlagDefinitions), + [path.join(androidPath, 'ReactNativeFeatureFlagsCxxInterop.kt')]: + ReactNativeFeatureFlagsCxxInteropKt(featureFlagDefinitions), + [path.join(androidPath, 'ReactNativeFeatureFlagsDefaults.kt')]: + ReactNativeFeatureFlagsDefaultsKt(featureFlagDefinitions), + [path.join(androidPath, 'ReactNativeFeatureFlagsProvider.kt')]: + ReactNativeFeatureFlagsProviderKt(featureFlagDefinitions), + [path.join(androidJniPath, 'JReactNativeFeatureFlagsCxxInterop.h')]: + JReactNativeFeatureFlagsCxxInteropH(featureFlagDefinitions), + [path.join(androidJniPath, 'JReactNativeFeatureFlagsCxxInterop.cpp')]: + JReactNativeFeatureFlagsCxxInteropCPP(featureFlagDefinitions), }; -}; +} diff --git a/packages/react-native/scripts/featureflags/generateCommonCxxModules.js b/packages/react-native/scripts/featureflags/generateCommonCxxModules.js index 4c021fc1d644..7329bf8abbd0 100644 --- a/packages/react-native/scripts/featureflags/generateCommonCxxModules.js +++ b/packages/react-native/scripts/featureflags/generateCommonCxxModules.js @@ -4,43 +4,37 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {GeneratorConfig, GeneratorResult} from './types'; -const ReactNativeFeatureFlagsCPP = require('./templates/common-cxx/ReactNativeFeatureFlags.cpp-template'); -const ReactNativeFeatureFlagsH = require('./templates/common-cxx/ReactNativeFeatureFlags.h-template'); -const ReactNativeFeatureFlagsAccessorCPP = require('./templates/common-cxx/ReactNativeFeatureFlagsAccessor.cpp-template'); -const ReactNativeFeatureFlagsAccessorH = require('./templates/common-cxx/ReactNativeFeatureFlagsAccessor.h-template'); -const ReactNativeFeatureFlagsDefaultsH = require('./templates/common-cxx/ReactNativeFeatureFlagsDefaults.h-template'); -const ReactNativeFeatureFlagsProviderH = require('./templates/common-cxx/ReactNativeFeatureFlagsProvider.h-template'); -const path = require('path'); +import ReactNativeFeatureFlagsCPP from './templates/common-cxx/ReactNativeFeatureFlags.cpp-template'; +import ReactNativeFeatureFlagsH from './templates/common-cxx/ReactNativeFeatureFlags.h-template'; +import ReactNativeFeatureFlagsAccessorCPP from './templates/common-cxx/ReactNativeFeatureFlagsAccessor.cpp-template'; +import ReactNativeFeatureFlagsAccessorH from './templates/common-cxx/ReactNativeFeatureFlagsAccessor.h-template'; +import ReactNativeFeatureFlagsDefaultsH from './templates/common-cxx/ReactNativeFeatureFlagsDefaults.h-template'; +import ReactNativeFeatureFlagsProviderH from './templates/common-cxx/ReactNativeFeatureFlagsProvider.h-template'; +import path from 'path'; + +export default function generateCommonCxxModules( + generatorConfig: GeneratorConfig, +): GeneratorResult { + const {commonCxxPath, featureFlagDefinitions} = generatorConfig; -module.exports = function generateCommonCxxModules( - generatorConfig, - featureFlagsConfig, -) { return { - [path.join(generatorConfig.commonCxxPath, 'ReactNativeFeatureFlags.h')]: - ReactNativeFeatureFlagsH(featureFlagsConfig), - [path.join(generatorConfig.commonCxxPath, 'ReactNativeFeatureFlags.cpp')]: - ReactNativeFeatureFlagsCPP(featureFlagsConfig), - [path.join( - generatorConfig.commonCxxPath, - 'ReactNativeFeatureFlagsAccessor.h', - )]: ReactNativeFeatureFlagsAccessorH(featureFlagsConfig), - [path.join( - generatorConfig.commonCxxPath, - 'ReactNativeFeatureFlagsAccessor.cpp', - )]: ReactNativeFeatureFlagsAccessorCPP(featureFlagsConfig), - [path.join( - generatorConfig.commonCxxPath, - 'ReactNativeFeatureFlagsDefaults.h', - )]: ReactNativeFeatureFlagsDefaultsH(featureFlagsConfig), - [path.join( - generatorConfig.commonCxxPath, - 'ReactNativeFeatureFlagsProvider.h', - )]: ReactNativeFeatureFlagsProviderH(featureFlagsConfig), + [path.join(commonCxxPath, 'ReactNativeFeatureFlags.h')]: + ReactNativeFeatureFlagsH(featureFlagDefinitions), + [path.join(commonCxxPath, 'ReactNativeFeatureFlags.cpp')]: + ReactNativeFeatureFlagsCPP(featureFlagDefinitions), + [path.join(commonCxxPath, 'ReactNativeFeatureFlagsAccessor.h')]: + ReactNativeFeatureFlagsAccessorH(featureFlagDefinitions), + [path.join(commonCxxPath, 'ReactNativeFeatureFlagsAccessor.cpp')]: + ReactNativeFeatureFlagsAccessorCPP(featureFlagDefinitions), + [path.join(commonCxxPath, 'ReactNativeFeatureFlagsDefaults.h')]: + ReactNativeFeatureFlagsDefaultsH(featureFlagDefinitions), + [path.join(commonCxxPath, 'ReactNativeFeatureFlagsProvider.h')]: + ReactNativeFeatureFlagsProviderH(featureFlagDefinitions), }; -}; +} diff --git a/packages/react-native/scripts/featureflags/generateFiles.js b/packages/react-native/scripts/featureflags/generateFiles.js index 91a974354931..f03df2163e64 100644 --- a/packages/react-native/scripts/featureflags/generateFiles.js +++ b/packages/react-native/scripts/featureflags/generateFiles.js @@ -4,49 +4,37 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -const generateAndroidModules = require('./generateAndroidModules'); -const generateCommonCxxModules = require('./generateCommonCxxModules'); -const generateJavaScriptModules = require('./generateJavaScriptModules'); -const fs = require('fs'); +import type {GeneratorConfig, GeneratorOptions} from './types'; -module.exports = function generateFiles(generatorConfig, generatorOptions) { - const userDefinedFeatureFlagsConfig = JSON.parse( - fs.readFileSync(generatorConfig.configPath, 'utf8'), - ); - - const featureFlagsConfig = Object.assign( - {jsOnly: {}, common: {}}, - userDefinedFeatureFlagsConfig, - ); +import generateAndroidModules from './generateAndroidModules'; +import generateCommonCxxModules from './generateCommonCxxModules'; +import generateJavaScriptModules from './generateJavaScriptModules'; +import fs from 'fs'; +export default function generateFiles( + generatorConfig: GeneratorConfig, + generatorOptions: GeneratorOptions, +): void { fs.mkdirSync(generatorConfig.jsPath, {recursive: true}); fs.mkdirSync(generatorConfig.commonCxxPath, {recursive: true}); fs.mkdirSync(generatorConfig.commonNativeModuleCxxPath, {recursive: true}); fs.mkdirSync(generatorConfig.androidPath, {recursive: true}); fs.mkdirSync(generatorConfig.androidJniPath, {recursive: true}); - const jsModules = generateJavaScriptModules( - generatorConfig, - featureFlagsConfig, - ); + const jsModules = generateJavaScriptModules(generatorConfig); - const commonCxxModules = generateCommonCxxModules( - generatorConfig, - featureFlagsConfig, - ); + const commonCxxModules = generateCommonCxxModules(generatorConfig); - const androidModules = generateAndroidModules( - generatorConfig, - featureFlagsConfig, - ); + const androidModules = generateAndroidModules(generatorConfig); const generatedFiles = {...jsModules, ...commonCxxModules, ...androidModules}; if (generatorOptions.verifyUnchanged) { - const existingModules = {}; + const existingModules: {[string]: string} = {}; for (const moduleName of Object.keys(generatedFiles)) { const existingModule = fs.readFileSync(moduleName, 'utf8'); existingModules[moduleName] = existingModule; @@ -79,4 +67,4 @@ module.exports = function generateFiles(generatorConfig, generatorOptions) { for (const [modulePath, moduleContents] of Object.entries(generatedFiles)) { fs.writeFileSync(modulePath, moduleContents, 'utf8'); } -}; +} diff --git a/packages/react-native/scripts/featureflags/generateJavaScriptModules.js b/packages/react-native/scripts/featureflags/generateJavaScriptModules.js index 63b11b912eb0..4fc7d30e1553 100644 --- a/packages/react-native/scripts/featureflags/generateJavaScriptModules.js +++ b/packages/react-native/scripts/featureflags/generateJavaScriptModules.js @@ -4,33 +4,32 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {GeneratorConfig, GeneratorResult} from './types'; -const NativeReactNativeFeatureFlagsCPP = require('./templates/js/NativeReactNativeFeatureFlags.cpp-template'); -const NativeReactNativeFeatureFlagsH = require('./templates/js/NativeReactNativeFeatureFlags.h-template'); -const NativeReactNativeFeatureFlagsJS = require('./templates/js/NativeReactNativeFeatureFlags.js-template'); -const ReactNativeFeatureFlagsJS = require('./templates/js/ReactNativeFeatureFlags.js-template'); -const path = require('path'); +import NativeReactNativeFeatureFlagsCPP from './templates/js/NativeReactNativeFeatureFlags.cpp-template'; +import NativeReactNativeFeatureFlagsH from './templates/js/NativeReactNativeFeatureFlags.h-template'; +import NativeReactNativeFeatureFlagsJS from './templates/js/NativeReactNativeFeatureFlags.js-template'; +import ReactNativeFeatureFlagsJS from './templates/js/ReactNativeFeatureFlags.js-template'; +import path from 'path'; + +export default function generateCommonCxxModules( + generatorConfig: GeneratorConfig, +): GeneratorResult { + const {jsPath, commonNativeModuleCxxPath, featureFlagDefinitions} = + generatorConfig; -module.exports = function generateCommonCxxModules( - generatorConfig, - featureFlagsConfig, -) { return { - [path.join(generatorConfig.jsPath, 'ReactNativeFeatureFlags.js')]: - ReactNativeFeatureFlagsJS(featureFlagsConfig), - [path.join(generatorConfig.jsPath, 'NativeReactNativeFeatureFlags.js')]: - NativeReactNativeFeatureFlagsJS(featureFlagsConfig), - [path.join( - generatorConfig.commonNativeModuleCxxPath, - 'NativeReactNativeFeatureFlags.h', - )]: NativeReactNativeFeatureFlagsH(featureFlagsConfig), - [path.join( - generatorConfig.commonNativeModuleCxxPath, - 'NativeReactNativeFeatureFlags.cpp', - )]: NativeReactNativeFeatureFlagsCPP(featureFlagsConfig), + [path.join(jsPath, 'ReactNativeFeatureFlags.js')]: + ReactNativeFeatureFlagsJS(featureFlagDefinitions), + [path.join(jsPath, 'NativeReactNativeFeatureFlags.js')]: + NativeReactNativeFeatureFlagsJS(featureFlagDefinitions), + [path.join(commonNativeModuleCxxPath, 'NativeReactNativeFeatureFlags.h')]: + NativeReactNativeFeatureFlagsH(featureFlagDefinitions), + [path.join(commonNativeModuleCxxPath, 'NativeReactNativeFeatureFlags.cpp')]: + NativeReactNativeFeatureFlagsCPP(featureFlagDefinitions), }; -}; +} diff --git a/packages/react-native/scripts/featureflags/index.js b/packages/react-native/scripts/featureflags/index.js new file mode 100644 index 000000000000..38e991437f20 --- /dev/null +++ b/packages/react-native/scripts/featureflags/index.js @@ -0,0 +1,14 @@ +/** + * 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. + * + * @format + */ + +if (require.main === module) { + require('../../../../scripts/build/babel-register').registerForMonorepo(); + const update = require('./update').default; + update(process.argv.includes('--verify-unchanged')); +} diff --git a/packages/react-native/scripts/featureflags/templates/android/JReactNativeFeatureFlagsCxxInterop.cpp-template.js b/packages/react-native/scripts/featureflags/templates/android/JReactNativeFeatureFlagsCxxInterop.cpp-template.js index 35e95e17fbf2..223a0e272153 100644 --- a/packages/react-native/scripts/featureflags/templates/android/JReactNativeFeatureFlagsCxxInterop.cpp-template.js +++ b/packages/react-native/scripts/featureflags/templates/android/JReactNativeFeatureFlagsCxxInterop.cpp-template.js @@ -4,19 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { - DO_NOT_MODIFY_COMMENT, - getCxxTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT, getCxxTypeFromDefaultValue} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -29,11 +27,44 @@ ${DO_NOT_MODIFY_COMMENT} #include "JReactNativeFeatureFlagsCxxInterop.h" #include -#include namespace facebook::react { -${Object.entries(config.common) +static jni::alias_ref getReactNativeFeatureFlagsProviderJavaClass() { + static const auto jClass = facebook::jni::findClassStatic( + "com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider"); + return jClass; +} + +/** + * Implementation of ReactNativeFeatureFlagsProvider that wraps a + * ReactNativeFeatureFlagsProvider Java object. + */ +class ReactNativeFeatureFlagsProviderHolder + : public ReactNativeFeatureFlagsProvider { + public: + explicit ReactNativeFeatureFlagsProviderHolder( + jni::alias_ref javaProvider) + : javaProvider_(make_global(javaProvider)){}; + +${Object.entries(definitions.common) + .map( + ([flagName, flagConfig]) => + ` ${getCxxTypeFromDefaultValue( + flagConfig.defaultValue, + )} ${flagName}() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("${flagName}"); + return method(javaProvider_); + }`, + ) + .join('\n\n')} + + private: + jni::global_ref javaProvider_; +}; + +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => `${getCxxTypeFromDefaultValue( @@ -62,7 +93,7 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "override", JReactNativeFeatureFlagsCxxInterop::override), makeNativeMethod("dangerouslyReset", JReactNativeFeatureFlagsCxxInterop::dangerouslyReset), -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` makeNativeMethod( @@ -75,3 +106,4 @@ ${Object.entries(config.common) } // namespace facebook::react `); +} diff --git a/packages/react-native/scripts/featureflags/templates/android/JReactNativeFeatureFlagsCxxInterop.h-template.js b/packages/react-native/scripts/featureflags/templates/android/JReactNativeFeatureFlagsCxxInterop.h-template.js index 580e47fcaab3..72995b1f714a 100644 --- a/packages/react-native/scripts/featureflags/templates/android/JReactNativeFeatureFlagsCxxInterop.h-template.js +++ b/packages/react-native/scripts/featureflags/templates/android/JReactNativeFeatureFlagsCxxInterop.h-template.js @@ -4,19 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { - DO_NOT_MODIFY_COMMENT, - getCxxTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT, getCxxTypeFromDefaultValue} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -40,7 +38,7 @@ class JReactNativeFeatureFlagsCxxInterop constexpr static auto kJavaDescriptor = "Lcom/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop;"; -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` static ${getCxxTypeFromDefaultValue( @@ -62,3 +60,4 @@ ${Object.entries(config.common) } // namespace facebook::react `); +} diff --git a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlags.kt-template.js b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlags.kt-template.js index 148e6c364aff..520dc13456c0 100644 --- a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlags.kt-template.js +++ b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlags.kt-template.js @@ -4,16 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const {DO_NOT_MODIFY_COMMENT} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -35,7 +36,7 @@ object ReactNativeFeatureFlags { private var accessorProvider: () -> ReactNativeFeatureFlagsAccessor = { ReactNativeFeatureFlagsCxxAccessor() } private var accessor: ReactNativeFeatureFlagsAccessor = accessorProvider() -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` /** @@ -90,3 +91,4 @@ ${Object.entries(config.common) } } `); +} diff --git a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsCxxAccessor.kt-template.js b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsCxxAccessor.kt-template.js index a5fe55b8579d..9f63cbca9cc5 100644 --- a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsCxxAccessor.kt-template.js +++ b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsCxxAccessor.kt-template.js @@ -4,19 +4,20 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { +import { DO_NOT_MODIFY_COMMENT, getKotlinTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -30,7 +31,7 @@ ${DO_NOT_MODIFY_COMMENT} package com.facebook.react.internal.featureflags class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccessor { -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` private var ${flagName}Cache: ${getKotlinTypeFromDefaultValue( @@ -39,7 +40,7 @@ ${Object.entries(config.common) ) .join('\n')} -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` override fun ${flagName}(): Boolean { var cached = ${flagName}Cache @@ -58,3 +59,4 @@ ${Object.entries(config.common) override fun dangerouslyReset() = ReactNativeFeatureFlagsCxxInterop.dangerouslyReset() } `); +} diff --git a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsCxxInterop.kt-template.js b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsCxxInterop.kt-template.js index 813f010d2126..3007b06913bb 100644 --- a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsCxxInterop.kt-template.js +++ b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsCxxInterop.kt-template.js @@ -4,19 +4,20 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { +import { DO_NOT_MODIFY_COMMENT, getKotlinTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -38,7 +39,7 @@ object ReactNativeFeatureFlagsCxxInterop { SoLoader.loadLibrary("react_featureflagsjni") } -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` @DoNotStrip @JvmStatic external fun ${flagName}(): ${getKotlinTypeFromDefaultValue( @@ -52,3 +53,4 @@ ${Object.entries(config.common) @DoNotStrip @JvmStatic external fun dangerouslyReset() } `); +} diff --git a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsDefaults.kt-template.js b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsDefaults.kt-template.js index d20df80a87b5..9707a32cb3b8 100644 --- a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsDefaults.kt-template.js +++ b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsDefaults.kt-template.js @@ -4,19 +4,20 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { +import { DO_NOT_MODIFY_COMMENT, getKotlinTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -33,7 +34,7 @@ open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvider { // We could use JNI to get the defaults from C++, // but that is more expensive than just duplicating the defaults here. -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` override fun ${flagName}(): ${getKotlinTypeFromDefaultValue( @@ -43,3 +44,4 @@ ${Object.entries(config.common) .join('\n\n')} } `); +} diff --git a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsLocalAccessor.kt-template.js b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsLocalAccessor.kt-template.js index 3271ac929315..8c87853ca003 100644 --- a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsLocalAccessor.kt-template.js +++ b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsLocalAccessor.kt-template.js @@ -4,19 +4,20 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { +import { DO_NOT_MODIFY_COMMENT, getKotlinTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -34,7 +35,7 @@ class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAccessor { private val accessedFeatureFlags = mutableSetOf() -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` private var ${flagName}Cache: ${getKotlinTypeFromDefaultValue( @@ -43,7 +44,7 @@ ${Object.entries(config.common) ) .join('\n')} -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` override fun ${flagName}(): Boolean { var cached = ${flagName}Cache @@ -72,3 +73,4 @@ ${Object.entries(config.common) } } `); +} diff --git a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsProvider.kt-template.js b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsProvider.kt-template.js index 57eea78a02e2..558f86a5af3b 100644 --- a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsProvider.kt-template.js +++ b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsProvider.kt-template.js @@ -4,19 +4,20 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { +import { DO_NOT_MODIFY_COMMENT, getKotlinTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -33,7 +34,7 @@ import com.facebook.proguard.annotations.DoNotStrip @DoNotStrip interface ReactNativeFeatureFlagsProvider { -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` @DoNotStrip fun ${flagName}(): ${getKotlinTypeFromDefaultValue( @@ -43,3 +44,4 @@ ${Object.entries(config.common) .join('\n\n')} } `); +} diff --git a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsProviderHolder.cpp-template.js b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsProviderHolder.cpp-template.js deleted file mode 100644 index 4bd3b3da43ce..000000000000 --- a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsProviderHolder.cpp-template.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * 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. - * - * @format - */ - -'use strict'; - -const { - DO_NOT_MODIFY_COMMENT, - getCxxTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); - -module.exports = config => - signedsource.signFile(`/* - * 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. - * - * ${signedsource.getSigningToken()} - */ - -${DO_NOT_MODIFY_COMMENT} - -#include "ReactNativeFeatureFlagsProviderHolder.h" - -namespace facebook::react { - -static jni::alias_ref getJClass() { - static const auto jClass = facebook::jni::findClassStatic( - "com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider"); - return jClass; -} - -${Object.entries(config.common) - .map( - ([flagName, flagConfig]) => - `${getCxxTypeFromDefaultValue( - flagConfig.defaultValue, - )} ReactNativeFeatureFlagsProviderHolder::${flagName}() { - static const auto method = - getJClass()->getMethod("${flagName}"); - return method(javaProvider_); -}`, - ) - .join('\n\n')} - -} // namespace facebook::react -`); diff --git a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsProviderHolder.h-template.js b/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsProviderHolder.h-template.js deleted file mode 100644 index 60e3272c9036..000000000000 --- a/packages/react-native/scripts/featureflags/templates/android/ReactNativeFeatureFlagsProviderHolder.h-template.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * 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. - * - * @format - */ - -'use strict'; - -const { - DO_NOT_MODIFY_COMMENT, - getCxxTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); - -module.exports = config => - signedsource.signFile(`/* - * 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. - * - * ${signedsource.getSigningToken()} - */ - -${DO_NOT_MODIFY_COMMENT} - -#pragma once - -#include -#include - -namespace facebook::react { - -/** - * Implementation of ReactNativeFeatureFlagsProvider that wraps a - * ReactNativeFeatureFlagsProvider Java object. - */ -class ReactNativeFeatureFlagsProviderHolder - : public ReactNativeFeatureFlagsProvider { - public: - explicit ReactNativeFeatureFlagsProviderHolder( - jni::alias_ref javaProvider) - : javaProvider_(make_global(javaProvider)){}; - -${Object.entries(config.common) - .map( - ([flagName, flagConfig]) => - ` ${getCxxTypeFromDefaultValue( - flagConfig.defaultValue, - )} ${flagName}() override;`, - ) - .join('\n')} - - private: - jni::global_ref javaProvider_; -}; - -} // namespace facebook::react -`); diff --git a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlags.cpp-template.js b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlags.cpp-template.js index 3bd2d55eddc9..bef6fbb8c20e 100644 --- a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlags.cpp-template.js +++ b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlags.cpp-template.js @@ -4,19 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { - DO_NOT_MODIFY_COMMENT, - getCxxTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT, getCxxTypeFromDefaultValue} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -31,7 +29,7 @@ ${DO_NOT_MODIFY_COMMENT} namespace facebook::react { -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => `${getCxxTypeFromDefaultValue( @@ -62,3 +60,4 @@ ReactNativeFeatureFlagsAccessor& ReactNativeFeatureFlags::getAccessor( } // namespace facebook::react `); +} diff --git a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlags.h-template.js b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlags.h-template.js index 829f61822a42..5e6e896560e6 100644 --- a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlags.h-template.js +++ b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlags.h-template.js @@ -4,19 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { - DO_NOT_MODIFY_COMMENT, - getCxxTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT, getCxxTypeFromDefaultValue} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -38,11 +36,12 @@ namespace facebook::react { /** * This class provides access to internal React Native feature flags. * - * All the methods are thread-safe if you handle \`override\` correctly. + * All the methods are thread-safe (as long as the methods in the overridden + * provider are). */ class ReactNativeFeatureFlags { public: -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` /** @@ -94,3 +93,4 @@ ${Object.entries(config.common) } // namespace facebook::react `); +} diff --git a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsAccessor.cpp-template.js b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsAccessor.cpp-template.js index 0c83a6b54604..26b9df54910e 100644 --- a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsAccessor.cpp-template.js +++ b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsAccessor.cpp-template.js @@ -4,19 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { - DO_NOT_MODIFY_COMMENT, - getCxxTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT, getCxxTypeFromDefaultValue} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -28,60 +26,81 @@ module.exports = config => ${DO_NOT_MODIFY_COMMENT} #include -#include #include #include +#include #include "ReactNativeFeatureFlags.h" namespace facebook::react { ReactNativeFeatureFlagsAccessor::ReactNativeFeatureFlagsAccessor() - : currentProvider_(std::make_unique()) {} + : currentProvider_(std::make_unique()), + wasOverridden_(false) {} -${Object.entries(config.common) +${Object.entries(definitions.common) .map( - ([flagName, flagConfig]) => + ([flagName, flagConfig], flagPosition) => `${getCxxTypeFromDefaultValue( flagConfig.defaultValue, )} ReactNativeFeatureFlagsAccessor::${flagName}() { - if (!${flagName}_.has_value()) { - // Mark the flag as accessed. - static const char* flagName = "${flagName}"; - if (std::find( - accessedFeatureFlags_.begin(), - accessedFeatureFlags_.end(), - flagName) == accessedFeatureFlags_.end()) { - accessedFeatureFlags_.push_back(flagName); - } + auto flagValue = ${flagName}_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(${flagPosition}, "${flagName}"); - ${flagName}_.emplace(currentProvider_->${flagName}()); + flagValue = currentProvider_->${flagName}(); + ${flagName}_ = flagValue; } - return ${flagName}_.value(); + return flagValue.value(); }`, ) .join('\n\n')} void ReactNativeFeatureFlagsAccessor::override( std::unique_ptr provider) { - if (!accessedFeatureFlags_.empty()) { - std::ostringstream featureFlagListBuilder; - for (const auto& featureFlagName : accessedFeatureFlags_) { + if (wasOverridden_) { + throw std::runtime_error( + "Feature flags cannot be overridden more than once"); + } + + ensureFlagsNotAccessed(); + wasOverridden_ = true; + currentProvider_ = std::move(provider); +} + +void ReactNativeFeatureFlagsAccessor::markFlagAsAccessed( + int position, + const char* flagName) { + accessedFeatureFlags_[position] = flagName; +} + +void ReactNativeFeatureFlagsAccessor::ensureFlagsNotAccessed() { + std::ostringstream featureFlagListBuilder; + for (const auto& featureFlagName : accessedFeatureFlags_) { + if (featureFlagName != nullptr) { featureFlagListBuilder << featureFlagName << ", "; } - std::string accessedFeatureFlagNames = featureFlagListBuilder.str(); - if (!accessedFeatureFlagNames.empty()) { - accessedFeatureFlagNames = accessedFeatureFlagNames.substr( - 0, accessedFeatureFlagNames.size() - 2); - } + } + std::string accessedFeatureFlagNames = featureFlagListBuilder.str(); + if (!accessedFeatureFlagNames.empty()) { + accessedFeatureFlagNames = + accessedFeatureFlagNames.substr(0, accessedFeatureFlagNames.size() - 2); + } + + if (!accessedFeatureFlagNames.empty()) { throw std::runtime_error( "Feature flags were accessed before being overridden: " + accessedFeatureFlagNames); } - - currentProvider_ = std::move(provider); } } // namespace facebook::react `); +} diff --git a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsAccessor.h-template.js b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsAccessor.h-template.js index e2cd096586da..07ad24bc0fa9 100644 --- a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsAccessor.h-template.js +++ b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsAccessor.h-template.js @@ -4,19 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { - DO_NOT_MODIFY_COMMENT, - getCxxTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT, getCxxTypeFromDefaultValue} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -30,9 +28,10 @@ ${DO_NOT_MODIFY_COMMENT} #pragma once #include +#include +#include #include #include -#include namespace facebook::react { @@ -40,7 +39,7 @@ class ReactNativeFeatureFlagsAccessor { public: ReactNativeFeatureFlagsAccessor(); -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` ${getCxxTypeFromDefaultValue(flagConfig.defaultValue)} ${flagName}();`, @@ -50,18 +49,26 @@ ${Object.entries(config.common) void override(std::unique_ptr provider); private: + void markFlagAsAccessed(int position, const char* flagName); + void ensureFlagsNotAccessed(); + std::unique_ptr currentProvider_; - std::vector accessedFeatureFlags_; + bool wasOverridden_; + + std::array, ${ + Object.keys(definitions.common).length + }> accessedFeatureFlags_; -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => - ` std::optional<${getCxxTypeFromDefaultValue( + ` std::atomic ${flagName}_;`, + )}>> ${flagName}_;`, ) .join('\n')} }; } // namespace facebook::react `); +} diff --git a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsDefaults.h-template.js b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsDefaults.h-template.js index eec42229555d..e70768d2eec8 100644 --- a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsDefaults.h-template.js +++ b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsDefaults.h-template.js @@ -4,19 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { - DO_NOT_MODIFY_COMMENT, - getCxxTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT, getCxxTypeFromDefaultValue} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -37,7 +35,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { public: ReactNativeFeatureFlagsDefaults() = default; -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` ${getCxxTypeFromDefaultValue( @@ -51,3 +49,4 @@ ${Object.entries(config.common) } // namespace facebook::react `); +} diff --git a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsProvider.h-template.js b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsProvider.h-template.js index 1f01590b07b3..68689f927faa 100644 --- a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsProvider.h-template.js +++ b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlagsProvider.h-template.js @@ -4,19 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { - DO_NOT_MODIFY_COMMENT, - getCxxTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT, getCxxTypeFromDefaultValue} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -35,7 +33,7 @@ class ReactNativeFeatureFlagsProvider { public: virtual ~ReactNativeFeatureFlagsProvider() = default; -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` virtual ${getCxxTypeFromDefaultValue( @@ -47,3 +45,4 @@ ${Object.entries(config.common) } // namespace facebook::react `); +} diff --git a/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.cpp-template.js b/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.cpp-template.js index 9844c5a5b4a7..13a28a72cecb 100644 --- a/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.cpp-template.js +++ b/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.cpp-template.js @@ -4,19 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { - DO_NOT_MODIFY_COMMENT, - getCxxTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT, getCxxTypeFromDefaultValue} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -45,7 +43,7 @@ NativeReactNativeFeatureFlags::NativeReactNativeFeatureFlags( std::shared_ptr jsInvoker) : NativeReactNativeFeatureFlagsCxxSpec(std::move(jsInvoker)) {} -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => `${getCxxTypeFromDefaultValue( @@ -59,3 +57,4 @@ ${Object.entries(config.common) } // namespace facebook::react `); +} diff --git a/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.h-template.js b/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.h-template.js index 0bf7a9b28dc1..492639ed9d3d 100644 --- a/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.h-template.js +++ b/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.h-template.js @@ -4,19 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const { - DO_NOT_MODIFY_COMMENT, - getCxxTypeFromDefaultValue, -} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT, getCxxTypeFromDefaultValue} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/* +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -40,7 +38,7 @@ class NativeReactNativeFeatureFlags public: NativeReactNativeFeatureFlags(std::shared_ptr jsInvoker); -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` ${getCxxTypeFromDefaultValue( @@ -52,3 +50,4 @@ ${Object.entries(config.common) } // namespace facebook::react `); +} diff --git a/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.js-template.js b/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.js-template.js index 3bd1b05daac1..9c9e557879db 100644 --- a/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.js-template.js +++ b/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.js-template.js @@ -4,16 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const {DO_NOT_MODIFY_COMMENT} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/** +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -30,7 +31,7 @@ import type {TurboModule} from '../../../Libraries/TurboModule/RCTExport'; import * as TurboModuleRegistry from '../../../Libraries/TurboModule/TurboModuleRegistry'; export interface Spec extends TurboModule { -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => ` +${flagName}?: () => ${typeof flagConfig.defaultValue};`, @@ -44,3 +45,4 @@ const NativeReactNativeFeatureFlags: ?Spec = TurboModuleRegistry.get( export default NativeReactNativeFeatureFlags; `); +} diff --git a/packages/react-native/scripts/featureflags/templates/js/ReactNativeFeatureFlags.js-template.js b/packages/react-native/scripts/featureflags/templates/js/ReactNativeFeatureFlags.js-template.js index 3d6251d3e7cd..90872bd5e58a 100644 --- a/packages/react-native/scripts/featureflags/templates/js/ReactNativeFeatureFlags.js-template.js +++ b/packages/react-native/scripts/featureflags/templates/js/ReactNativeFeatureFlags.js-template.js @@ -4,16 +4,17 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -'use strict'; +import type {FeatureFlagDefinitions} from '../../types'; -const {DO_NOT_MODIFY_COMMENT} = require('../../utils'); -const signedsource = require('signedsource'); +import {DO_NOT_MODIFY_COMMENT} from '../../utils'; +import signedsource from 'signedsource'; -module.exports = config => - signedsource.signFile(`/** +export default function (definitions: FeatureFlagDefinitions): string { + return signedsource.signFile(`/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the @@ -33,7 +34,7 @@ import { } from './ReactNativeFeatureFlagsBase'; export type ReactNativeFeatureFlagsJsOnly = { -${Object.entries(config.jsOnly) +${Object.entries(definitions.jsOnly) .map( ([flagName, flagConfig]) => ` ${flagName}: Getter<${typeof flagConfig.defaultValue}>,`, @@ -45,7 +46,7 @@ export type ReactNativeFeatureFlagsJsOnlyOverrides = Partial ` ${flagName}: Getter<${typeof flagConfig.defaultValue}>,`, @@ -53,7 +54,7 @@ ${Object.entries(config.common) .join('\n')} } -${Object.entries(config.jsOnly) +${Object.entries(definitions.jsOnly) .map( ([flagName, flagConfig]) => `/** @@ -65,7 +66,7 @@ export const ${flagName}: Getter<${typeof flagConfig.defaultValue}> = createJava ) .join('\n\n')} -${Object.entries(config.common) +${Object.entries(definitions.common) .map( ([flagName, flagConfig]) => `/** @@ -83,3 +84,4 @@ export const ${flagName}: Getter<${typeof flagConfig.defaultValue}> = createNati */ export const override = setOverrides; `); +} diff --git a/packages/react-native/scripts/featureflags/types.js b/packages/react-native/scripts/featureflags/types.js new file mode 100644 index 000000000000..688a081d5b9a --- /dev/null +++ b/packages/react-native/scripts/featureflags/types.js @@ -0,0 +1,40 @@ +/** + * 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. + * + * @flow strict + * @format + */ + +export type FeatureFlagValue = boolean | number | string; + +export type FeatureFlagDefinitions = { + common: FeatureFlagList, + jsOnly: FeatureFlagList, +}; + +type FeatureFlagList = { + [flagName: string]: { + description: string, + defaultValue: FeatureFlagValue, + }, +}; + +export type GeneratorConfig = { + featureFlagDefinitions: FeatureFlagDefinitions, + jsPath: string, + commonCxxPath: string, + commonNativeModuleCxxPath: string, + androidPath: string, + androidJniPath: string, +}; + +export type GeneratorOptions = { + verifyUnchanged: boolean, +}; + +export type GeneratorResult = { + [path: string]: string /* content */, +}; diff --git a/packages/react-native/scripts/featureflags/update.js b/packages/react-native/scripts/featureflags/update.js index dff625d3e8d2..46ce9493f145 100644 --- a/packages/react-native/scripts/featureflags/update.js +++ b/packages/react-native/scripts/featureflags/update.js @@ -4,18 +4,20 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -const generateFiles = require('./generateFiles'); -const path = require('path'); +import generateFiles from './generateFiles'; +import featureFlagDefinitions from './ReactNativeFeatureFlags.config'; +import path from 'path'; const REACT_NATIVE_PACKAGE_ROOT = path.join(__dirname, '..', '..'); -function update() { +export default function update(verifyUnchanged: boolean): void { generateFiles( { - configPath: path.join(__dirname, 'ReactNativeFeatureFlags.json'), + featureFlagDefinitions, jsPath: path.join( REACT_NATIVE_PACKAGE_ROOT, 'src', @@ -58,11 +60,7 @@ function update() { ), }, { - verifyUnchanged: process.argv.includes('--verify-unchanged'), + verifyUnchanged, }, ); } - -if (require.main === module) { - update(); -} diff --git a/packages/react-native/scripts/featureflags/utils.js b/packages/react-native/scripts/featureflags/utils.js index a551227a6cb2..1634f3c73ff8 100644 --- a/packages/react-native/scripts/featureflags/utils.js +++ b/packages/react-native/scripts/featureflags/utils.js @@ -4,47 +4,48 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format */ -module.exports = { - getCxxTypeFromDefaultValue: defaultValue => { - switch (typeof defaultValue) { - case 'boolean': - return 'bool'; - case 'number': - return 'int'; - case 'string': - return 'std::string'; - default: - throw new Error( - `Unsupported default value type: ${typeof defaultValue}`, - ); - } - }, +import type {FeatureFlagValue} from './types'; - getKotlinTypeFromDefaultValue: defaultValue => { - switch (typeof defaultValue) { - case 'boolean': - return 'Boolean'; - case 'number': - return 'Int'; - case 'string': - return 'String'; - default: - throw new Error( - `Unsupported default value type: ${typeof defaultValue}`, - ); - } - }, +export function getCxxTypeFromDefaultValue( + defaultValue: FeatureFlagValue, +): string { + switch (typeof defaultValue) { + case 'boolean': + return 'bool'; + case 'number': + return 'int'; + case 'string': + return 'std::string'; + default: + throw new Error(`Unsupported default value type: ${typeof defaultValue}`); + } +} - DO_NOT_MODIFY_COMMENT: `/** +export function getKotlinTypeFromDefaultValue( + defaultValue: FeatureFlagValue, +): string { + switch (typeof defaultValue) { + case 'boolean': + return 'Boolean'; + case 'number': + return 'Int'; + case 'string': + return 'String'; + default: + throw new Error(`Unsupported default value type: ${typeof defaultValue}`); + } +} + +export const DO_NOT_MODIFY_COMMENT = `/** * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update - */`, -}; + */`; diff --git a/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js index 22050a3f31be..5de7dd082157 100644 --- a/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2ca87dc970592f66d83f4799c4047c9b>> + * @generated SignedSource<<70e1fc59e5a458192195ceb083119eaa>> * @flow strict-local */ @@ -12,7 +12,7 @@ * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -30,6 +30,7 @@ export interface Spec extends TurboModule { +enableSpannableBuildingUnification?: () => boolean; +enableCustomDrawOrderFabric?: () => boolean; +enableFixForClippedSubviewsCrash?: () => boolean; + +enablePropIteratorSetter?: () => boolean; } const NativeReactNativeFeatureFlags: ?Spec = TurboModuleRegistry.get( diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index dc612641d200..6909a110c9cc 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> * @flow strict-local */ @@ -12,7 +12,7 @@ * IMPORTANT: Do NOT modify this file directly. * * To change the definition of the flags, edit - * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json. + * packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js. * * To regenerate this code, run the following script from the repo root: * yarn featureflags-update @@ -47,6 +47,7 @@ export type ReactNativeFeatureFlags = { enableSpannableBuildingUnification: Getter, enableCustomDrawOrderFabric: Getter, enableFixForClippedSubviewsCrash: Getter, + enablePropIteratorSetter: Getter, } /** @@ -117,6 +118,10 @@ export const enableCustomDrawOrderFabric: Getter = createNativeFlagGett * Attempt at fixing a crash related to subview clipping on Android. This is a kill switch for the fix */ export const enableFixForClippedSubviewsCrash: Getter = createNativeFlagGetter('enableFixForClippedSubviewsCrash', false); +/** + * Specifies whether the iterator-style prop parsing is enabled. + */ +export const enablePropIteratorSetter: Getter = createNativeFlagGetter('enablePropIteratorSetter', false); /** * Overrides the feature flags with the provided methods. diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlagsBase.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlagsBase.js index a6fdee5d289f..a0d7be5da25c 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlagsBase.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlagsBase.js @@ -16,7 +16,7 @@ import type { import NativeReactNativeFeatureFlags from './NativeReactNativeFeatureFlags'; const accessedFeatureFlags: Set = new Set(); -const overrides: ReactNativeFeatureFlagsJsOnlyOverrides = {}; +let overrides: ?ReactNativeFeatureFlagsJsOnlyOverrides; export type Getter = () => T; @@ -44,7 +44,7 @@ export function createJavaScriptFlagGetter< ): Getter> { return createGetter( configName, - () => overrides[configName]?.(), + () => overrides?.[configName]?.(), defaultValue, ); } @@ -69,6 +69,10 @@ export function getOverrides(): ?ReactNativeFeatureFlagsJsOnlyOverrides { export function setOverrides( newOverrides: ReactNativeFeatureFlagsJsOnlyOverrides, ): void { + if (overrides != null) { + throw new Error('Feature flags cannot be overridden more than once'); + } + if (accessedFeatureFlags.size > 0) { const accessedFeatureFlagsStr = Array.from(accessedFeatureFlags).join(', '); throw new Error( @@ -76,5 +80,5 @@ export function setOverrides( ); } - Object.assign(overrides, newOverrides); + overrides = newOverrides; } diff --git a/packages/react-native/src/private/featureflags/__tests__/ReactNativeFeatureFlags-test.js b/packages/react-native/src/private/featureflags/__tests__/ReactNativeFeatureFlags-test.js index fef002a2bc51..13264b6974bc 100644 --- a/packages/react-native/src/private/featureflags/__tests__/ReactNativeFeatureFlags-test.js +++ b/packages/react-native/src/private/featureflags/__tests__/ReactNativeFeatureFlags-test.js @@ -75,4 +75,18 @@ describe('ReactNativeFeatureFlags', () => { 'Feature flags were accessed before being overridden: commonTestFlag', ); }); + + it('should throw an error when trying to set overrides twice', () => { + const ReactNativeFeatureFlags = require('../ReactNativeFeatureFlags'); + + ReactNativeFeatureFlags.override({ + jsOnlyTestFlag: () => true, + }); + + expect(() => + ReactNativeFeatureFlags.override({ + jsOnlyTestFlag: () => false, + }), + ).toThrow('Feature flags cannot be overridden more than once'); + }); });