diff options
author | Jesse Wilson <jessewilson@google.com> | 2010-04-08 09:44:42 -0700 |
---|---|---|
committer | Jesse Wilson <jessewilson@google.com> | 2010-04-08 09:44:42 -0700 |
commit | 32fd763272fd336222abe8dcc2444b685a6af0fb (patch) | |
tree | 439d20bbf2409764cf6266cb69aad82dc2c2f4d2 | |
parent | f47dc0638a58cf1976d0a3b42ed6da1d6b8fd161 (diff) | |
download | build-32fd763272fd336222abe8dcc2444b685a6af0fb.zip build-32fd763272fd336222abe8dcc2444b685a6af0fb.tar.gz build-32fd763272fd336222abe8dcc2444b685a6af0fb.tar.bz2 |
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
-rw-r--r-- | tools/apicheck/src/com/android/apicheck/ApiCheck.java | 1 | ||||
-rw-r--r-- | tools/apicheck/src/com/android/apicheck/ApiInfo.java | 3 | ||||
-rw-r--r-- | tools/apicheck/src/com/android/apicheck/ClassInfo.java | 26 |
3 files changed, 23 insertions, 7 deletions
diff --git a/tools/apicheck/src/com/android/apicheck/ApiCheck.java b/tools/apicheck/src/com/android/apicheck/ApiCheck.java index c8272dd..b2f2265 100644 --- a/tools/apicheck/src/com/android/apicheck/ApiCheck.java +++ b/tools/apicheck/src/com/android/apicheck/ApiCheck.java @@ -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, diff --git a/tools/apicheck/src/com/android/apicheck/ApiInfo.java b/tools/apicheck/src/com/android/apicheck/ApiInfo.java index c237814..47b9a15 100644 --- a/tools/apicheck/src/com/android/apicheck/ApiInfo.java +++ b/tools/apicheck/src/com/android/apicheck/ApiInfo.java @@ -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())) { diff --git a/tools/apicheck/src/com/android/apicheck/ClassInfo.java b/tools/apicheck/src/com/android/apicheck/ClassInfo.java index e62a3d0..2555ea4 100644 --- a/tools/apicheck/src/com/android/apicheck/ClassInfo.java +++ b/tools/apicheck/src/com/android/apicheck/ClassInfo.java @@ -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)); |