From 2f79960a69e02ee7a2bc1ebf91685f1e12e0ed69 Mon Sep 17 00:00:00 2001 From: Ram N Date: Thu, 6 Sep 2018 09:21:23 -0700 Subject: [PATCH] Convert ReactPackages in FB4a to switch-case Reviewed By: achen1 Differential Revision: D9511962 fbshipit-source-id: ea42b25f13b157866057d96d026317098e47ea63 --- .../com/facebook/react/LazyReactPackage.java | 8 +- .../react/NativeModuleRegistryBuilder.java | 3 + .../com/facebook/react/TurboReactPackage.java | 136 ++++++++++++++++++ 3 files changed, 140 insertions(+), 7 deletions(-) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/TurboReactPackage.java diff --git a/ReactAndroid/src/main/java/com/facebook/react/LazyReactPackage.java b/ReactAndroid/src/main/java/com/facebook/react/LazyReactPackage.java index b9e1a0455..0db2dbfce 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/LazyReactPackage.java +++ b/ReactAndroid/src/main/java/com/facebook/react/LazyReactPackage.java @@ -78,7 +78,6 @@ public abstract class LazyReactPackage implements ReactPackage { */ /* package */ Iterable getNativeModuleIterator(final ReactApplicationContext reactContext) { - final List eagerNativeModules = getEagerNativeModules(); final Map reactModuleInfoMap = getReactModuleInfoProvider().getReactModuleInfos(); final List nativeModules = getNativeModules(reactContext); @@ -96,7 +95,7 @@ public abstract class LazyReactPackage implements ReactPackage { String name = moduleSpec.getName(); ReactModuleInfo reactModuleInfo = reactModuleInfoMap.get(name); ModuleHolder moduleHolder; - if (reactModuleInfo == null || eagerNativeModules.contains(name)) { + if (reactModuleInfo == null) { NativeModule module; ReactMarker.logMarker(ReactMarkerConstants.CREATE_MODULE_START, name); try { @@ -131,11 +130,6 @@ public abstract class LazyReactPackage implements ReactPackage { */ protected abstract List getNativeModules(ReactApplicationContext reactContext); - /** @return list of native modules which should be eagerly initialized. */ - protected List getEagerNativeModules() { - return Collections.emptyList(); - } - /** * This is only used when a LazyReactPackage is a part of {@link CompositeReactPackage} Once we * deprecate {@link CompositeReactPackage}, this can be removed too diff --git a/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.java b/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.java index e1e16ce5c..2520e36ba 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.java +++ b/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.java @@ -32,6 +32,9 @@ public class NativeModuleRegistryBuilder { if (reactPackage instanceof LazyReactPackage) { moduleHolders = ((LazyReactPackage) reactPackage).getNativeModuleIterator(mReactApplicationContext); + } else if (reactPackage instanceof TurboReactPackage) { + moduleHolders = + ((TurboReactPackage) reactPackage).getNativeModuleIterator(mReactApplicationContext); } else { moduleHolders = ReactPackageHelper.getNativeModuleIterator( diff --git a/ReactAndroid/src/main/java/com/facebook/react/TurboReactPackage.java b/ReactAndroid/src/main/java/com/facebook/react/TurboReactPackage.java new file mode 100644 index 000000000..221abf474 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/TurboReactPackage.java @@ -0,0 +1,136 @@ +package com.facebook.react; + +import android.support.annotation.NonNull; +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.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.Set; +import javax.inject.Provider; + +/** This will eventually replace {@link LazyReactPackage} when TurboModules are finally done. */ +public abstract class TurboReactPackage implements ReactPackage { + + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + throw new UnsupportedOperationException( + "In case of TurboModules, createNativeModules is not supported. NativeModuleRegistry should instead use getModuleList or getModule method"); + } + + /** + * This is only a temporary method to test the impact of initializing some modules eagerly. This + * will deleted whenn + * qe_react_native_startup_module_optimization.eager_init_current_viewer_native_module is removed + * + * @return + */ + protected List getEagerNativeModules() { + return Collections.emptyList(); + } + + /** + * The API needed for TurboModules. Given a module name, it returns an instance of {@link + * NativeModule} for the name + * + * @param name + * @param reactContext + * @return + */ + public abstract NativeModule getModule(String name, final ReactApplicationContext reactContext); + + /** + * This is a temporary method till we implement TurboModules. Once we implement TurboModules, we + * will be able to directly call {@link TurboReactPackage#getModule(String, + * ReactApplicationContext)} This method will be removed when TurboModule implementation is + * complete + * + * @param reactContext + * @return + */ + public Iterable getNativeModuleIterator( + final ReactApplicationContext reactContext) { + final Set> entrySet = + getReactModuleInfoProvider().getReactModuleInfos().entrySet(); + final Iterator> entrySetIterator = entrySet.iterator(); + final List eagerNativeModules = getEagerNativeModules(); + return new Iterable() { + @NonNull + @Override + // This should ideally be an IteratorConvertor, but we don't have any internal library for it + public Iterator iterator() { + return new Iterator() { + @Override + public boolean hasNext() { + return entrySetIterator.hasNext(); + } + + @Override + public ModuleHolder next() { + Map.Entry entry = entrySetIterator.next(); + String name = entry.getKey(); + ReactModuleInfo reactModuleInfo = entry.getValue(); + if (eagerNativeModules.contains(name)) { + return new ModuleHolder(getModule(name, reactContext)); + } else { + 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 getViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + List viewManagerModuleSpecs = getViewManagers(reactContext); + if (viewManagerModuleSpecs == null || viewManagerModuleSpecs.isEmpty()) { + return Collections.emptyList(); + } + + List viewManagers = new ArrayList<>(); + for (ModuleSpec moduleSpec : viewManagerModuleSpecs) { + viewManagers.add((ViewManager) moduleSpec.getProvider().get()); + } + return viewManagers; + } + + public abstract ReactModuleInfoProvider getReactModuleInfoProvider(); + + private class ModuleHolderProvider implements Provider { + + private final String mName; + private final ReactApplicationContext mReactContext; + + public ModuleHolderProvider(String name, ReactApplicationContext reactContext) { + mName = name; + mReactContext = reactContext; + } + + @Override + public NativeModule get() { + return getModule(mName, mReactContext); + } + } +}