Skip to content

Commit

Permalink
rewrite RNTesterApplication to kotlin (#39557)
Browse files Browse the repository at this point in the history
Summary:
Rewrite `RNTesterApplication` to Kotlin as per [Help us Kotlin-ify React Native tests - Round 2](#38825)

## Changelog:

[ANDROID] [CHANGED] - Rewrite RNTesterApplication to Kotlin, add AnnotationTarget property.

Pull Request resolved: #39557

Test Plan:
`yarn && yarn android` ✅

The only thing I'm kinda unsure of is whether `AnnotationTarget.PROPERTY` should be added, but it didn't let me annotate `reactHostInterface` without that and didn't compile.
<img width="637" alt="image" src="https://github.com/facebook/react-native/assets/33528752/8bc84870-f3f2-4a46-b076-6ee7e38bd735">

 cortinico mdvacca

Reviewed By: cortinico

Differential Revision: D49598401

Pulled By: mdvacca

fbshipit-source-id: 105ae0c13c93dae0eeb2b6fa9040f03f42d2736a
  • Loading branch information
ShevO27 authored and huntie committed Oct 19, 2023
1 parent f476353 commit 3700d6a
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 215 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
package com.facebook.react.common.annotations

@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
@RequiresOptIn(
level = RequiresOptIn.Level.ERROR,
message = "This API is experimental and is likely to change or to be removed in the future")
Expand Down

This file was deleted.

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

import android.app.Application
import com.facebook.fbreact.specs.SampleLegacyModule
import com.facebook.fbreact.specs.SampleTurboModule
import com.facebook.react.JSEngineResolutionAlgorithm
import com.facebook.react.ReactApplication
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.TurboReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.common.assets.ReactFontManager
import com.facebook.react.common.mapbuffer.ReadableMapBuffer
import com.facebook.react.config.ReactFeatureFlags
import com.facebook.react.defaults.DefaultComponentsRegistry.Companion.register
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.react.fabric.ComponentFactory
import com.facebook.react.flipper.ReactNativeFlipper.initializeFlipper
import com.facebook.react.interfaces.ReactHost
import com.facebook.react.interfaces.exceptionmanager.ReactJsExceptionHandler
import com.facebook.react.module.model.ReactModuleInfo
import com.facebook.react.module.model.ReactModuleInfoProvider
import com.facebook.react.runtime.ReactHostImpl
import com.facebook.react.shell.MainReactPackage
import com.facebook.react.uiapp.component.MyLegacyViewManager
import com.facebook.react.uiapp.component.MyNativeViewManager
import com.facebook.react.uimanager.ViewManager
import com.facebook.soloader.SoLoader

class RNTesterApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost by lazy {
if (ReactFeatureFlags.enableBridgelessArchitecture) {
throw RuntimeException("Should not use ReactNativeHost when Bridgeless enabled")
}
object : DefaultReactNativeHost(this) {
public override fun getJSMainModuleName(): String = "js/RNTesterApp.android"

public override fun getBundleAssetName(): String = "RNTesterApp.android.bundle"

override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG

public override fun getPackages(): List<ReactPackage> {
return listOf(
MainReactPackage(),
object : TurboReactPackage() {
override fun getModule(
name: String,
reactContext: ReactApplicationContext
): NativeModule? {
if (!ReactFeatureFlags.useTurboModules) {
return null
}
if (SampleTurboModule.NAME == name) {
return SampleTurboModule(reactContext)
}
if (SampleLegacyModule.NAME == name) {
return SampleLegacyModule(reactContext)
}
return null
}

// Note: Specialized annotation processor for @ReactModule isn't configured in OSS
// yet. For now, hardcode this information, though it's not necessary for most
// modules.
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider =
ReactModuleInfoProvider {
if (ReactFeatureFlags.useTurboModules) {
mapOf(
SampleTurboModule.NAME to
ReactModuleInfo(
SampleTurboModule.NAME,
"SampleTurboModule",
false, // canOverrideExistingModule
false, // needsEagerInit
false, // isCxxModule
true // isTurboModule
),
SampleLegacyModule.NAME to
ReactModuleInfo(
SampleLegacyModule.NAME,
"SampleLegacyModule",
false, // canOverrideExistingModule
false, // needsEagerInit
false, // isCxxModule
false // isTurboModule
))
} else {
emptyMap()
}
}
},
object : ReactPackage {
override fun createNativeModules(
reactContext: ReactApplicationContext
): List<NativeModule> {
return emptyList()
}

override fun createViewManagers(
reactContext: ReactApplicationContext
): List<ViewManager<*, *>> =
listOf(MyNativeViewManager(), MyLegacyViewManager(reactContext))
})
}

override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED_IN_FLAVOR
}
}

override fun onCreate() {
ReactFontManager.getInstance().addCustomFont(this, "Rubik", R.font.rubik)
super.onCreate()
SoLoader.init(this, /* native exopackage */ false)
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
load()
}
if (ReactFeatureFlags.enableBridgelessArchitecture) {
// TODO: initialize Flipper for Bridgeless
} else {
initializeFlipper(this, reactNativeHost.reactInstanceManager)
}
}

@UnstableReactNativeAPI
override val reactHost: ReactHost by lazy {
// Create an instance of ReactHost to manager the instance of ReactInstance,
// which is similar to how we use ReactNativeHost to manager instance of ReactInstanceManager
val reactHostDelegate = RNTesterReactHostDelegate(applicationContext)
val reactJsExceptionHandler = RNTesterReactJsExceptionHandler()
val componentFactory = ComponentFactory()
register(componentFactory)
ReactHostImpl(
this.applicationContext,
reactHostDelegate,
componentFactory,
true,
reactJsExceptionHandler,
true)
.apply {
jsEngineResolutionAlgorithm =
if (BuildConfig.IS_HERMES_ENABLED_IN_FLAVOR) {
JSEngineResolutionAlgorithm.HERMES
} else {
JSEngineResolutionAlgorithm.JSC
}
reactHostDelegate.reactHost = this
}
}

@UnstableReactNativeAPI
class RNTesterReactJsExceptionHandler : ReactJsExceptionHandler {
override fun reportJsException(errorMap: ReadableMapBuffer?) {}
}
}

0 comments on commit 3700d6a

Please sign in to comment.