From e2641a237a453b27bed72815d5c14d251fd491a3 Mon Sep 17 00:00:00 2001 From: Alexander Blom Date: Tue, 12 Jan 2016 13:40:25 -0800 Subject: [PATCH] Scan parent class' methods for @ReactProp and @ReactPropGroup annotations Summary: When class A declares a ReactProp method foo() and class B that extends from A overrides foo(), it loses the annotation so it has to be duplicated. To allow "inheriting" annotation on Override, we need to scan parent class methods for annotation as well. This diff implements the required logic. public Reviewed By: dkoroskin Differential Revision: D2818278 fb-gh-sync-id: 7e9ae728cc70ce2345db7bc48b3857a0e91c4ca3 --- .../processing/ReactPropertyProcessor.java | 62 ++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/processing/ReactPropertyProcessor.java b/ReactAndroid/src/main/java/com/facebook/react/processing/ReactPropertyProcessor.java index 19641f633..bffd3f5df 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/processing/ReactPropertyProcessor.java +++ b/ReactAndroid/src/main/java/com/facebook/react/processing/ReactPropertyProcessor.java @@ -23,6 +23,7 @@ import javax.lang.model.util.Types; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -157,6 +158,14 @@ public class ReactPropertyProcessor extends AbstractProcessor { for (ClassInfo classInfo : mClasses.values()) { try { if (!shouldIgnoreClass(classInfo)) { + // Sort by name + Collections.sort( + classInfo.mProperties, new Comparator() { + @Override + public int compare(PropertyInfo a, PropertyInfo b) { + return a.mProperty.name().compareTo(b.mProperty.name()); + } + }); generateCode(classInfo, classInfo.mProperties); } else if (shouldWarnClass(classInfo)) { warning(classInfo.mElement, "Class was skipped. Classes need to be non-private."); @@ -178,31 +187,42 @@ public class ReactPropertyProcessor extends AbstractProcessor { TypeName viewType = targetType.equals(SHADOW_NODE_TYPE) ? null : targetType; ClassInfo classInfo = new ClassInfo(className, typeElement, viewType); + findProperties(classInfo, typeElement); - PropertyInfo.Builder propertyBuilder = new PropertyInfo.Builder(mTypes, mElements, classInfo); - for (Element element : mElements.getAllMembers(typeElement)) { - ReactProp prop = element.getAnnotation(ReactProp.class); - ReactPropGroup propGroup = element.getAnnotation(ReactPropGroup.class); - - try { - if (prop != null || propGroup != null) { - checkElement(element); - } - - if (prop != null) { - classInfo.addProperty(propertyBuilder.build(element, new RegularProperty(prop))); - } else if (propGroup != null) { - for (int i = 0, size = propGroup.names().length; i < size; i++) { - classInfo.addProperty(propertyBuilder.build(element, new GroupProperty(propGroup, i))); - } - } - } catch (ReactPropertyException e) { - error(e.element, e.getMessage()); - } - } return classInfo; } + private void findProperties(ClassInfo classInfo, TypeElement typeElement) { + PropertyInfo.Builder propertyBuilder = new PropertyInfo.Builder(mTypes, mElements, classInfo); + + // Recursively search class hierarchy + while (typeElement != null) { + for (Element element : typeElement.getEnclosedElements()) { + ReactProp prop = element.getAnnotation(ReactProp.class); + ReactPropGroup propGroup = element.getAnnotation(ReactPropGroup.class); + + try { + if (prop != null || propGroup != null) { + checkElement(element); + } + + if (prop != null) { + classInfo.addProperty(propertyBuilder.build(element, new RegularProperty(prop))); + } else if (propGroup != null) { + for (int i = 0, size = propGroup.names().length; i < size; i++) { + classInfo + .addProperty(propertyBuilder.build(element, new GroupProperty(propGroup, i))); + } + } + } catch (ReactPropertyException e) { + error(e.element, e.getMessage()); + } + } + + typeElement = (TypeElement) mTypes.asElement(typeElement.getSuperclass()); + } + } + private TypeName getTargetType(TypeMirror mirror) { TypeName typeName = TypeName.get(mirror); if (typeName instanceof ParameterizedTypeName) {