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
This commit is contained in:
Alexander Blom 2016-01-12 13:40:25 -08:00 committed by facebook-github-bot-0
parent 2ed199fa2b
commit e2641a237a
1 changed files with 41 additions and 21 deletions

View File

@ -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<PropertyInfo>() {
@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) {