Use JavaScriptModuleRegistry.getJSModuleName()

Summary:
It turns out that in release builds, proguard is doing something weird with inner classes, so that getSimpleName() is actually returning "OuterClass$InnerClass" in some cases. We have logic to handle this case already in JavaScriptModuleRegistry, so I'm moving that out to a static method that I can access in bridgeless mode.

Also adding tests for it.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D19701703

fbshipit-source-id: 625737bfb50ca8ba2bd26034e2a74c682783ba8a
This commit is contained in:
Emily Janzer
2020-02-05 15:26:11 -08:00
committed by Facebook Github Bot
parent 014bc95135
commit 73427561f7
4 changed files with 54 additions and 14 deletions
@@ -1,4 +1,4 @@
load("//tools/build_defs/oss:rn_defs.bzl", "IS_OSS_BUILD", "react_native_dep", "react_native_target", "rn_android_library")
load("//tools/build_defs/oss:rn_defs.bzl", "IS_OSS_BUILD", "react_native_dep", "react_native_target", "react_native_tests_target", "rn_android_library")
INTERFACES = [
"Dynamic.java",
@@ -30,6 +30,9 @@ rn_android_library(
react_native_dep("third-party/android/androidx:legacy-support-core-utils"),
],
required_for_source_only_abi = True,
tests = [
react_native_tests_target("java/com/facebook/react/bridge:bridge"),
],
visibility = [
"PUBLIC",
],
@@ -71,17 +71,8 @@ public final class JavaScriptModuleRegistry {
private String getJSModuleName() {
if (mName == null) {
// With proguard obfuscation turned on, proguard apparently (poorly) emulates inner
// classes or something because Class#getSimpleName() no longer strips the outer
// class name. We manually strip it here if necessary.
String name = mModuleInterface.getSimpleName();
int dollarSignIndex = name.lastIndexOf('$');
if (dollarSignIndex != -1) {
name = name.substring(dollarSignIndex + 1);
}
// getting the class name every call is expensive, so cache it
mName = name;
// Getting the class name every call is expensive, so cache it
mName = JavaScriptModuleRegistry.getJSModuleName(mModuleInterface);
}
return mName;
}
@@ -94,4 +85,16 @@ public final class JavaScriptModuleRegistry {
return null;
}
}
public static String getJSModuleName(Class<? extends JavaScriptModule> jsModuleInterface) {
// With proguard obfuscation turned on, proguard apparently (poorly) emulates inner
// classes or something because Class#getSimpleName() no longer strips the outer
// class name. We manually strip it here if necessary.
String name = jsModuleInterface.getSimpleName();
int dollarSignIndex = name.lastIndexOf('$');
if (dollarSignIndex != -1) {
name = name.substring(dollarSignIndex + 1);
}
return name;
}
}
@@ -25,8 +25,7 @@ rn_android_library(
rn_robolectric_test(
name = "bridge",
srcs = glob(STANDARD_TEST_SRCS),
# Please change the contact to the oncall of your team
contacts = ["oncall+fbandroid_sheriff@xmail.facebook.com"],
contacts = ["oncall+react_native@xmail.facebook.com"],
visibility = [
"PUBLIC",
],
@@ -0,0 +1,35 @@
/*
* 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 org.junit.Assert;
import org.junit.Test;
/** Tests for {@link JavaScriptModuleRegistry} */
public class JavaScriptModuleRegistryTest {
private interface TestJavaScriptModule extends JavaScriptModule {
void doSomething();
}
private interface OuterClass$NestedInnerClass extends JavaScriptModule {
void doSomething();
}
@Test
public void testGetJSModuleName() {
String name = JavaScriptModuleRegistry.getJSModuleName(TestJavaScriptModule.class);
Assert.assertEquals("TestJavaScriptModule", name);
}
@Test
public void testGetJSModuleName_stripOuterClass() {
String name = JavaScriptModuleRegistry.getJSModuleName(OuterClass$NestedInnerClass.class);
Assert.assertEquals("NestedInnerClass", name);
}
}