aboutsummaryrefslogtreecommitdiffstats
path: root/lint/libs
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2012-05-22 17:08:48 -0700
committerTor Norbye <tnorbye@google.com>2012-05-22 17:08:48 -0700
commit74c48cca4341247d87e43ce56f8f6d327decb607 (patch)
tree691ae91df1a08ce20b23a253d7076ae5c01ce12e /lint/libs
parent180557283cc7b80d718c1d79a7cba380fc7cb11f (diff)
downloadsdk-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')
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java41
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java2
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java9
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");