diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index e1c874827a8..180ff9fe814 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -5737,18 +5737,19 @@ public abstract interface class com/facebook/react/uimanager/util/ReactFindViewU public abstract fun onViewFound (Landroid/view/View;)V } -public class com/facebook/react/util/ExceptionDataHelper { - public fun ()V - public static fun getExtraDataAsJson (Lcom/facebook/react/bridge/ReadableMap;)Ljava/lang/String; +public final class com/facebook/react/util/ExceptionDataHelper { + public static final field EXTRA_DATA_FIELD Ljava/lang/String; + public static final field INSTANCE Lcom/facebook/react/util/ExceptionDataHelper; + public static final fun getExtraDataAsJson (Lcom/facebook/react/bridge/ReadableMap;)Ljava/lang/String; } -public class com/facebook/react/util/JSStackTrace { +public final class com/facebook/react/util/JSStackTrace { public static final field COLUMN_KEY Ljava/lang/String; public static final field FILE_KEY Ljava/lang/String; + public static final field INSTANCE Lcom/facebook/react/util/JSStackTrace; public static final field LINE_NUMBER_KEY Ljava/lang/String; public static final field METHOD_NAME_KEY Ljava/lang/String; - public fun ()V - public static fun format (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)Ljava/lang/String; + public static final fun format (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)Ljava/lang/String; } public abstract interface class com/facebook/react/util/RCTLog : com/facebook/react/bridge/JavaScriptModule { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/ExceptionDataHelper.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/ExceptionDataHelper.java deleted file mode 100644 index a266dd8cf8f..00000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/ExceptionDataHelper.java +++ /dev/null @@ -1,37 +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.util; - -import android.util.JsonWriter; -import com.facebook.react.bridge.JsonWriterHelper; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.ReadableType; -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import javax.annotation.Nullable; - -public class ExceptionDataHelper { - static final String EXTRA_DATA_FIELD = "extraData"; - - public static String getExtraDataAsJson(@Nullable ReadableMap metadata) { - if (metadata == null || metadata.getType(EXTRA_DATA_FIELD) == ReadableType.Null) { - return null; - } - try { - Writer extraDataWriter = new StringWriter(); - JsonWriter json = new JsonWriter(extraDataWriter); - JsonWriterHelper.value(json, metadata.getDynamic(EXTRA_DATA_FIELD)); - json.close(); - extraDataWriter.close(); - return extraDataWriter.toString(); - } catch (IOException ex) { - } - return null; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/ExceptionDataHelper.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/ExceptionDataHelper.kt new file mode 100644 index 00000000000..5c806a7c5b7 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/ExceptionDataHelper.kt @@ -0,0 +1,36 @@ +/* + * 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.util + +import android.util.JsonWriter +import com.facebook.react.bridge.JsonWriterHelper +import com.facebook.react.bridge.ReadableMap +import com.facebook.react.bridge.ReadableType +import java.io.IOException +import java.io.StringWriter + +public object ExceptionDataHelper { + + public const val EXTRA_DATA_FIELD: String = "extraData" + + @JvmStatic + public fun getExtraDataAsJson(metadata: ReadableMap?): String? { + if (metadata == null || metadata.getType(EXTRA_DATA_FIELD) == ReadableType.Null) { + return null + } + try { + val extraDataWriter = StringWriter() + val json = JsonWriter(extraDataWriter) + JsonWriterHelper.value(json, metadata.getDynamic(EXTRA_DATA_FIELD)) + json.close() + extraDataWriter.close() + return extraDataWriter.toString() + } catch (ex: IOException) {} + return null + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/JSStackTrace.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/JSStackTrace.java deleted file mode 100644 index f0e0d7f814b..00000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/JSStackTrace.java +++ /dev/null @@ -1,74 +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.util; - -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.ReadableType; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -@Nullsafe(Nullsafe.Mode.LOCAL) -public class JSStackTrace { - - public static final String LINE_NUMBER_KEY = "lineNumber"; - public static final String FILE_KEY = "file"; - public static final String COLUMN_KEY = "column"; - public static final String METHOD_NAME_KEY = "methodName"; - - private static final Pattern FILE_ID_PATTERN = - Pattern.compile("\\b((?:seg-\\d+(?:_\\d+)?|\\d+)\\.js)"); - - public static String format(String message, ReadableArray stack) { - StringBuilder stringBuilder = new StringBuilder(message).append(", stack:\n"); - for (int i = 0; i < stack.size(); i++) { - ReadableMap frame = stack.getMap(i); - stringBuilder.append(frame.getString(METHOD_NAME_KEY)).append("@").append(parseFileId(frame)); - - if (frame.hasKey(LINE_NUMBER_KEY) - && !frame.isNull(LINE_NUMBER_KEY) - && frame.getType(LINE_NUMBER_KEY) == ReadableType.Number) { - stringBuilder.append(frame.getInt(LINE_NUMBER_KEY)); - } else { - stringBuilder.append(-1); - } - - if (frame.hasKey(COLUMN_KEY) - && !frame.isNull(COLUMN_KEY) - && frame.getType(COLUMN_KEY) == ReadableType.Number) { - stringBuilder.append(":").append(frame.getInt(COLUMN_KEY)); - } - - stringBuilder.append("\n"); - } - return stringBuilder.toString(); - } - - // Besides a regular bundle (e.g. "bundle.js"), a stack frame can be produced by: - // 1) "random access bundle (RAM)", e.g. "1.js", where "1" is a module name - // 2) "segment file", e.g. "seg-1.js", where "1" is a segment name - // 3) "RAM segment file", e.g. "seg-1_2.js", where "1" is a segment name and "2" is a module name - // We are using a special source map format for such cases, so that we could symbolicate - // stack traces with a single source map file. - // NOTE: The ".js" suffix is kept to avoid ambiguities between "module-id:line" and "line:column". - private static String parseFileId(ReadableMap frame) { - if (frame.hasKey(FILE_KEY) - && !frame.isNull(FILE_KEY) - && frame.getType(FILE_KEY) == ReadableType.String) { - String file = frame.getString(FILE_KEY); - if (file != null) { - final Matcher matcher = FILE_ID_PATTERN.matcher(file); - if (matcher.find()) { - return matcher.group(1) + ":"; - } - } - } - return ""; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/JSStackTrace.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/JSStackTrace.kt new file mode 100644 index 00000000000..67f39388f27 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/JSStackTrace.kt @@ -0,0 +1,67 @@ +/* + * 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.util + +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.bridge.ReadableMap +import com.facebook.react.bridge.ReadableType +import java.util.regex.Pattern + +public object JSStackTrace { + + public const val LINE_NUMBER_KEY: String = "lineNumber" + public const val FILE_KEY: String = "file" + public const val COLUMN_KEY: String = "column" + public const val METHOD_NAME_KEY: String = "methodName" + private val FILE_ID_PATTERN = Pattern.compile("\\b((?:seg-\\d+(?:_\\d+)?|\\d+)\\.js)") + + @JvmStatic + public fun format(message: String, stack: ReadableArray): String { + val stringBuilder = StringBuilder(message).append(", stack:\n") + for (i in 0 until stack.size()) { + val frame = stack.getMap(i) + stringBuilder.append(frame.getString(METHOD_NAME_KEY)).append("@").append(parseFileId(frame)) + if (frame.hasKey(LINE_NUMBER_KEY) && + !frame.isNull(LINE_NUMBER_KEY) && + frame.getType(LINE_NUMBER_KEY) == ReadableType.Number) { + stringBuilder.append(frame.getInt(LINE_NUMBER_KEY)) + } else { + stringBuilder.append(-1) + } + if (frame.hasKey(COLUMN_KEY) && + !frame.isNull(COLUMN_KEY) && + frame.getType(COLUMN_KEY) == ReadableType.Number) { + stringBuilder.append(":").append(frame.getInt(COLUMN_KEY)) + } + stringBuilder.append("\n") + } + return stringBuilder.toString() + } + + // Besides a regular bundle (e.g. "bundle.js"), a stack frame can be produced by: + // 1) "random access bundle (RAM)", e.g. "1.js", where "1" is a module name + // 2) "segment file", e.g. "seg-1.js", where "1" is a segment name + // 3) "RAM segment file", e.g. "seg-1_2.js", where "1" is a segment name and "2" is a module name + // We are using a special source map format for such cases, so that we could symbolicate + // stack traces with a single source map file. + // NOTE: The ".js" suffix is kept to avoid ambiguities between "module-id:line" and "line:column". + private fun parseFileId(frame: ReadableMap): String { + if (frame.hasKey(FILE_KEY) && + !frame.isNull(FILE_KEY) && + frame.getType(FILE_KEY) == ReadableType.String) { + val file = frame.getString(FILE_KEY) + if (file != null) { + val matcher = FILE_ID_PATTERN.matcher(file) + if (matcher.find()) { + return "${matcher.group(1)}:" + } + } + } + return "" + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/RCTLog.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/RCTLog.kt similarity index 58% rename from packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/RCTLog.java rename to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/RCTLog.kt index 823dac14256..e34838bc484 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/RCTLog.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/util/RCTLog.kt @@ -5,22 +5,21 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.util; +package com.facebook.react.util -import com.facebook.react.bridge.JavaScriptModule; +import com.facebook.react.bridge.JavaScriptModule /** * JS module interface for RCTLog * - *

The RCTLog module allows for showing native logs in JavaScript. + * The RCTLog module allows for showing native logs in JavaScript. */ -public interface RCTLog extends JavaScriptModule { - +public interface RCTLog : JavaScriptModule { /** * Send a log to JavaScript. * * @param level The level of the log. * @param message The message to log. */ - void logIfNoNativeHook(String level, String message); + public fun logIfNoNativeHook(level: String?, message: String?) }