aboutsummaryrefslogtreecommitdiffstats
path: root/lint/libs/lint_api
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2012-09-25 11:26:37 -0700
committerTor Norbye <tnorbye@google.com>2012-09-25 12:05:29 -0700
commit92e041939296097eb6b9851f82131625bd766d29 (patch)
treef80a174c9c44d12a6d6f2a26bc47356b9dd2b51f /lint/libs/lint_api
parente41d71e6d66d7fc3ac8a502dabf3f6be93b9403d (diff)
downloadsdk-92e041939296097eb6b9851f82131625bd766d29.zip
sdk-92e041939296097eb6b9851f82131625bd766d29.tar.gz
sdk-92e041939296097eb6b9851f82131625bd766d29.tar.bz2
37733: TargetAPI doesn't fails to report unsupported API
Make incremental lint in source files use the Eclipse context to find super classes. Change-Id: I31af7a146c259875857026bc7721294205482a91
Diffstat (limited to 'lint/libs/lint_api')
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java42
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/LintDriver.java40
2 files changed, 79 insertions, 3 deletions
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java
index c15b284..2e21c06 100644
--- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java
+++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java
@@ -599,4 +599,46 @@ public abstract class LintClient {
return max;
}
+
+ /**
+ * Returns the super class for the given class name, which should be in VM
+ * format (e.g. java/lang/Integer, not java.lang.Integer, and using $ rather
+ * than . for inner classes). If the super class is not known, returns null.
+ * <p>
+ * This is typically not necessary, since lint analyzes all the available
+ * classes. However, if this lint client is invoking lint in an incremental
+ * context (for example, an IDE offering incremental analysis of a single
+ * source file), then lint may not see all the classes, and the client can
+ * provide its own super class lookup.
+ *
+ * @param project the project containing the class
+ * @param name the fully qualified class name
+ * @return the corresponding super class name (in VM format), or null if not
+ * known
+ */
+ @Nullable
+ public String getSuperClass(@NonNull Project project, @NonNull String name) {
+ return null;
+ }
+
+ /**
+ * Checks whether the given name is a subclass of the given super class. If
+ * the method does not know, it should return null, and otherwise return
+ * {@link Boolean#TRUE} or {@link Boolean#FALSE}.
+ * <p>
+ * Note that the class names are in internal VM format (java/lang/Integer,
+ * not java.lang.Integer, and using $ rather than . for inner classes).
+ *
+ * @param project the project context to look up the class in
+ * @param name the name of the class to be checked
+ * @param superClassName the name of the super class to compare to
+ * @return true if the class of the given name extends the given super class
+ */
+ @Nullable
+ public Boolean isSubclassOf(
+ @NonNull Project project,
+ @NonNull String name, @NonNull
+ String superClassName) {
+ return null;
+ }
}
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintDriver.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintDriver.java
index a833dae..aad1ad7 100644
--- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintDriver.java
+++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintDriver.java
@@ -53,6 +53,7 @@ import com.google.common.annotations.Beta;
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;
@@ -930,7 +931,19 @@ public class LintDriver {
throw new IllegalStateException("Only callable during ClassScanner#checkClass");
}
assert name.indexOf('.') == -1 : "Use VM signatures, e.g. java/lang/Integer";
- return mSuperClassMap.get(name);
+
+ String superClass = mSuperClassMap.get(name);
+ if (superClass == null && mCurrentProject != null) {
+ if ("java/lang/Object".equals(name)) { //$NON-NLS-1$
+ return null;
+ }
+ superClass = mClient.getSuperClass(mCurrentProject, name);
+ if (superClass != null) {
+ mSuperClassMap.put(name, superClass);
+ }
+ }
+
+ return superClass;
}
/**
@@ -947,6 +960,13 @@ public class LintDriver {
return true;
}
+ if (mCurrentProject != null) {
+ Boolean isSub = mClient.isSubclassOf(mCurrentProject, classNode.name, superClassName);
+ if (isSub != null) {
+ return isSub.booleanValue();
+ }
+ }
+
String className = classNode.name;
while (className != null) {
if (className.equals(superClassName)) {
@@ -1071,8 +1091,9 @@ public class LintDriver {
if (entries.size() > 0) {
Collections.sort(entries);
- // No superclass info available on individual lint runs
- mSuperClassMap = Collections.emptyMap();
+ // No superclass info available on individual lint runs, unless
+ // the client can provide it
+ mSuperClassMap = Maps.newHashMap();
runClassDetectors(Scope.CLASS_FILE, entries, project, main);
}
}
@@ -1711,6 +1732,19 @@ public class LintDriver {
public int getHighestKnownApiLevel() {
return mDelegate.getHighestKnownApiLevel();
}
+
+ @Override
+ @Nullable
+ public String getSuperClass(@NonNull Project project, @NonNull String name) {
+ return mDelegate.getSuperClass(project, name);
+ }
+
+ @Override
+ @Nullable
+ public Boolean isSubclassOf(@NonNull Project project, @NonNull String name,
+ @NonNull String superClassName) {
+ return mDelegate.isSubclassOf(project, name, superClassName);
+ }
}
/**