diff options
author | Tor Norbye <tnorbye@google.com> | 2012-05-22 17:08:48 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2012-05-22 17:08:48 -0700 |
commit | 74c48cca4341247d87e43ce56f8f6d327decb607 (patch) | |
tree | 691ae91df1a08ce20b23a253d7076ae5c01ce12e /lint/libs | |
parent | 180557283cc7b80d718c1d79a7cba380fc7cb11f (diff) | |
download | sdk-74c48cca4341247d87e43ce56f8f6d327decb607.zip sdk-74c48cca4341247d87e43ce56f8f6d327decb607.tar.gz sdk-74c48cca4341247d87e43ce56f8f6d327decb607.tar.bz2 |
Fix interface method lookup in the API Detector
The api-versions.xml file is being updated in a separate CL to pick up
some metadata which was missing, such as some enumeration constants.
As part of the update, it's also removing the duplication of all the
interface methods in the classes that implement those methods.
This changeset updates the API Lookup code to handle this
correctly. It will now properly visit the interface hierarchy, not
just the superclass hierarchy, when computing the full set of methods
and fields inherited into a class, as well as when it determines the
introduced-in API level for each method.
Change-Id: If19697b9812eaa072536057daa5cffe3589a0c75
Diffstat (limited to 'lint/libs')
3 files changed, 47 insertions, 5 deletions
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java index 8c35b74..9b18c03 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java @@ -17,8 +17,8 @@ package com.android.tools.lint.checks; import com.android.util.Pair; +import com.google.common.collect.Lists; -import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -38,8 +38,8 @@ public class ApiClass { private final String mName; private final int mSince; - private final List<Pair<String, Integer>> mSuperClasses = new ArrayList<Pair<String, Integer>>(); - private final List<Pair<String, Integer>> mInterfaces = new ArrayList<Pair<String, Integer>>(); + private final List<Pair<String, Integer>> mSuperClasses = Lists.newArrayList(); + private final List<Pair<String, Integer>> mInterfaces = Lists.newArrayList(); private final Map<String, Integer> mFields = new HashMap<String, Integer>(); private final Map<String, Integer> mMethods = new HashMap<String, Integer>(); @@ -161,6 +161,20 @@ public class ApiClass { } } + // now look at the interfaces classes + for (Pair<String, Integer> interfacePair : mInterfaces) { + ApiClass superClass = info.getClass(interfacePair.getFirst()); + if (superClass != null) { + i = superClass.getMethod(methodSignature, info); + if (i != null) { + int tmp = interfacePair.getSecond() > i ? interfacePair.getSecond() : i; + if (tmp < min) { + min = tmp; + } + } + } + } + return min; } @@ -232,6 +246,7 @@ public class ApiClass { for (String method : mMethods.keySet()) { set.add(method); } + for (Pair<String, Integer> superClass : mSuperClasses) { ApiClass clz = info.getClass(superClass.getFirst()); assert clz != null : superClass.getSecond(); @@ -239,6 +254,15 @@ public class ApiClass { clz.addAllMethods(info, set); } } + + // Get methods from implemented interfaces as well; + for (Pair<String, Integer> superClass : mInterfaces) { + ApiClass clz = info.getClass(superClass.getFirst()); + assert clz != null : superClass.getSecond(); + if (clz != null) { + clz.addAllMethods(info, set); + } + } } /** @@ -259,6 +283,7 @@ public class ApiClass { for (String field : mFields.keySet()) { set.add(field); } + for (Pair<String, Integer> superClass : mSuperClasses) { ApiClass clz = info.getClass(superClass.getFirst()); assert clz != null : superClass.getSecond(); @@ -266,6 +291,14 @@ public class ApiClass { clz.addAllFields(info, set); } } - } + // Get methods from implemented interfaces as well; + for (Pair<String, Integer> superClass : mInterfaces) { + ApiClass clz = info.getClass(superClass.getFirst()); + assert clz != null : superClass.getSecond(); + if (clz != null) { + clz.addAllFields(info, set); + } + } + } } diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java index 3163a6c..dd5585b 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java @@ -73,7 +73,7 @@ public class ApiLookup { /** Relative path to the api-versions.xml database file within the Lint installation */ private static final String XML_FILE_PATH = "platform-tools/api/api-versions.xml"; //$NON-NLS-1$ private static final String FILE_HEADER = "API database used by Android lint\000"; - private static final int BINARY_FORMAT_VERSION = 2; + private static final int BINARY_FORMAT_VERSION = 3; private static final boolean DEBUG_FORCE_REGENERATE_BINARY = false; private static final boolean DEBUG_SEARCH = false; private static final boolean WRITE_STATS = false; diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java index 044778f..1b9c3ef 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java @@ -62,6 +62,15 @@ public class ApiLookupTest extends AbstractCheckTest { assertEquals(9, mDb.getCallVersion("java/nio/Buffer", "array", "()")); } + public void testInheritInterfaces() { + // The onPreferenceStartFragment is inherited via the + // android/preference/PreferenceFragment$OnPreferenceStartFragmentCallback + // interface + assertEquals(11, mDb.getCallVersion("android/preference/PreferenceActivity", + "onPreferenceStartFragment", + "(Landroid/preference/PreferenceFragment;Landroid/preference/Preference;)")); + } + @Override protected Detector getDetector() { fail("This is not used in the ApiDatabase test"); |