Skip to content

Commit ae8f533

Browse files
artus9033uffoltzl
authored and
uffoltzl
committed
refactor: migrate DynamicFromMap to Kotlin (facebook#50597)
Summary: This PR introduces a rewrite of `DynamicFromMap.java` to Kotlin as requested in facebook#50513. ## Changelog: [ANDROID] [CHANGED] - Migrated `DynamicFromMap.java` to Kotlin Pull Request resolved: facebook#50597 Test Plan: 1. Implement unit tests for `DynamicFromMap.kt` - `DynamicFromMapTests.kt` 2. Ensure the tests pass: `./gradlew test` 3. Run the RN tester app on new & on old architectures Reviewed By: javache, rshest Differential Revision: D72853616 Pulled By: cortinico fbshipit-source-id: 855acdc7fa7810ab9f223b0be7778c028a646de5
1 parent fcd81c2 commit ae8f533

File tree

3 files changed

+144
-119
lines changed

3 files changed

+144
-119
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/DynamicFromMap.java

-119
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.bridge
9+
10+
import androidx.core.util.Pools.SimplePool
11+
12+
/** Implementation of Dynamic wrapping a ReadableMap. */
13+
internal class DynamicFromMap
14+
// This is a pools object. Hide the constructor.
15+
private constructor() : Dynamic {
16+
private var map: ReadableMap? = null
17+
private var name: String? = null
18+
19+
override fun recycle() {
20+
map = null
21+
name = null
22+
pool.get()?.release(this)
23+
}
24+
25+
override val isNull: Boolean
26+
get() {
27+
return accessMapSafely { map, name -> map.isNull(name) }
28+
}
29+
30+
override fun asBoolean(): Boolean = accessMapSafely { map, name -> map.getBoolean(name) }
31+
32+
override fun asDouble(): Double = accessMapSafely { map, name -> map.getDouble(name) }
33+
34+
override fun asInt(): Int = accessMapSafely { map, name -> map.getInt(name) }
35+
36+
override fun asString(): String? = accessMapSafely { map, name -> map.getString(name) }
37+
38+
override fun asArray(): ReadableArray? = accessMapSafely { map, name -> map.getArray(name) }
39+
40+
override fun asMap(): ReadableMap? = accessMapSafely { map, name -> map.getMap(name) }
41+
42+
override val type: ReadableType
43+
get() {
44+
return accessMapSafely { map, name -> map.getType(name) }
45+
}
46+
47+
/**
48+
* Asserts that both map and name are non-null and invokes the lambda with
49+
*
50+
* @param executor the callback to be invoked with non-null-asserted prop values
51+
* @return value returned by the executor
52+
*/
53+
private fun <T> accessMapSafely(executor: (map: ReadableMap, name: String) -> T): T {
54+
val name = checkNotNull(name) { DYNAMIC_VALUE_RECYCLED_FAILURE_MESSAGE }
55+
val map = checkNotNull(map) { DYNAMIC_VALUE_RECYCLED_FAILURE_MESSAGE }
56+
57+
return executor(map, name)
58+
}
59+
60+
companion object {
61+
private val pool: ThreadLocal<SimplePool<DynamicFromMap>> =
62+
object : ThreadLocal<SimplePool<DynamicFromMap>>() {
63+
override fun initialValue(): SimplePool<DynamicFromMap> {
64+
return SimplePool(10)
65+
}
66+
}
67+
68+
private const val DYNAMIC_VALUE_RECYCLED_FAILURE_MESSAGE =
69+
"This dynamic value has been recycled"
70+
71+
fun create(map: ReadableMap, name: String): DynamicFromMap {
72+
val dynamic = pool.get()?.acquire() ?: DynamicFromMap()
73+
74+
return dynamic.apply {
75+
this.map = map
76+
this.name = name
77+
}
78+
}
79+
}
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.bridge
9+
10+
import org.assertj.core.api.Assertions.assertThat
11+
import org.assertj.core.api.Assertions.assertThatThrownBy
12+
import org.junit.Test
13+
14+
/** Tests for [DynamicFromMap] */
15+
class DynamicFromMapTest {
16+
@Test
17+
fun testGetDynamic() {
18+
assertThat(getDynamicFromMap("int").asInt()).isEqualTo(1)
19+
assertThat(getDynamicFromMap("double").asDouble()).isEqualTo(2.0)
20+
assertThat(getDynamicFromMap("string").asString()).isEqualTo("str")
21+
assertThat(getDynamicFromMap("boolean").asBoolean()).isEqualTo(false)
22+
assertThat(getDynamicFromMap("array").asArray()).isEqualTo(testSource.getArray("array"))
23+
assertThat(getDynamicFromMap("map").asMap()).isEqualTo(testSource.getMap("map"))
24+
assertThat(getDynamicFromMap("null").isNull).isEqualTo(true)
25+
assertThat(getDynamicFromMap("int").type).isEqualTo(ReadableType.Number)
26+
}
27+
28+
@Test
29+
fun testGetFromRecycledDynamic() {
30+
assertThatThrownBy { getRecycledDynamicFromMap("int").asInt() }
31+
assertThatThrownBy { getRecycledDynamicFromMap("double").asDouble() }
32+
assertThatThrownBy { getRecycledDynamicFromMap("string").asString() }
33+
assertThatThrownBy { getRecycledDynamicFromMap("boolean").asMap() }
34+
assertThatThrownBy { getRecycledDynamicFromMap("array").asArray() }
35+
assertThatThrownBy { getRecycledDynamicFromMap("map").asBoolean() }
36+
assertThatThrownBy { getRecycledDynamicFromMap("null").isNull }
37+
assertThatThrownBy { getRecycledDynamicFromMap("anything").type }
38+
}
39+
40+
private fun getDynamicFromMap(key: String): Dynamic = DynamicFromMap.create(testSource, key)
41+
42+
private fun getRecycledDynamicFromMap(key: String): Dynamic =
43+
getDynamicFromMap(key).apply { recycle() }
44+
45+
companion object {
46+
private val testSource =
47+
JavaOnlyMap.of(
48+
"boolean",
49+
false,
50+
"array",
51+
JavaOnlyArray.of(),
52+
"map",
53+
JavaOnlyMap.of(),
54+
"null",
55+
null,
56+
"int",
57+
1,
58+
"double",
59+
2.0,
60+
"string",
61+
"str",
62+
)
63+
}
64+
}

0 commit comments

Comments
 (0)