mirror of
https://github.com/facebook/react-native.git
synced 2024-11-21 22:10:14 +00:00
Convert com.facebook.react.BaseReactPackage to Kotlin (#47679)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47679 Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D66119659 fbshipit-source-id: d7917aa09edac6d5a8c07635d294de229723f0c9
This commit is contained in:
parent
ba1bc639b8
commit
09b08aa4e0
@ -28,7 +28,7 @@ public class PopupMenuPackage() : BaseReactPackage(), ViewManagerOnDemandReactPa
|
||||
return null
|
||||
}
|
||||
|
||||
protected override fun getViewManagers(context: ReactApplicationContext): List<ModuleSpec> {
|
||||
protected override fun getViewManagers(reactContext: ReactApplicationContext): List<ModuleSpec> {
|
||||
return viewManagersMap.values.toList()
|
||||
}
|
||||
|
||||
|
@ -1,159 +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;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.bridge.ModuleHolder;
|
||||
import com.facebook.react.bridge.ModuleSpec;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
|
||||
import com.facebook.react.module.model.ReactModuleInfo;
|
||||
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import javax.inject.Provider;
|
||||
|
||||
/** Abstract class that supports lazy loading of NativeModules by default. */
|
||||
public abstract class BaseReactPackage implements ReactPackage {
|
||||
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
|
||||
throw new UnsupportedOperationException(
|
||||
"createNativeModules method is not supported. Use getModule() method instead.");
|
||||
}
|
||||
|
||||
/**
|
||||
* The API needed for TurboModules. Given a module name, it returns an instance of {@link
|
||||
* NativeModule} for the name
|
||||
*
|
||||
* @param name name of the Native Module
|
||||
* @param reactContext {@link ReactApplicationContext} context for this
|
||||
*/
|
||||
@Override
|
||||
public abstract @Nullable NativeModule getModule(
|
||||
@NonNull String name, @NonNull ReactApplicationContext reactContext);
|
||||
|
||||
/**
|
||||
* This is a temporary method till we implement TurboModules. Once we implement TurboModules, we
|
||||
* will be able to directly call {@link BaseReactPackage#getModule(String,
|
||||
* ReactApplicationContext)} This method will be removed when TurboModule implementation is
|
||||
* complete
|
||||
*
|
||||
* @param reactContext
|
||||
* @return
|
||||
*/
|
||||
/** package */
|
||||
Iterable<ModuleHolder> getNativeModuleIterator(final ReactApplicationContext reactContext) {
|
||||
final Set<Map.Entry<String, ReactModuleInfo>> entrySet =
|
||||
getReactModuleInfoProvider().getReactModuleInfos().entrySet();
|
||||
final Iterator<Map.Entry<String, ReactModuleInfo>> entrySetIterator = entrySet.iterator();
|
||||
// This should ideally be an IteratorConvertor, but we don't have any internal library for it
|
||||
return () ->
|
||||
new Iterator<ModuleHolder>() {
|
||||
@Nullable Map.Entry<String, ReactModuleInfo> nextEntry = null;
|
||||
|
||||
private void findNext() {
|
||||
while (entrySetIterator.hasNext()) {
|
||||
Map.Entry<String, ReactModuleInfo> entry = entrySetIterator.next();
|
||||
ReactModuleInfo reactModuleInfo = entry.getValue();
|
||||
|
||||
// This Iterator is used to create the NativeModule registry. The NativeModule
|
||||
// registry must not have TurboModules. Therefore, if TurboModules are enabled, and
|
||||
// the current NativeModule is a TurboModule, we need to skip iterating over it.
|
||||
if (ReactNativeFeatureFlags.useTurboModules() && reactModuleInfo.isTurboModule()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nextEntry = entry;
|
||||
return;
|
||||
}
|
||||
nextEntry = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (nextEntry == null) {
|
||||
findNext();
|
||||
}
|
||||
return nextEntry != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleHolder next() {
|
||||
if (nextEntry == null) {
|
||||
findNext();
|
||||
}
|
||||
|
||||
if (nextEntry == null) {
|
||||
throw new NoSuchElementException("ModuleHolder not found");
|
||||
}
|
||||
|
||||
Map.Entry<String, ReactModuleInfo> entry = nextEntry;
|
||||
|
||||
// Advance iterator
|
||||
findNext();
|
||||
String name = entry.getKey();
|
||||
ReactModuleInfo reactModuleInfo = entry.getValue();
|
||||
return new ModuleHolder(reactModuleInfo, new ModuleHolderProvider(name, reactContext));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Cannot remove native modules from the list");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reactContext react application context that can be used to create View Managers.
|
||||
* @return list of module specs that can create the View Managers.
|
||||
*/
|
||||
protected List<ModuleSpec> getViewManagers(ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
|
||||
List<ModuleSpec> viewManagerModuleSpecs = getViewManagers(reactContext);
|
||||
if (viewManagerModuleSpecs == null || viewManagerModuleSpecs.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<ViewManager> viewManagers = new ArrayList<>();
|
||||
for (ModuleSpec moduleSpec : viewManagerModuleSpecs) {
|
||||
viewManagers.add((ViewManager) moduleSpec.getProvider().get());
|
||||
}
|
||||
return viewManagers;
|
||||
}
|
||||
|
||||
public abstract ReactModuleInfoProvider getReactModuleInfoProvider();
|
||||
|
||||
private class ModuleHolderProvider implements Provider<NativeModule> {
|
||||
|
||||
private final String mName;
|
||||
private final ReactApplicationContext mReactContext;
|
||||
|
||||
public ModuleHolderProvider(String name, ReactApplicationContext reactContext) {
|
||||
mName = name;
|
||||
mReactContext = reactContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable NativeModule get() {
|
||||
return getModule(mName, mReactContext);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.facebook.react.bridge.ModuleHolder
|
||||
import com.facebook.react.bridge.ModuleSpec
|
||||
import com.facebook.react.bridge.NativeModule
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
|
||||
import com.facebook.react.module.model.ReactModuleInfo
|
||||
import com.facebook.react.module.model.ReactModuleInfoProvider
|
||||
import com.facebook.react.uimanager.ViewManager
|
||||
import java.util.ArrayList
|
||||
import java.util.NoSuchElementException
|
||||
import javax.inject.Provider
|
||||
|
||||
/** Abstract class that supports lazy loading of NativeModules by default. */
|
||||
public abstract class BaseReactPackage : ReactPackage {
|
||||
|
||||
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
||||
throw UnsupportedOperationException(
|
||||
"createNativeModules method is not supported. Use getModule() method instead.")
|
||||
}
|
||||
|
||||
/**
|
||||
* The API needed for TurboModules. Given a module name, it returns an instance of [NativeModule]
|
||||
* for the name
|
||||
*
|
||||
* @param name name of the Native Module
|
||||
* @param reactContext [ReactApplicationContext] context for this
|
||||
*/
|
||||
abstract override fun getModule(
|
||||
name: String,
|
||||
reactContext: ReactApplicationContext
|
||||
): NativeModule?
|
||||
|
||||
/**
|
||||
* This is a temporary method till we implement TurboModules. Once we implement TurboModules, we
|
||||
* will be able to directly call [BaseReactPackage#getModule(String, ReactApplicationContext)]
|
||||
* This method will be removed when TurboModule implementation is complete
|
||||
*
|
||||
* @param reactContext [ReactApplicationContext]
|
||||
* @return
|
||||
*/
|
||||
internal fun getNativeModuleIterator(
|
||||
reactContext: ReactApplicationContext
|
||||
): Iterable<ModuleHolder> {
|
||||
val entrySet = getReactModuleInfoProvider().getReactModuleInfos().entries
|
||||
val entrySetIterator = entrySet.iterator()
|
||||
// This should ideally be an IteratorConvertor, but we don't have any internal library for it
|
||||
return Iterable {
|
||||
object : Iterator<ModuleHolder> {
|
||||
var nextEntry: Map.Entry<String, ReactModuleInfo>? = null
|
||||
|
||||
private fun findNext() {
|
||||
while (entrySetIterator.hasNext()) {
|
||||
val entry = entrySetIterator.next()
|
||||
val reactModuleInfo = entry.value
|
||||
|
||||
// This Iterator is used to create the NativeModule registry. The NativeModule
|
||||
// registry must not have TurboModules. Therefore, if TurboModules are enabled, and
|
||||
// the current NativeModule is a TurboModule, we need to skip iterating over it.
|
||||
if (ReactNativeFeatureFlags.useTurboModules() && reactModuleInfo.isTurboModule) {
|
||||
continue
|
||||
}
|
||||
|
||||
nextEntry = entry
|
||||
return
|
||||
}
|
||||
nextEntry = null
|
||||
}
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
if (nextEntry == null) {
|
||||
findNext()
|
||||
}
|
||||
return nextEntry != null
|
||||
}
|
||||
|
||||
override fun next(): ModuleHolder {
|
||||
if (nextEntry == null) {
|
||||
findNext()
|
||||
}
|
||||
|
||||
val entry = nextEntry ?: throw NoSuchElementException("ModuleHolder not found")
|
||||
|
||||
// Advance iterator
|
||||
findNext()
|
||||
|
||||
return ModuleHolder(entry.value, ModuleHolderProvider(entry.key, reactContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reactContext react application context that can be used to create View Managers.
|
||||
* @return list of module specs that can create the View Managers.
|
||||
*/
|
||||
protected open fun getViewManagers(reactContext: ReactApplicationContext): List<ModuleSpec> =
|
||||
emptyList()
|
||||
|
||||
override fun createViewManagers(
|
||||
reactContext: ReactApplicationContext
|
||||
): List<ViewManager<in Nothing, in Nothing>> {
|
||||
val viewManagerModuleSpecs = getViewManagers(reactContext)
|
||||
if (viewManagerModuleSpecs.isNullOrEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
val viewManagers: MutableList<ViewManager<*, *>> = ArrayList()
|
||||
for (moduleSpec in viewManagerModuleSpecs) {
|
||||
viewManagers.add((moduleSpec.provider.get() as ViewManager<*, *>))
|
||||
}
|
||||
return viewManagers
|
||||
}
|
||||
|
||||
public abstract fun getReactModuleInfoProvider(): ReactModuleInfoProvider
|
||||
|
||||
private inner class ModuleHolderProvider(
|
||||
private val name: String,
|
||||
private val reactContext: ReactApplicationContext
|
||||
) : Provider<NativeModule?> {
|
||||
override fun get(): NativeModule? = getModule(name, reactContext)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user