From a0f016ecad4d577300e95de41be4e297b9c02c4f Mon Sep 17 00:00:00 2001 From: poonamjain96 Date: Tue, 15 Apr 2025 04:23:18 -0700 Subject: [PATCH] Migrated file ReactStylesDiffMap to kotlin (#50616) Summary: This PR aims to migrate ReactStylesDiffMap from Java to kotlin as part of https://github.com/facebook/react-native/issues/50513 ## Changelog: [ANDROID][CHANGED]Migrate ReactStylesDiffMap to Kotlin For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests Pull Request resolved: https://github.com/facebook/react-native/pull/50616 Test Plan: Tested on RN tester with both new and old arch Reviewed By: alanleedev Differential Revision: D72962016 Pulled By: cortinico fbshipit-source-id: 4de63ab78cd692822c01b5964209000c9d41f595 --- .../ReactAndroid/api/ReactAndroid.api | 24 ++--- .../NativeViewHierarchyOptimizer.java | 4 +- .../react/uimanager/ReactStylesDiffMap.java | 99 ------------------- .../react/uimanager/ReactStylesDiffMap.kt | 63 ++++++++++++ .../facebook/react/uimanager/ViewManager.java | 2 +- .../uimanager/ViewManagerPropertyUpdater.kt | 6 +- 6 files changed, 81 insertions(+), 117 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMap.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMap.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index f3f9d5ce64a..195aa60f04a 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -4320,19 +4320,19 @@ public final class com/facebook/react/uimanager/ReactStage$Companion { public static final field SURFACE_DID_STOP I } -public class com/facebook/react/uimanager/ReactStylesDiffMap { +public final class com/facebook/react/uimanager/ReactStylesDiffMap { public fun (Lcom/facebook/react/bridge/ReadableMap;)V - public fun getArray (Ljava/lang/String;)Lcom/facebook/react/bridge/ReadableArray; - public fun getBoolean (Ljava/lang/String;Z)Z - public fun getDouble (Ljava/lang/String;D)D - public fun getDynamic (Ljava/lang/String;)Lcom/facebook/react/bridge/Dynamic; - public fun getFloat (Ljava/lang/String;F)F - public fun getInt (Ljava/lang/String;I)I - public fun getMap (Ljava/lang/String;)Lcom/facebook/react/bridge/ReadableMap; - public fun getString (Ljava/lang/String;)Ljava/lang/String; - public fun hasKey (Ljava/lang/String;)Z - public fun isNull (Ljava/lang/String;)Z - public fun toMap ()Ljava/util/Map; + public final fun getArray (Ljava/lang/String;)Lcom/facebook/react/bridge/ReadableArray; + public final fun getBoolean (Ljava/lang/String;Z)Z + public final fun getDouble (Ljava/lang/String;D)D + public final fun getDynamic (Ljava/lang/String;)Lcom/facebook/react/bridge/Dynamic; + public final fun getFloat (Ljava/lang/String;F)F + public final fun getInt (Ljava/lang/String;I)I + public final fun getMap (Ljava/lang/String;)Lcom/facebook/react/bridge/ReadableMap; + public final fun getString (Ljava/lang/String;)Ljava/lang/String; + public final fun hasKey (Ljava/lang/String;)Z + public final fun isNull (Ljava/lang/String;)Z + public final fun toMap ()Ljava/util/Map; public fun toString ()Ljava/lang/String; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java index 033cc9ba094..459bc1e29a2 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java @@ -462,9 +462,9 @@ public class NativeViewHierarchyOptimizer { return false; } - ReadableMapKeySetIterator keyIterator = props.mBackingMap.keySetIterator(); + ReadableMapKeySetIterator keyIterator = props.backingMap.keySetIterator(); while (keyIterator.hasNextKey()) { - if (!ViewProps.isLayoutOnly(props.mBackingMap, keyIterator.nextKey())) { + if (!ViewProps.isLayoutOnly(props.backingMap, keyIterator.nextKey())) { return false; } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMap.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMap.java deleted file mode 100644 index 7f7982597e8..00000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMap.java +++ /dev/null @@ -1,99 +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. - */ - -package com.facebook.react.uimanager; - -import android.view.View; -import androidx.annotation.Nullable; -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.react.bridge.Dynamic; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import java.util.Map; - -/** - * Wrapper for {@link ReadableMap} which should be used for styles property map. It extends some of - * the accessor methods of {@link ReadableMap} by adding a default value property such that caller - * is enforced to provide a default value for a style property. - * - *

Instances of this class are used to update {@link View} or {@link CSSNode} style properties. - * Since properties are generated by React framework based on what has been updated each value in - * this map should either be interpreted as a new value set for a style property or as a "reset this - * property to default" command in case when value is null (this is a way React communicates change - * in which the style key that was previously present in a map has been removed). - * - *

NOTE: Accessor method with default value will throw an exception when the key is not present - * in the map. Style applicator logic should verify whether the key exists in the map using {@link - * #hasKey} before fetching the value. The motivation behind this is that in case when the updated - * style diff map doesn't contain a certain style key it means that the corresponding view property - * shouldn't be updated (whereas in all other cases it should be updated to the new value or the - * property should be reset). - */ -@Nullsafe(Nullsafe.Mode.LOCAL) -public class ReactStylesDiffMap { - - /* package */ final ReadableMap mBackingMap; - - public ReactStylesDiffMap(ReadableMap props) { - mBackingMap = props; - } - - public Map toMap() { - return mBackingMap.toHashMap(); - } - - public boolean hasKey(String name) { - return mBackingMap.hasKey(name); - } - - public boolean isNull(String name) { - return mBackingMap.isNull(name); - } - - public boolean getBoolean(String name, boolean restoreNullToDefaultValue) { - return mBackingMap.isNull(name) ? restoreNullToDefaultValue : mBackingMap.getBoolean(name); - } - - public double getDouble(String name, double restoreNullToDefaultValue) { - return mBackingMap.isNull(name) ? restoreNullToDefaultValue : mBackingMap.getDouble(name); - } - - public float getFloat(String name, float restoreNullToDefaultValue) { - return mBackingMap.isNull(name) - ? restoreNullToDefaultValue - : (float) mBackingMap.getDouble(name); - } - - public int getInt(String name, int restoreNullToDefaultValue) { - return mBackingMap.isNull(name) ? restoreNullToDefaultValue : mBackingMap.getInt(name); - } - - @Nullable - public String getString(String name) { - return mBackingMap.getString(name); - } - - @Nullable - public ReadableArray getArray(String key) { - return mBackingMap.getArray(key); - } - - @Nullable - public ReadableMap getMap(String key) { - return mBackingMap.getMap(key); - } - - @Nullable - public Dynamic getDynamic(String key) { - return mBackingMap.getDynamic(key); - } - - @Override - public String toString() { - return "{ " + getClass().getSimpleName() + ": " + mBackingMap.toString() + " }"; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMap.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMap.kt new file mode 100644 index 00000000000..52a8a4c3cfd --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMap.kt @@ -0,0 +1,63 @@ +/* + * 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. + */ + +package com.facebook.react.uimanager + +import com.facebook.react.bridge.Dynamic +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.bridge.ReadableMap + +/** + * Wrapper for [ReadableMap] which should be used for styles property map. It extends some of the + * accessor methods of [ReadableMap] by adding a default value property such that caller is enforced + * to provide a default value for a style property. + * + * Instances of this class are used to update [View] or [CSSNode] style properties. Since properties + * are generated by React framework based on what has been updated each value in this map should + * either be interpreted as a new value set for a style property or as a "reset this property to + * default" command in case when value is null (this is a way React communicates change in which the + * style key that was previously present in a map has been removed). + * + * NOTE: Accessor method with default value will throw an exception when the key is not present in + * the map. Style applicator logic should verify whether the key exists in the map using [.hasKey] + * before fetching the value. The motivation behind this is that in case when the updated style diff + * map doesn't contain a certain style key it means that the corresponding view property shouldn't + * be updated (whereas in all other cases it should be updated to the new value or the property + * should be reset). + */ +public class ReactStylesDiffMap(props: ReadableMap) { + + @JvmField internal val backingMap: ReadableMap = props + + public fun toMap(): Map = backingMap.toHashMap() + + public fun hasKey(name: String): Boolean = backingMap.hasKey(name) + + public fun isNull(name: String): Boolean = backingMap.isNull(name) + + public fun getBoolean(name: String, default: Boolean): Boolean = + if (backingMap.isNull(name)) default else backingMap.getBoolean(name) + + public fun getDouble(name: String, default: Double): Double = + if (backingMap.isNull(name)) default else backingMap.getDouble(name) + + public fun getFloat(name: String, default: Float): Float = + if (backingMap.isNull(name)) default else backingMap.getDouble(name).toFloat() + + public fun getInt(name: String, default: Int): Int = + if (backingMap.isNull(name)) default else backingMap.getInt(name) + + public fun getString(name: String): String? = backingMap.getString(name) + + public fun getArray(name: String): ReadableArray? = backingMap.getArray(name) + + public fun getMap(name: String): ReadableMap? = backingMap.getMap(name) + + public fun getDynamic(name: String): Dynamic? = backingMap.getDynamic(name) + + override fun toString(): String = "{ ${javaClass.simpleName}: $backingMap }" +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java index c9adbf9801a..cd4dc2392f5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java @@ -96,7 +96,7 @@ public abstract class ViewManager */ public void updateProperties(@NonNull T viewToUpdate, ReactStylesDiffMap props) { ViewManagerDelegate delegate = getOrCreateViewManagerDelegate(); - Iterator> iterator = props.mBackingMap.getEntryIterator(); + Iterator> iterator = props.backingMap.getEntryIterator(); while (iterator.hasNext()) { Map.Entry entry = iterator.next(); delegate.setProperty(viewToUpdate, entry.getKey(), entry.getValue()); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagerPropertyUpdater.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagerPropertyUpdater.kt index 356fabe4b57..48d812314e5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagerPropertyUpdater.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagerPropertyUpdater.kt @@ -48,7 +48,7 @@ public object ViewManagerPropertyUpdater { view: V, props: ReactStylesDiffMap ) { - val iterator = props.mBackingMap.entryIterator + val iterator = props.backingMap.entryIterator while (iterator.hasNext()) { val entry = iterator.next() delegate.setProperty(view, entry.key, entry.value) @@ -63,7 +63,7 @@ public object ViewManagerPropertyUpdater { props: ReactStylesDiffMap ) { val setter = findManagerSetter(manager.javaClass) - val iterator = props.mBackingMap.entryIterator + val iterator = props.backingMap.entryIterator while (iterator.hasNext()) { val entry = iterator.next() setter.setProperty(manager, view, entry.key, entry.value) @@ -74,7 +74,7 @@ public object ViewManagerPropertyUpdater { @JvmStatic public fun > updateProps(node: T, props: ReactStylesDiffMap) { val setter = findNodeSetter(node.javaClass) - val iterator = props.mBackingMap.entryIterator + val iterator = props.backingMap.entryIterator while (iterator.hasNext()) { val entry = iterator.next() setter.setProperty(node, entry.key, entry.value)