mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Migrate PromiseImpl to Kotlin (#51241)
Summary: Migrate com.facebook.react.bridge.PromiseImpl to Kotlin. ## Changelog: [INTERNAL] - Migrate com.facebook.react.bridge.PromiseImpl to Kotlin Pull Request resolved: https://github.com/facebook/react-native/pull/51241 Test Plan: ```bash yarn test-android yarn android ``` Reviewed By: rshest Differential Revision: D74567102 Pulled By: cortinico fbshipit-source-id: 1a7a36a88c0499e5bc35dc37d276219aaf823c90
This commit is contained in:
committed by
Facebook GitHub Bot
parent
a12d9f9d33
commit
25abb0acdf
@@ -1032,7 +1032,8 @@ public abstract interface class com/facebook/react/bridge/Promise {
|
||||
public abstract fun resolve (Ljava/lang/Object;)V
|
||||
}
|
||||
|
||||
public class com/facebook/react/bridge/PromiseImpl : com/facebook/react/bridge/Promise {
|
||||
public final class com/facebook/react/bridge/PromiseImpl : com/facebook/react/bridge/Promise {
|
||||
public static final field Companion Lcom/facebook/react/bridge/PromiseImpl$Companion;
|
||||
public fun <init> (Lcom/facebook/react/bridge/Callback;Lcom/facebook/react/bridge/Callback;)V
|
||||
public fun reject (Ljava/lang/String;)V
|
||||
public fun reject (Ljava/lang/String;Lcom/facebook/react/bridge/WritableMap;)V
|
||||
@@ -1047,6 +1048,9 @@ public class com/facebook/react/bridge/PromiseImpl : com/facebook/react/bridge/P
|
||||
public fun resolve (Ljava/lang/Object;)V
|
||||
}
|
||||
|
||||
public final class com/facebook/react/bridge/PromiseImpl$Companion {
|
||||
}
|
||||
|
||||
public abstract class com/facebook/react/bridge/ReactApplicationContext : com/facebook/react/bridge/ReactContext {
|
||||
public fun <init> (Landroid/content/Context;)V
|
||||
}
|
||||
|
||||
-257
@@ -1,257 +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.bridge;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.infer.annotation.Nullsafe;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
|
||||
/*
|
||||
* Implementation of {@link Promise} that represents a JavaScript Promise which can be passed to the
|
||||
* native module as a method parameter.
|
||||
*
|
||||
* Methods annotated with {@link ReactMethod} that use a {@link Promise} as the last parameter
|
||||
* will be marked as "promise" and will return a promise when invoked from JavaScript.
|
||||
*/
|
||||
@Nullsafe(Nullsafe.Mode.LOCAL)
|
||||
@DoNotStrip
|
||||
public class PromiseImpl implements Promise {
|
||||
// Number of stack frames to parse and return to mReject.invoke
|
||||
// for ERROR_MAP_KEY_NATIVE_STACK
|
||||
private static final int ERROR_STACK_FRAME_LIMIT = 50;
|
||||
|
||||
private static final String ERROR_DEFAULT_CODE = "EUNSPECIFIED";
|
||||
private static final String ERROR_DEFAULT_MESSAGE = "Error not specified.";
|
||||
|
||||
// Keys for mReject's WritableMap
|
||||
private static final String ERROR_MAP_KEY_CODE = "code";
|
||||
private static final String ERROR_MAP_KEY_MESSAGE = "message";
|
||||
private static final String ERROR_MAP_KEY_NAME = "name";
|
||||
private static final String ERROR_MAP_KEY_USER_INFO = "userInfo";
|
||||
private static final String ERROR_MAP_KEY_NATIVE_STACK = "nativeStackAndroid";
|
||||
|
||||
// Keys for ERROR_MAP_KEY_NATIVE_STACK's StackFrame maps
|
||||
private static final String STACK_FRAME_KEY_CLASS = "class";
|
||||
private static final String STACK_FRAME_KEY_FILE = "file";
|
||||
private static final String STACK_FRAME_KEY_LINE_NUMBER = "lineNumber";
|
||||
private static final String STACK_FRAME_KEY_METHOD_NAME = "methodName";
|
||||
|
||||
private @Nullable Callback mResolve;
|
||||
private @Nullable Callback mReject;
|
||||
|
||||
@DoNotStrip
|
||||
public PromiseImpl(@Nullable Callback resolve, @Nullable Callback reject) {
|
||||
mResolve = resolve;
|
||||
mReject = reject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Successfully resolve the Promise with an optional value.
|
||||
*
|
||||
* @param value Object
|
||||
*/
|
||||
@Override
|
||||
public void resolve(@Nullable Object value) {
|
||||
if (mResolve != null) {
|
||||
mResolve.invoke(value);
|
||||
mResolve = null;
|
||||
mReject = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an error without an exception using a custom code and error message.
|
||||
*
|
||||
* @param code String
|
||||
* @param message String
|
||||
*/
|
||||
@Override
|
||||
public void reject(String code, @Nullable String message) {
|
||||
reject(code, message, /*Throwable*/ null, /*WritableMap*/ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an exception with a custom code.
|
||||
*
|
||||
* @param code String
|
||||
* @param throwable Throwable
|
||||
*/
|
||||
@Override
|
||||
public void reject(String code, @Nullable Throwable throwable) {
|
||||
reject(code, /*Message*/ null, throwable, /*WritableMap*/ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an exception with a custom code and error message.
|
||||
*
|
||||
* @param code String
|
||||
* @param message String
|
||||
* @param throwable Throwable
|
||||
*/
|
||||
@Override
|
||||
public void reject(String code, @Nullable String message, @Nullable Throwable throwable) {
|
||||
reject(code, message, throwable, /*WritableMap*/ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an exception, with default error code. Useful in catch-all scenarios where it's unclear
|
||||
* why the error occurred.
|
||||
*
|
||||
* @param throwable Throwable
|
||||
*/
|
||||
@Override
|
||||
public void reject(Throwable throwable) {
|
||||
reject(/*Code*/ null, /*Message*/ null, throwable, /*WritableMap*/ null);
|
||||
}
|
||||
|
||||
/* ---------------------------
|
||||
* With userInfo WritableMap
|
||||
* --------------------------- */
|
||||
|
||||
/**
|
||||
* Report an exception, with default error code, with userInfo. Useful in catch-all scenarios
|
||||
* where it's unclear why the error occurred.
|
||||
*
|
||||
* @param throwable Throwable
|
||||
* @param userInfo WritableMap
|
||||
*/
|
||||
@Override
|
||||
public void reject(Throwable throwable, WritableMap userInfo) {
|
||||
reject(/*Code*/ null, /*Message*/ null, throwable, userInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject with a code and userInfo WritableMap.
|
||||
*
|
||||
* @param code String
|
||||
* @param userInfo WritableMap
|
||||
*/
|
||||
@Override
|
||||
public void reject(String code, WritableMap userInfo) {
|
||||
reject(code, /*Message*/ null, /*Throwable*/ null, userInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an exception with a custom code and userInfo.
|
||||
*
|
||||
* @param code String
|
||||
* @param throwable Throwable
|
||||
* @param userInfo WritableMap
|
||||
*/
|
||||
@Override
|
||||
public void reject(String code, @Nullable Throwable throwable, WritableMap userInfo) {
|
||||
reject(code, /*Message*/ null, throwable, userInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an error with a custom code, error message and userInfo, an error not caused by an
|
||||
* exception.
|
||||
*
|
||||
* @param code String
|
||||
* @param message String
|
||||
* @param userInfo WritableMap
|
||||
*/
|
||||
@Override
|
||||
public void reject(String code, @Nullable String message, WritableMap userInfo) {
|
||||
reject(code, message, /*Throwable*/ null, userInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an exception with a custom code, error message and userInfo.
|
||||
*
|
||||
* @param code String
|
||||
* @param message String
|
||||
* @param throwable Throwable
|
||||
* @param userInfo WritableMap
|
||||
*/
|
||||
@Override
|
||||
public void reject(
|
||||
@Nullable String code,
|
||||
@Nullable String message,
|
||||
@Nullable Throwable throwable,
|
||||
@Nullable WritableMap userInfo) {
|
||||
if (mReject == null) {
|
||||
mResolve = null;
|
||||
return;
|
||||
}
|
||||
|
||||
WritableNativeMap errorInfo = new WritableNativeMap();
|
||||
|
||||
if (code == null) {
|
||||
errorInfo.putString(ERROR_MAP_KEY_CODE, ERROR_DEFAULT_CODE);
|
||||
} else {
|
||||
errorInfo.putString(ERROR_MAP_KEY_CODE, code);
|
||||
}
|
||||
|
||||
// Use the custom message if provided otherwise use the throwable message.
|
||||
if (message != null) {
|
||||
errorInfo.putString(ERROR_MAP_KEY_MESSAGE, message);
|
||||
} else if (throwable != null) {
|
||||
String throwableMessage = throwable.getMessage();
|
||||
// Fallback to the trowable name, so we record some useful information
|
||||
if (throwableMessage == null || throwableMessage.isEmpty()) {
|
||||
throwableMessage = throwable.getClass().getCanonicalName();
|
||||
}
|
||||
errorInfo.putString(ERROR_MAP_KEY_MESSAGE, throwableMessage);
|
||||
} else {
|
||||
// The JavaScript side expects a map with at least an error message.
|
||||
// /Libraries/BatchedBridge/NativeModules.js -> createErrorFromErrorData
|
||||
// TYPE: (errorData: { message: string })
|
||||
errorInfo.putString(ERROR_MAP_KEY_MESSAGE, ERROR_DEFAULT_MESSAGE);
|
||||
}
|
||||
|
||||
// For consistency with iOS ensure userInfo key exists, even if we null it.
|
||||
// iOS: /React/Base/RCTUtils.m -> RCTJSErrorFromCodeMessageAndNSError
|
||||
if (userInfo != null) {
|
||||
errorInfo.putMap(ERROR_MAP_KEY_USER_INFO, userInfo);
|
||||
} else {
|
||||
errorInfo.putNull(ERROR_MAP_KEY_USER_INFO);
|
||||
}
|
||||
|
||||
// Attach a nativeStackAndroid array if a throwable was passed
|
||||
// this matches iOS behavior - iOS adds a `nativeStackIOS` property
|
||||
// iOS: /React/Base/RCTUtils.m -> RCTJSErrorFromCodeMessageAndNSError
|
||||
if (throwable != null) {
|
||||
errorInfo.putString(ERROR_MAP_KEY_NAME, throwable.getClass().getCanonicalName());
|
||||
|
||||
StackTraceElement[] stackTrace = throwable.getStackTrace();
|
||||
WritableNativeArray nativeStackAndroid = new WritableNativeArray();
|
||||
|
||||
// Build an an Array of StackFrames to match JavaScript:
|
||||
// iOS: /Libraries/Core/Devtools/parseErrorStack.js -> StackFrame
|
||||
for (int i = 0; i < stackTrace.length && i < ERROR_STACK_FRAME_LIMIT; i++) {
|
||||
StackTraceElement frame = stackTrace[i];
|
||||
WritableMap frameMap = new WritableNativeMap();
|
||||
// NOTE: no column number exists StackTraceElement
|
||||
frameMap.putString(STACK_FRAME_KEY_CLASS, frame.getClassName());
|
||||
frameMap.putString(STACK_FRAME_KEY_FILE, frame.getFileName());
|
||||
frameMap.putInt(STACK_FRAME_KEY_LINE_NUMBER, frame.getLineNumber());
|
||||
frameMap.putString(STACK_FRAME_KEY_METHOD_NAME, frame.getMethodName());
|
||||
nativeStackAndroid.pushMap(frameMap);
|
||||
}
|
||||
|
||||
errorInfo.putArray(ERROR_MAP_KEY_NATIVE_STACK, nativeStackAndroid);
|
||||
} else {
|
||||
errorInfo.putArray(ERROR_MAP_KEY_NATIVE_STACK, new WritableNativeArray());
|
||||
}
|
||||
|
||||
mReject.invoke(errorInfo);
|
||||
mResolve = null;
|
||||
mReject = null;
|
||||
}
|
||||
|
||||
/* ------------
|
||||
* Deprecated
|
||||
* ------------ */
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void reject(String message) {
|
||||
reject(/*Code*/ null, message, /*Throwable*/ null, /*WritableMap*/ null);
|
||||
}
|
||||
}
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* 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.proguard.annotations.DoNotStrip
|
||||
|
||||
/**
|
||||
* Implementation of [Promise] that represents a JavaScript Promise which can be passed to the
|
||||
* native module as a method parameter. Methods annotated with [ReactMethod] that use a [Promise] as
|
||||
* the last parameter will be marked as "promise" and will return a promise when invoked from
|
||||
* JavaScript.
|
||||
*/
|
||||
@DoNotStrip
|
||||
public class PromiseImpl(private var resolve: Callback?, private var reject: Callback?) : Promise {
|
||||
/**
|
||||
* Successfully resolve the [Promise] with an optional value.
|
||||
*
|
||||
* @param value Object
|
||||
*/
|
||||
override fun resolve(value: Any?) {
|
||||
resolve?.let { res ->
|
||||
res.invoke(value)
|
||||
resolve = null
|
||||
reject = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an error without an exception using a custom code and error message.
|
||||
*
|
||||
* @param code String
|
||||
* @param message String
|
||||
*/
|
||||
override fun reject(code: String, message: String?) {
|
||||
reject(code, message, null, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an exception with a custom code.
|
||||
*
|
||||
* @param code String
|
||||
* @param throwable Throwable
|
||||
*/
|
||||
override fun reject(code: String, throwable: Throwable?) {
|
||||
reject(code, null, throwable, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an exception with a custom code and error message.
|
||||
*
|
||||
* @param code String
|
||||
* @param message String
|
||||
* @param throwable Throwable
|
||||
*/
|
||||
override fun reject(code: String, message: String?, throwable: Throwable?) {
|
||||
reject(code, message, throwable, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an exception, with default error code. Useful in catch-all scenarios where it's unclear
|
||||
* why the error occurred.
|
||||
*
|
||||
* @param throwable Throwable
|
||||
*/
|
||||
override fun reject(throwable: Throwable) {
|
||||
reject(null, null, throwable, null)
|
||||
}
|
||||
|
||||
/* ---------------------------
|
||||
* With userInfo WritableMap
|
||||
* --------------------------- */
|
||||
|
||||
/**
|
||||
* Report an exception, with default error code, with userInfo. Useful in catch-all scenarios
|
||||
* where it's unclear why the error occurred.
|
||||
*
|
||||
* @param throwable Throwable
|
||||
* @param userInfo WritableMap
|
||||
*/
|
||||
override fun reject(throwable: Throwable, userInfo: WritableMap) {
|
||||
reject(null, null, throwable, userInfo)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject with a code and userInfo WritableMap.
|
||||
*
|
||||
* @param code String
|
||||
* @param userInfo WritableMap
|
||||
*/
|
||||
override fun reject(code: String, userInfo: WritableMap) {
|
||||
reject(code, null, null, userInfo)
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an exception with a custom code and userInfo.
|
||||
*
|
||||
* @param code String
|
||||
* @param throwable Throwable
|
||||
* @param userInfo WritableMap
|
||||
*/
|
||||
override fun reject(code: String, throwable: Throwable?, userInfo: WritableMap) {
|
||||
reject(code, null, throwable, userInfo)
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an error with a custom code, error message and userInfo, an error not caused by an
|
||||
* exception.
|
||||
*
|
||||
* @param code String
|
||||
* @param message String
|
||||
* @param userInfo WritableMap
|
||||
*/
|
||||
override fun reject(code: String, message: String?, userInfo: WritableMap) {
|
||||
reject(code, message, null, userInfo)
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an exception with a custom code, error message and userInfo.
|
||||
*
|
||||
* @param code String
|
||||
* @param message String
|
||||
* @param throwable Throwable
|
||||
* @param userInfo WritableMap
|
||||
*/
|
||||
override fun reject(
|
||||
code: String?,
|
||||
message: String?,
|
||||
throwable: Throwable?,
|
||||
userInfo: WritableMap?
|
||||
) {
|
||||
if (reject == null) {
|
||||
resolve = null
|
||||
return
|
||||
}
|
||||
|
||||
val errorInfo = WritableNativeMap()
|
||||
|
||||
if (code == null) {
|
||||
errorInfo.putString(ERROR_MAP_KEY_CODE, ERROR_DEFAULT_CODE)
|
||||
} else {
|
||||
errorInfo.putString(ERROR_MAP_KEY_CODE, code)
|
||||
}
|
||||
|
||||
// Use the custom message if provided otherwise use the throwable message.
|
||||
if (message != null) {
|
||||
errorInfo.putString(ERROR_MAP_KEY_MESSAGE, message)
|
||||
} else if (throwable != null) {
|
||||
var throwableMessage = throwable.message
|
||||
// Fallback to the throwable name, so we record some useful information
|
||||
if (throwableMessage.isNullOrEmpty()) {
|
||||
throwableMessage = throwable.javaClass.canonicalName
|
||||
}
|
||||
errorInfo.putString(ERROR_MAP_KEY_MESSAGE, throwableMessage)
|
||||
} else {
|
||||
// The JavaScript side expects a map with at least an error message.
|
||||
// /Libraries/BatchedBridge/NativeModules.js -> createErrorFromErrorData
|
||||
// TYPE: (errorData: { message: string })
|
||||
errorInfo.putString(ERROR_MAP_KEY_MESSAGE, ERROR_DEFAULT_MESSAGE)
|
||||
}
|
||||
|
||||
// For consistency with iOS ensure userInfo key exists, even if we null it.
|
||||
// iOS: /React/Base/RCTUtils.m -> RCTJSErrorFromCodeMessageAndNSError
|
||||
if (userInfo != null) {
|
||||
errorInfo.putMap(ERROR_MAP_KEY_USER_INFO, userInfo)
|
||||
} else {
|
||||
errorInfo.putNull(ERROR_MAP_KEY_USER_INFO)
|
||||
}
|
||||
|
||||
// Attach a nativeStackAndroid array if a throwable was passed
|
||||
// this matches iOS behavior - iOS adds a `nativeStackIOS` property
|
||||
// iOS: /React/Base/RCTUtils.m -> RCTJSErrorFromCodeMessageAndNSError
|
||||
if (throwable != null) {
|
||||
errorInfo.putString(ERROR_MAP_KEY_NAME, throwable.javaClass.canonicalName)
|
||||
|
||||
val stackTrace = throwable.stackTrace
|
||||
val nativeStackAndroid = WritableNativeArray()
|
||||
|
||||
// Build an an Array of StackFrames to match JavaScript:
|
||||
// iOS: /Libraries/Core/Devtools/parseErrorStack.js -> StackFrame
|
||||
var i = 0
|
||||
while (i < stackTrace.size && i < ERROR_STACK_FRAME_LIMIT) {
|
||||
val frame = stackTrace[i]
|
||||
val frameMap: WritableMap = WritableNativeMap()
|
||||
// NOTE: no column number exists StackTraceElement
|
||||
frameMap.putString(STACK_FRAME_KEY_CLASS, frame.className)
|
||||
frameMap.putString(STACK_FRAME_KEY_FILE, frame.fileName)
|
||||
frameMap.putInt(STACK_FRAME_KEY_LINE_NUMBER, frame.lineNumber)
|
||||
frameMap.putString(STACK_FRAME_KEY_METHOD_NAME, frame.methodName)
|
||||
nativeStackAndroid.pushMap(frameMap)
|
||||
i++
|
||||
}
|
||||
|
||||
errorInfo.putArray(ERROR_MAP_KEY_NATIVE_STACK, nativeStackAndroid)
|
||||
} else {
|
||||
errorInfo.putArray(ERROR_MAP_KEY_NATIVE_STACK, WritableNativeArray())
|
||||
}
|
||||
|
||||
reject?.invoke(errorInfo)
|
||||
resolve = null
|
||||
reject = null
|
||||
}
|
||||
|
||||
/* ------------
|
||||
* Deprecated
|
||||
* ------------ */
|
||||
|
||||
@Deprecated("Use reject(code, message) instead.", ReplaceWith("reject(code, message)"))
|
||||
override fun reject(message: String) {
|
||||
reject(null, message, null, null)
|
||||
}
|
||||
|
||||
public companion object {
|
||||
// Number of stack frames to parse and return to reject.invoke
|
||||
// for ERROR_MAP_KEY_NATIVE_STACK
|
||||
private const val ERROR_STACK_FRAME_LIMIT = 50
|
||||
|
||||
private const val ERROR_DEFAULT_CODE = "EUNSPECIFIED"
|
||||
private const val ERROR_DEFAULT_MESSAGE = "Error not specified."
|
||||
|
||||
// Keys for reject's WritableMap
|
||||
private const val ERROR_MAP_KEY_CODE = "code"
|
||||
private const val ERROR_MAP_KEY_MESSAGE = "message"
|
||||
private const val ERROR_MAP_KEY_NAME = "name"
|
||||
private const val ERROR_MAP_KEY_USER_INFO = "userInfo"
|
||||
private const val ERROR_MAP_KEY_NATIVE_STACK = "nativeStackAndroid"
|
||||
|
||||
// Keys for ERROR_MAP_KEY_NATIVE_STACK's StackFrame maps
|
||||
private const val STACK_FRAME_KEY_CLASS = "class"
|
||||
private const val STACK_FRAME_KEY_FILE = "file"
|
||||
private const val STACK_FRAME_KEY_LINE_NUMBER = "lineNumber"
|
||||
private const val STACK_FRAME_KEY_METHOD_NAME = "methodName"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user