mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-15 12:12:31 +08:00
Add annotation processor for @ReactProp
Summary: The annotation processor finds subclasses of ViewManager and ShadowNode and generates classes that can both provide a mapping of property names to their type as well as a way of setting these properties. This avoids having to do reflection to find the properties. The annotation processor is currently not working when building with Gradle. public Reviewed By: astreet Differential Revision: D2748958 fb-gh-sync-id: ded5b072d236ebf19fb43eaf704fc7f221a82c26
This commit is contained in:
committed by
facebook-github-bot-4
parent
c1b7a369af
commit
57f6cbb3dc
@@ -0,0 +1,163 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.react.uimanager;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
||||
|
||||
public class ViewManagerPropertyUpdater {
|
||||
public interface Settable {
|
||||
Map<String, String> getProperties();
|
||||
}
|
||||
|
||||
public interface ViewManagerSetter<T extends ViewManager, V extends View> extends Settable {
|
||||
void setProperty(T manager, V view, String name, CatalystStylesDiffMap props);
|
||||
}
|
||||
|
||||
public interface ShadowNodeSetter<T extends ReactShadowNode> extends Settable {
|
||||
void setProperty(T node, String name, CatalystStylesDiffMap props);
|
||||
}
|
||||
|
||||
private static final String TAG = "ViewManagerPropertyUpdater";
|
||||
|
||||
private static final Map<Class<?>, ViewManagerSetter<?, ?>> VIEW_MANAGER_SETTER_MAP =
|
||||
new HashMap<>();
|
||||
private static final Map<Class<?>, ShadowNodeSetter<?>> SHADOW_NODE_SETTER_MAP = new HashMap<>();
|
||||
|
||||
public static <T extends ViewManager, V extends View> void updateProps(
|
||||
T manager,
|
||||
V v,
|
||||
CatalystStylesDiffMap props) {
|
||||
ViewManagerSetter<T, V> setter = findManagerSetter(manager.getClass());
|
||||
ReadableMap propMap = props.mBackingMap;
|
||||
ReadableMapKeySetIterator iterator = propMap.keySetIterator();
|
||||
while (iterator.hasNextKey()) {
|
||||
String key = iterator.nextKey();
|
||||
setter.setProperty(manager, v, key, props);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends ReactShadowNode> void updateProps(T node, CatalystStylesDiffMap props) {
|
||||
ShadowNodeSetter<T> setter = findNodeSetter(node.getClass());
|
||||
ReadableMap propMap = props.mBackingMap;
|
||||
ReadableMapKeySetIterator iterator = propMap.keySetIterator();
|
||||
while (iterator.hasNextKey()) {
|
||||
String key = iterator.nextKey();
|
||||
setter.setProperty(node, key, props);
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, String> getNativeProps(
|
||||
Class<? extends ViewManager> viewManagerTopClass,
|
||||
Class<? extends ReactShadowNode> shadowNodeTopClass) {
|
||||
Map<String, String> props = new HashMap<>();
|
||||
props.putAll(findManagerSetter(viewManagerTopClass).getProperties());
|
||||
props.putAll(findNodeSetter(shadowNodeTopClass).getProperties());
|
||||
return props;
|
||||
}
|
||||
|
||||
private static <T extends ViewManager, V extends View> ViewManagerSetter<T, V> findManagerSetter(
|
||||
Class<? extends ViewManager> managerClass) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ViewManagerSetter<T, V> setter =
|
||||
(ViewManagerSetter<T, V>) VIEW_MANAGER_SETTER_MAP.get(managerClass);
|
||||
if (setter == null) {
|
||||
setter = findGeneratedSetter(managerClass);
|
||||
if (setter == null) {
|
||||
setter = new FallbackViewManagerSetter<>(managerClass);
|
||||
}
|
||||
VIEW_MANAGER_SETTER_MAP.put(managerClass, setter);
|
||||
}
|
||||
|
||||
return setter;
|
||||
}
|
||||
|
||||
private static <T extends ReactShadowNode> ShadowNodeSetter<T> findNodeSetter(
|
||||
Class<? extends ReactShadowNode> nodeClass) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ShadowNodeSetter<T> setter = (ShadowNodeSetter<T>) SHADOW_NODE_SETTER_MAP.get(nodeClass);
|
||||
if (setter == null) {
|
||||
setter = findGeneratedSetter(nodeClass);
|
||||
if (setter == null) {
|
||||
setter = new FallbackShadowNodeSetter<>(nodeClass);
|
||||
}
|
||||
SHADOW_NODE_SETTER_MAP.put(nodeClass, setter);
|
||||
}
|
||||
|
||||
return setter;
|
||||
}
|
||||
|
||||
private static <T> T findGeneratedSetter(Class<?> cls) {
|
||||
String clsName = cls.getName();
|
||||
try {
|
||||
Class<?> setterClass = Class.forName(clsName + "$$PropsSetter");
|
||||
//noinspection unchecked
|
||||
return (T) setterClass.newInstance();
|
||||
} catch (ClassNotFoundException e) {
|
||||
FLog.w(TAG, "Could not find generated setter for " + cls);
|
||||
return null;
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
throw new RuntimeException("Unable to instantiate methods getter for " + clsName, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class FallbackViewManagerSetter<T extends ViewManager, V extends View>
|
||||
implements ViewManagerSetter<T, V> {
|
||||
private final Map<String, ViewManagersPropertyCache.PropSetter> mPropSetters;
|
||||
|
||||
private FallbackViewManagerSetter(Class<? extends ViewManager> viewManagerClass) {
|
||||
mPropSetters =
|
||||
ViewManagersPropertyCache.getNativePropSettersForViewManagerClass(viewManagerClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperty(T manager, V v, String name, CatalystStylesDiffMap props) {
|
||||
ViewManagersPropertyCache.PropSetter setter = mPropSetters.get(name);
|
||||
if (setter != null) {
|
||||
setter.updateViewProp(manager, v, props);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getProperties() {
|
||||
Map<String, String> nativeProps = new HashMap<>();
|
||||
for (ViewManagersPropertyCache.PropSetter setter : mPropSetters.values()) {
|
||||
nativeProps.put(setter.getPropName(), setter.getPropType());
|
||||
}
|
||||
return nativeProps;
|
||||
}
|
||||
}
|
||||
|
||||
private static class FallbackShadowNodeSetter<T extends ReactShadowNode>
|
||||
implements ShadowNodeSetter<T> {
|
||||
private final Map<String, ViewManagersPropertyCache.PropSetter> mPropSetters;
|
||||
|
||||
private FallbackShadowNodeSetter(Class<? extends ReactShadowNode> shadowNodeClass) {
|
||||
mPropSetters =
|
||||
ViewManagersPropertyCache.getNativePropSettersForShadowNodeClass(shadowNodeClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperty(ReactShadowNode node, String name, CatalystStylesDiffMap props) {
|
||||
ViewManagersPropertyCache.PropSetter setter = mPropSetters.get(name);
|
||||
if (setter != null) {
|
||||
setter.updateShadowNodeProp(node, props);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getProperties() {
|
||||
Map<String, String> nativeProps = new HashMap<>();
|
||||
for (ViewManagersPropertyCache.PropSetter setter : mPropSetters.values()) {
|
||||
nativeProps.put(setter.getPropName(), setter.getPropType());
|
||||
}
|
||||
return nativeProps;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user