Commit 32fd7632 authored by Jesse Wilson's avatar Jesse Wilson
Browse files

Fixing apicheck to cope with interfaces inherited from other interfaces.

For example, in Java 5, FutureTask was declared like this:
    public class FutureTask<V> implements Runnable, Future<V> {}

In Java 6, it's declared like this:
    public class FutureTask<V> implements RunnableFuture<V> {}
    public interface RunnableFuture extends Runnable, Future<V> {}

Change-Id: I0cd66a655fbe7fd5c7c48099d656b7a39368dac4
parent f47dc063
......@@ -107,6 +107,7 @@ public class ApiCheck {
xmlreader.parse(new InputSource(fileReader));
ApiInfo apiInfo = handler.getApi();
apiInfo.resolveSuperclasses();
apiInfo.resolveInterfaces();
return apiInfo;
} catch (SAXParseException e) {
Errors.error(Errors.PARSE_ERROR,
......
......@@ -31,14 +31,13 @@ public class ApiInfo {
return mAllClasses.get(name);
}
private void resolveInterfaces() {
public void resolveInterfaces() {
for (ClassInfo c : mAllClasses.values()) {
c.resolveInterfaces(this);
}
}
public boolean isConsistent(ApiInfo otherApi) {
resolveInterfaces();
boolean consistent = true;
for (PackageInfo pInfo : mPackages.values()) {
if (otherApi.getPackages().containsKey(pInfo.name())) {
......
......@@ -135,11 +135,7 @@ public class ClassInfo {
consistent = false;
}
for (String iface : mInterfaceNames) {
boolean found = false;
for (ClassInfo c = cl; c != null && !found; c = c.mSuperClass) {
found = c.mInterfaceNames.contains(iface);
}
if (!found) {
if (!implementsInterface(cl, iface)) {
Errors.error(Errors.REMOVED_INTERFACE, cl.position(),
"Class " + qualifiedName() + " no longer implements " + iface);
}
......@@ -274,6 +270,26 @@ public class ClassInfo {
return consistent;
}
/**
* Returns true if {@code cl} implements the interface {@code iface} either
* by either being that interface, implementing that interface or extending
* a type that implements the interface.
*/
private boolean implementsInterface(ClassInfo cl, String iface) {
if (cl.qualifiedName().equals(iface)) {
return true;
}
for (ClassInfo clImplements : cl.mInterfaces) {
if (implementsInterface(clImplements, iface)) {
return true;
}
}
if (cl.mSuperClass != null && implementsInterface(cl.mSuperClass, iface)) {
return true;
}
return false;
}
public void resolveInterfaces(ApiInfo apiInfo) {
for (String interfaceName : mInterfaceNames) {
mInterfaces.add(apiInfo.findClass(interfaceName));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment