Skip to content

Commit

Permalink
Migrate NativeArray classes to Kotlin (facebook#44569)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: facebook#44569

# Changelog:
[Internal] -

This converts the vertical of NativeArray/ReadableNativeArray/WritableNativeArray classes to Kotlin.

NOTE: the `getArray`, `getMap` and `getString` being annotated as `NonNull` in the Java code is a scam - there is no guarantee that native side will send non-null to the Java side, and in practice, indeed, in certain cases it doesn't. So I opted to make it nullable instead - this way it's at least explicit and is not a ticking bomb hidden to explode behind the false sense of security.

Differential Revision: https://internalfb.com/D57327835
  • Loading branch information
rshest authored and facebook-github-bot committed May 15, 2024
1 parent ad4c39e commit 62964ca
Show file tree
Hide file tree
Showing 15 changed files with 200 additions and 290 deletions.
4 changes: 2 additions & 2 deletions packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line number Diff line number Diff line change
Expand Up @@ -1390,7 +1390,7 @@ public class com/facebook/react/bridge/ReadableNativeArray : com/facebook/react/
public fun getDouble (I)D
public fun getDynamic (I)Lcom/facebook/react/bridge/Dynamic;
public fun getInt (I)I
public static fun getJNIPassCounter ()I
public static final fun getJNIPassCounter ()I
public fun getLong (I)J
public synthetic fun getMap (I)Lcom/facebook/react/bridge/ReadableMap;
public fun getMap (I)Lcom/facebook/react/bridge/ReadableNativeMap;
Expand Down Expand Up @@ -1527,7 +1527,7 @@ public abstract interface class com/facebook/react/bridge/WritableMap : com/face
public abstract fun putString (Ljava/lang/String;Ljava/lang/String;)V
}

public class com/facebook/react/bridge/WritableNativeArray : com/facebook/react/bridge/ReadableNativeArray, com/facebook/react/bridge/WritableArray {
public final class com/facebook/react/bridge/WritableNativeArray : com/facebook/react/bridge/ReadableNativeArray, com/facebook/react/bridge/WritableArray {
public fun <init> ()V
public fun pushArray (Lcom/facebook/react/bridge/ReadableArray;)V
public fun pushBoolean (Z)V
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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.bridge

import com.facebook.jni.HybridData
import com.facebook.proguard.annotations.DoNotStrip

/** Base class for an array whose members are stored in native code (C++). */
@DoNotStrip
public abstract class NativeArray
protected constructor(@field:DoNotStrip private val mHybridData: HybridData?) :
NativeArrayInterface {
external override fun toString(): String

private companion object {
init {
ReactBridge.staticInit()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import java.util.ArrayList
* to Kotlin.
*/
public interface ReadableArray {
public fun getArray(index: Int): ReadableArray
public fun getArray(index: Int): ReadableArray?

public fun getBoolean(index: Int): Boolean

Expand All @@ -26,7 +26,7 @@ public interface ReadableArray {

public fun getLong(index: Int): Long

public fun getMap(index: Int): ReadableMap
public fun getMap(index: Int): ReadableMap?

public fun getString(index: Int): String

Expand All @@ -36,5 +36,5 @@ public interface ReadableArray {

public fun size(): Int

public fun toArrayList(): ArrayList<Any>
public fun toArrayList(): ArrayList<Any?>
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* 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.bridge

import com.facebook.jni.HybridData
import com.facebook.proguard.annotations.DoNotStripAny
import java.util.Arrays

/**
* Implementation of a NativeArray that allows read-only access to its members. This will generally
* be constructed and filled in native code so you shouldn't construct one yourself.
*/
@DoNotStripAny
public open class ReadableNativeArray protected constructor(hybridData: HybridData?) :
NativeArray(hybridData), ReadableArray {

private val localArray: Array<Any?> by
lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
jniPassCounter++
importArray()
}

private external fun importArray(): Array<Any?>

private val localTypeArray: Array<ReadableType> by
lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
jniPassCounter++
importTypeArray()
}

private external fun importTypeArray(): Array<ReadableType>

override fun size(): Int = localArray.size

override fun isNull(index: Int): Boolean = localArray[index] == null

override fun getBoolean(index: Int): Boolean = localArray[index] as Boolean

override fun getDouble(index: Int): Double = localArray[index] as Double

override fun getInt(index: Int): Int = getDouble(index).toInt()

override fun getLong(index: Int): Long = localArray[index] as Long

override fun getString(index: Int): String = localArray[index] as String

override fun getArray(index: Int): ReadableNativeArray? =
localArray[index] as? ReadableNativeArray

override fun getMap(index: Int): ReadableNativeMap? = localArray[index] as? ReadableNativeMap

override fun getType(index: Int): ReadableType = localTypeArray[index]

override fun getDynamic(index: Int): Dynamic = DynamicFromArray.create(this, index)

override fun hashCode(): Int = localArray.hashCode()

override fun equals(other: Any?): Boolean =
if (other !is ReadableNativeArray) false else Arrays.deepEquals(localArray, other.localArray)

override fun toArrayList(): ArrayList<Any?> {
val arrayList = ArrayList<Any?>()
for (i in 0 until size()) {
when (getType(i)) {
ReadableType.Null -> arrayList.add(null)
ReadableType.Boolean -> arrayList.add(getBoolean(i))
ReadableType.Number -> arrayList.add(getDouble(i))
ReadableType.String -> arrayList.add(getString(i))
ReadableType.Map -> arrayList.add(getMap(i)?.toHashMap())
ReadableType.Array -> arrayList.add(getArray(i)?.toArrayList())
else -> throw IllegalArgumentException("Could not convert object at index: $i.")
}
}
return arrayList
}

private companion object {
init {
ReactBridge.staticInit()
}

private var jniPassCounter: Int = 0

@JvmStatic public fun getJNIPassCounter(): Int = jniPassCounter
}
}
Loading

0 comments on commit 62964ca

Please sign in to comment.