diff options
author | Tor Norbye <tnorbye@google.com> | 2012-09-25 11:26:37 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2012-09-25 12:05:29 -0700 |
commit | 92e041939296097eb6b9851f82131625bd766d29 (patch) | |
tree | f80a174c9c44d12a6d6f2a26bc47356b9dd2b51f /lint/libs/lint_api | |
parent | e41d71e6d66d7fc3ac8a502dabf3f6be93b9403d (diff) | |
download | sdk-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.java | 42 | ||||
-rw-r--r-- | lint/libs/lint_api/src/com/android/tools/lint/client/api/LintDriver.java | 40 |
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); + } } /** |