Bug 1186517 - Fix SDKProcessor API version detection; r=snorp

The API version detection functionality was broken in SDKProcessor
because we were passing in "Lpackage/Class;" as the class name rather
than just "package/Class". Also, some classes have a weird situation
where some methods were moved around in later API versions. For example,
some put* and get* methods in Bundle were moved to BaseBundle in API 21.
If we only checked BaseBundle.put*, we would think they are API 21+
only. The workaround is to check both the top-level class and the
declaring class for a member, and choose the lower API level as the
minimal API level for that member.

This patch also fixes bugs in including the right class members.
For SDKProcessor we want to include all public members of a class,
including inherited members, because the private/protected members are
not part of the public API. For AnnotationProcessor, we want to include
all the members declared in that class, including private and
protected members, because we may want to access private/protected
members of our own Java classes from C++.
This commit is contained in:
Jim Chen 2015-07-29 15:11:15 -04:00
parent 64eb7d8aff
commit c723648f9d
2 changed files with 25 additions and 18 deletions

View File

@ -125,7 +125,21 @@ public class SDKProcessor {
System.out.println("SDK processing complete in " + (e - s) + "ms");
}
private static Member[] sortAndFilterMembers(Member[] members) {
private static int getAPIVersion(Class<?> cls, Member m) {
if (m instanceof Method || m instanceof Constructor) {
return sApiLookup.getCallVersion(
cls.getName().replace('.', '/'),
Utils.getMemberName(m),
Utils.getSignature(m));
} else if (m instanceof Field) {
return sApiLookup.getFieldVersion(
Utils.getClassDescriptor(m.getDeclaringClass()), m.getName());
} else {
throw new IllegalArgumentException("expected member to be Method, Constructor, or Field");
}
}
private static Member[] sortAndFilterMembers(Class<?> cls, Member[] members) {
Arrays.sort(members, new Comparator<Member>() {
@Override
public int compare(Member a, Member b) {
@ -135,20 +149,13 @@ public class SDKProcessor {
ArrayList<Member> list = new ArrayList<>();
for (Member m : members) {
int version = 0;
if (m instanceof Method || m instanceof Constructor) {
version = sApiLookup.getCallVersion(
Utils.getClassDescriptor(m.getDeclaringClass()),
m.getName(),
Utils.getSignature(m));
} else if (m instanceof Field) {
version = sApiLookup.getFieldVersion(
Utils.getClassDescriptor(m.getDeclaringClass()), m.getName());
} else {
throw new IllegalArgumentException("expected member to be Method, Constructor, or Field");
// Sometimes (e.g. Bundle) has methods that moved to/from a superclass in a later SDK
// version, so we check for both classes and see if we can find a minimum SDK version.
int version = getAPIVersion(cls, m);
final int version2 = getAPIVersion(m.getDeclaringClass(), m);
if (version2 > 0 && version2 < version) {
version = version2;
}
if (version > sMaxSdkVersion) {
System.out.println("Skipping " + m.getDeclaringClass().getName() + "." + m.getName() +
", version " + version + " > " + sMaxSdkVersion);
@ -168,9 +175,9 @@ public class SDKProcessor {
CodeGenerator generator = new CodeGenerator(new ClassWithOptions(clazz, generatedName));
generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredConstructors()));
generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredMethods()));
generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredFields()));
generator.generateMembers(sortAndFilterMembers(clazz, clazz.getConstructors()));
generator.generateMembers(sortAndFilterMembers(clazz, clazz.getMethods()));
generator.generateMembers(sortAndFilterMembers(clazz, clazz.getFields()));
headerFile.append(generator.getHeaderFileContents());
implementationFile.append(generator.getWrapperFileContents());

View File

@ -31,7 +31,7 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
// Get all the elements of this class as AccessibleObjects.
Member[] aMethods = aClass.getDeclaredMethods();
Member[] aFields = aClass.getDeclaredFields();
Member[] aCtors = aClass.getConstructors();
Member[] aCtors = aClass.getDeclaredConstructors();
// Shove them all into one buffer.
Member[] objs = new Member[aMethods.length + aFields.length + aCtors.length];