Files
react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeArray.java
T
Dulmandakh b640b6faf7 nullable annotations to ReadableMap, WritableMap, ReadableArray, Writable. (#23329)
Summary:
Kotlin is getting traction and more developers write RN native modules in it. This PR adds nullable annotations to help with Kotlin null inference and improve developer experience. Also it'll help checking code quality using lint.

I skimmed through JavaOnlyMap.java, JavaOnlyArray.java, ReadableNativeArray.java, ReadableNativeMap.java, WritableNativeArray.java and WritableNativeMap.java to infer nullability.

This is breaking change to Kotlin code.

[Android] [Changed] - Add nullable annotations to ReadableMap, WritableMap, ReadableArray, Writable.
Pull Request resolved: https://github.com/facebook/react-native/pull/23329

Differential Revision: D14002571

Pulled By: cpojer

fbshipit-source-id: 899d8b3b0a5dad43e8300e6c4ea4208cca0f01a9
2019-02-08 04:16:24 -08:00

206 lines
5.7 KiB
Java

/**
* Copyright (c) Facebook, Inc. and its 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.infer.annotation.Assertions;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.config.ReactFeatureFlags;
import java.util.ArrayList;
import java.util.Arrays;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* 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.
*/
@DoNotStrip
public class ReadableNativeArray extends NativeArray implements ReadableArray {
static {
ReactBridge.staticInit();
}
protected ReadableNativeArray(HybridData hybridData) {
super(hybridData);
}
//WriteOnce but not in the constructor fields
private @Nullable Object[] mLocalArray;
private @Nullable ReadableType[] mLocalTypeArray;
private static int jniPassCounter = 0;
public static void setUseNativeAccessor(boolean useNativeAccessor) {
ReactFeatureFlags.useArrayNativeAccessor = useNativeAccessor;
}
public static int getJNIPassCounter() {
return jniPassCounter;
}
private Object[] getLocalArray() {
// Fast, non blocking check for the common case
if (mLocalArray != null) {
return mLocalArray;
}
synchronized (this) {
// Make sure no concurrent call already updated
if (mLocalArray == null) {
jniPassCounter++;
mLocalArray = Assertions.assertNotNull(importArray());
}
}
return mLocalArray;
}
private native Object[] importArray();
private ReadableType[] getLocalTypeArray() {
// Fast, non-blocking check for the common case
if (mLocalTypeArray != null) {
return mLocalTypeArray;
}
synchronized (this) {
// Make sure no concurrent call already updated
if (mLocalTypeArray == null) {
jniPassCounter++;
Object[] tempArray = Assertions.assertNotNull(importTypeArray());
mLocalTypeArray = Arrays.copyOf(tempArray, tempArray.length, ReadableType[].class);
}
}
return mLocalTypeArray;
}
private native Object[] importTypeArray();
@Override
public int size() {
if (ReactFeatureFlags.useArrayNativeAccessor) {
jniPassCounter++;
return sizeNative();
}
return getLocalArray().length;
}
private native int sizeNative();
@Override
public boolean isNull(int index) {
if (ReactFeatureFlags.useArrayNativeAccessor) {
jniPassCounter++;
return isNullNative(index);
}
return getLocalArray()[index] == null;
}
private native boolean isNullNative(int index);
@Override
public boolean getBoolean(int index) {
if (ReactFeatureFlags.useArrayNativeAccessor) {
jniPassCounter++;
return getBooleanNative(index);
}
return ((Boolean) getLocalArray()[index]).booleanValue();
}
private native boolean getBooleanNative(int index);
@Override
public double getDouble(int index) {
if (ReactFeatureFlags.useArrayNativeAccessor) {
jniPassCounter++;
return getDoubleNative(index);
}
return ((Double) getLocalArray()[index]).doubleValue();
}
private native double getDoubleNative(int index);
@Override
public int getInt(int index) {
if (ReactFeatureFlags.useArrayNativeAccessor) {
jniPassCounter++;
return getIntNative(index);
}
return ((Double) getLocalArray()[index]).intValue();
}
private native int getIntNative(int index);
@Override
public @Nullable String getString(int index) {
if (ReactFeatureFlags.useArrayNativeAccessor) {
jniPassCounter++;
return getStringNative(index);
}
return (String) getLocalArray()[index];
}
private native String getStringNative(int index);
@Override
public @Nullable ReadableNativeArray getArray(int index) {
if (ReactFeatureFlags.useArrayNativeAccessor) {
jniPassCounter++;
return getArrayNative(index);
}
return (ReadableNativeArray) getLocalArray()[index];
}
private native ReadableNativeArray getArrayNative(int index);
@Override
public @Nullable ReadableNativeMap getMap(int index) {
if (ReactFeatureFlags.useArrayNativeAccessor) {
jniPassCounter++;
return getMapNative(index);
}
return (ReadableNativeMap) getLocalArray()[index];
}
private native ReadableNativeMap getMapNative(int index);
@Override
public @Nonnull ReadableType getType(int index) {
if (ReactFeatureFlags.useArrayNativeAccessor) {
jniPassCounter++;
return getTypeNative(index);
}
return getLocalTypeArray()[index];
}
private native ReadableType getTypeNative(int index);
@Override
public @Nonnull Dynamic getDynamic(int index) {
return DynamicFromArray.create(this, index);
}
@Override
public @Nonnull ArrayList<Object> toArrayList() {
ArrayList<Object> arrayList = new ArrayList<>();
for (int i = 0; i < this.size(); i++) {
switch (getType(i)) {
case Null:
arrayList.add(null);
break;
case Boolean:
arrayList.add(getBoolean(i));
break;
case Number:
arrayList.add(getDouble(i));
break;
case String:
arrayList.add(getString(i));
break;
case Map:
arrayList.add(getMap(i).toHashMap());
break;
case Array:
arrayList.add(getArray(i).toArrayList());
break;
default:
throw new IllegalArgumentException("Could not convert object at index: " + i + ".");
}
}
return arrayList;
}
}