diff options
author | Tor Norbye <tnorbye@google.com> | 2012-01-10 12:31:43 -0800 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2012-01-10 14:39:32 -0800 |
commit | b1283f2cc2dd403fa9f92407d4dfac37eddd520d (patch) | |
tree | 8ccbc3cf337c1338494289cea044b5bc4d327e9c /lint | |
parent | 37d5a9bbdc2895921cd0f636777efe2d3bad4e5b (diff) | |
download | sdk-b1283f2cc2dd403fa9f92407d4dfac37eddd520d.zip sdk-b1283f2cc2dd403fa9f92407d4dfac37eddd520d.tar.gz sdk-b1283f2cc2dd403fa9f92407d4dfac37eddd520d.tar.bz2 |
Add annotations to the Lint API
Change-Id: I6222f3ef2909174d9111dcfc037a2e74ad093acd
Diffstat (limited to 'lint')
27 files changed, 542 insertions, 230 deletions
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/Configuration.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/Configuration.java index 461c438..8f5f230 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/Configuration.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/Configuration.java @@ -16,6 +16,8 @@ package com.android.tools.lint.client.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.tools.lint.detector.api.Context; import com.android.tools.lint.detector.api.Issue; import com.android.tools.lint.detector.api.Location; @@ -46,8 +48,12 @@ public abstract class Configuration { * more information * @return true if this issue should be suppressed */ - public boolean isIgnored(Context context, Issue issue, Location location, - String message, Object data) { + public boolean isIgnored( + @NonNull Context context, + @NonNull Issue issue, + @Nullable Location location, + @NonNull String message, + @Nullable Object data) { return false; } @@ -58,7 +64,7 @@ public abstract class Configuration { * @param issue the issue to check * @return false if the issue has been disabled */ - public boolean isEnabled(Issue issue) { + public boolean isEnabled(@NonNull Issue issue) { return getSeverity(issue) != Severity.IGNORE; } @@ -70,7 +76,7 @@ public abstract class Configuration { * @param issue the issue to look up the severity from * @return the severity use for issues for the given detector */ - public Severity getSeverity(Issue issue) { + public Severity getSeverity(@NonNull Issue issue) { return issue.getDefaultSeverity(); } @@ -81,12 +87,16 @@ public abstract class Configuration { * * @param context The scanning context * @param issue the issue to be ignored - * @param location The location to ignore the warning at + * @param location The location to ignore the warning at, if any * @param message The message for the warning * @param data The corresponding data, or null */ - public abstract void ignore(Context context, Issue issue, Location location, - String message, Object data); + public abstract void ignore( + @NonNull Context context, + @NonNull Issue issue, + @Nullable Location location, + @NonNull String message, + @Nullable Object data); /** * Sets the severity to be used for this issue. @@ -95,7 +105,7 @@ public abstract class Configuration { * @param severity the severity to associate with this issue, or null to * reset the severity to the default */ - public abstract void setSeverity(Issue issue, Severity severity); + public abstract void setSeverity(@NonNull Issue issue, @Nullable Severity severity); // Bulk editing support diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultConfiguration.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultConfiguration.java index 3622a73..1281987 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultConfiguration.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultConfiguration.java @@ -16,6 +16,8 @@ package com.android.tools.lint.client.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.tools.lint.detector.api.Context; import com.android.tools.lint.detector.api.Issue; import com.android.tools.lint.detector.api.Location; @@ -62,10 +64,15 @@ public class DefaultConfiguration extends Configuration { private static final String CONFIG_FILE_NAME = "lint.xml"; //$NON-NLS-1$ // Lint XML File + @NonNull private static final String TAG_ISSUE = "issue"; //$NON-NLS-1$ + @NonNull private static final String ATTR_ID = "id"; //$NON-NLS-1$ + @NonNull private static final String ATTR_SEVERITY = "severity"; //$NON-NLS-1$ + @NonNull private static final String ATTR_PATH = "path"; //$NON-NLS-1$ + @NonNull private static final String TAG_IGNORE = "ignore"; //$NON-NLS-1$ private final Configuration mParent; @@ -81,15 +88,21 @@ public class DefaultConfiguration extends Configuration { */ private Map<String, Severity> mSeverity; - protected DefaultConfiguration(LintClient client, Project project, Configuration parent, - File configFile) { + protected DefaultConfiguration( + @NonNull LintClient client, + @Nullable Project project, + @Nullable Configuration parent, + @NonNull File configFile) { mClient = client; mProject = project; mParent = parent; mConfigFile = configFile; } - protected DefaultConfiguration(LintClient client, Project project, Configuration parent) { + protected DefaultConfiguration( + @NonNull LintClient client, + @Nullable Project project, + @Nullable Configuration parent) { this(client, project, parent, new File(project.getDir(), CONFIG_FILE_NAME)); } @@ -101,8 +114,11 @@ public class DefaultConfiguration extends Configuration { * @param parent the parent/fallback configuration or null * @return a new configuration */ - public static DefaultConfiguration create(LintClient client, Project project, - Configuration parent) { + @NonNull + public static DefaultConfiguration create( + @NonNull LintClient client, + @NonNull Project project, + @Nullable Configuration parent) { return new DefaultConfiguration(client, project, parent); } @@ -115,13 +131,18 @@ public class DefaultConfiguration extends Configuration { * @param lintFile the lint file containing the configuration * @return a new configuration */ - public static DefaultConfiguration create(LintClient client, File lintFile) { + @NonNull + public static DefaultConfiguration create(@NonNull LintClient client, @NonNull File lintFile) { return new DefaultConfiguration(client, null /*project*/, null /*parent*/, lintFile); } @Override - public boolean isIgnored(Context context, Issue issue, Location location, String message, - Object data) { + public boolean isIgnored( + @NonNull Context context, + @NonNull Issue issue, + @Nullable Location location, + @NonNull String message, + @Nullable Object data) { ensureInitialized(); String id = issue.getId(); @@ -143,7 +164,8 @@ public class DefaultConfiguration extends Configuration { return false; } - protected Severity getDefaultSeverity(Issue issue) { + @NonNull + protected Severity getDefaultSeverity(@NonNull Issue issue) { if (!issue.isEnabledByDefault()) { return Severity.IGNORE; } @@ -152,7 +174,8 @@ public class DefaultConfiguration extends Configuration { } @Override - public Severity getSeverity(Issue issue) { + @NonNull + public Severity getSeverity(@NonNull Issue issue) { ensureInitialized(); Severity severity = mSeverity.get(issue.getId()); @@ -328,7 +351,8 @@ public class DefaultConfiguration extends Configuration { } } - private static void writeAttribute(Writer writer, String name, String value) + private static void writeAttribute( + @NonNull Writer writer, @NonNull String name, @NonNull String value) throws IOException { writer.write(' '); writer.write(name); @@ -339,8 +363,12 @@ public class DefaultConfiguration extends Configuration { } @Override - public void ignore(Context context, Issue issue, Location location, String message, - Object data) { + public void ignore( + @NonNull Context context, + @NonNull Issue issue, + @Nullable Location location, + @NonNull String message, + @Nullable Object data) { // This configuration only supports suppressing warnings on a per-file basis if (location != null) { ignore(issue, location.getFile()); @@ -353,7 +381,7 @@ public class DefaultConfiguration extends Configuration { * @param issue the issue to be ignored in the given file * @param file the file to ignore the issue in */ - public void ignore(Issue issue, File file) { + public void ignore(@NonNull Issue issue, @NonNull File file) { ensureInitialized(); String path = mProject != null ? mProject.getRelativePath(file) : file.getPath(); @@ -374,7 +402,7 @@ public class DefaultConfiguration extends Configuration { } @Override - public void setSeverity(Issue issue, Severity severity) { + public void setSeverity(@NonNull Issue issue, @Nullable Severity severity) { ensureInitialized(); String id = issue.getId(); diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java index 0392a6f..d012d67 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java @@ -56,6 +56,8 @@ import static com.android.tools.lint.detector.api.LintConstants.VIEW_STUB; import static com.android.tools.lint.detector.api.LintConstants.VIEW_SWITCHER; import static com.android.tools.lint.detector.api.LintConstants.WIDGET_PKG_PREFIX; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.google.common.annotations.Beta; import java.util.HashMap; @@ -70,12 +72,14 @@ import java.util.Map; @Beta class DefaultSdkInfo extends SdkInfo { @Override - public String getParentViewName(String name) { + @Nullable + public String getParentViewName(@NonNull String name) { return PARENTS.get(name); } @Override - public String getParentViewClass(String fqcn) { + @Nullable + public String getParentViewClass(@NonNull String fqcn) { int index = fqcn.lastIndexOf('.'); if (index != -1) { fqcn = fqcn.substring(index + 1); @@ -94,7 +98,7 @@ class DefaultSdkInfo extends SdkInfo { } @Override - public boolean isSubViewOf(String parent, String child) { + public boolean isSubViewOf(@NonNull String parent, @NonNull String child) { // Do analysis just on non-fqcn paths if (parent.indexOf('.') != -1) { parent = parent.substring(parent.lastIndexOf('.') + 1); @@ -117,7 +121,10 @@ class DefaultSdkInfo extends SdkInfo { } private static final int CLASS_COUNT = 56; + + @NonNull private static final Map<String, String> PARENTS = new HashMap<String, String>(CLASS_COUNT); + static { PARENTS.put(COMPOUND_BUTTON, VIEW); PARENTS.put(ABS_SPINNER, ADAPTER_VIEW); diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/IDomParser.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/IDomParser.java index 743e0c5..871133b 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/IDomParser.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/IDomParser.java @@ -16,6 +16,8 @@ package com.android.tools.lint.client.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.tools.lint.detector.api.Context; import com.android.tools.lint.detector.api.Location; import com.android.tools.lint.detector.api.XmlContext; @@ -42,7 +44,8 @@ public interface IDomParser { * editor buffer in the surrounding tool, etc) * @return the parsed DOM document, or null if parsing fails */ - Document parseXml(XmlContext context); + @Nullable + Document parseXml(@NonNull XmlContext context); /** * Returns a {@link Location} for the given DOM node @@ -51,7 +54,8 @@ public interface IDomParser { * @param node the node to create a location for * @return a location for the given node */ - Location getLocation(XmlContext context, Node node); + @NonNull + Location getLocation(@NonNull XmlContext context, @NonNull Node node); /** * Creates a light-weight handle to a location for the given node. It can be @@ -63,12 +67,13 @@ public interface IDomParser { * for * @return a location handle */ - Location.Handle createLocationHandle(XmlContext context, Node node); + @NonNull + Location.Handle createLocationHandle(@NonNull XmlContext context, @NonNull Node node); /** * Dispose any data structures held for the given context. * @param context information about the file previously parsed * @param document the document that was parsed and is now being disposed */ - void dispose(XmlContext context, Document document); + void dispose(@NonNull XmlContext context, @NonNull Document document); } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/IJavaParser.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/IJavaParser.java index 4de463b..34a9306 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/IJavaParser.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/IJavaParser.java @@ -16,6 +16,8 @@ package com.android.tools.lint.client.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.tools.lint.detector.api.Context; import com.android.tools.lint.detector.api.JavaContext; import com.android.tools.lint.detector.api.Location; @@ -40,7 +42,8 @@ public interface IJavaParser { * editor buffer in the surrounding tool, etc) * @return the compilation unit node for the file */ - Node parseJava(JavaContext context); + @Nullable + Node parseJava(@NonNull JavaContext context); /** * Returns a {@link Location} for the given node @@ -49,7 +52,8 @@ public interface IJavaParser { * @param node the node to create a location for * @return a location for the given node */ - Location getLocation(JavaContext context, Node node); + @NonNull + Location getLocation(@NonNull JavaContext context, @NonNull Node node); /** * Creates a light-weight handle to a location for the given node. It can be @@ -61,12 +65,13 @@ public interface IJavaParser { * for * @return a location handle */ - Location.Handle createLocationHandle(XmlContext context, Node node); + @NonNull + Location.Handle createLocationHandle(@NonNull XmlContext context, @NonNull Node node); /** * Dispose any data structures held for the given context. * @param context information about the file previously parsed * @param compilationUnit the compilation unit being disposed */ - void dispose(JavaContext context, Node compilationUnit); + void dispose(@NonNull JavaContext context, @NonNull Node compilationUnit); } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/IssueRegistry.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/IssueRegistry.java index 67efe36..a809841 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/IssueRegistry.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/IssueRegistry.java @@ -16,6 +16,8 @@ package com.android.tools.lint.client.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.tools.lint.detector.api.Category; import com.android.tools.lint.detector.api.Detector; import com.android.tools.lint.detector.api.Issue; @@ -46,6 +48,7 @@ public abstract class IssueRegistry { * Issue reported by lint (not a specific detector) when it cannot even * parse an XML file prior to analysis */ + @NonNull public static final Issue PARSER_ERROR = Issue.create( "ParserError", //$NON-NLS-1$ "Finds files that contain fatal parser errors", @@ -63,6 +66,7 @@ public abstract class IssueRegistry { * @return the list of issues to be checked (including those that may be * disabled!) */ + @NonNull public abstract List<Issue> getIssues(); /** @@ -79,11 +83,12 @@ public abstract class IssueRegistry { * the applicable detectors for that scope * @return a list of new detector instances */ + @NonNull final List<? extends Detector> createDetectors( - LintClient client, - Configuration configuration, - EnumSet<Scope> scope, - Map<Scope, List<Detector>> scopeToDetectors) { + @NonNull LintClient client, + @NonNull Configuration configuration, + @NonNull EnumSet<Scope> scope, + @Nullable Map<Scope, List<Detector>> scopeToDetectors) { List<Issue> issues = getIssues(); Set<Class<? extends Detector>> detectorClasses = new HashSet<Class<? extends Detector>>(); Map<Class<? extends Detector>, EnumSet<Scope>> detectorToScope = @@ -152,7 +157,7 @@ public abstract class IssueRegistry { * @param id the id to be checked * @return true if the given id is valid */ - public final boolean isIssueId(String id) { + public final boolean isIssueId(@NonNull String id) { return getIssue(id) != null; } @@ -162,7 +167,7 @@ public abstract class IssueRegistry { * @param name the category name to be checked * @return true if the given string is a valid category */ - public final boolean isCategoryName(String name) { + public final boolean isCategoryName(@NonNull String name) { for (Category c : getCategories()) { if (c.getName().equals(name) || c.getFullName().equals(name)) { return true; @@ -177,6 +182,7 @@ public abstract class IssueRegistry { * * @return an iterator for all the categories, never null */ + @NonNull public List<Category> getCategories() { if (sCategories == null) { final Set<Category> categories = new HashSet<Category>(); @@ -197,7 +203,8 @@ public abstract class IssueRegistry { * @param id the id to be checked * @return the corresponding issue, or null */ - public final Issue getIssue(String id) { + @Nullable + public final Issue getIssue(@NonNull String id) { if (sIdToIssue == null) { List<Issue> issues = getIssues(); sIdToIssue = new HashMap<String, Issue>(issues.size()); diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/JavaVisitor.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/JavaVisitor.java index 14a0627..63b51b5 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/JavaVisitor.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/JavaVisitor.java @@ -16,6 +16,7 @@ package com.android.tools.lint.client.api; +import com.android.annotations.NonNull; import com.android.tools.lint.detector.api.Detector; import com.android.tools.lint.detector.api.Detector.JavaScanner; import com.android.tools.lint.detector.api.Detector.XmlScanner; @@ -136,7 +137,7 @@ public class JavaVisitor { new HashMap<Class<? extends Node>, List<VisitingDetector>>(); private final IJavaParser mParser; - JavaVisitor(IJavaParser parser, List<Detector> detectors) { + JavaVisitor(@NonNull IJavaParser parser, @NonNull List<Detector> detectors) { mParser = parser; mAllDetectors = new ArrayList<VisitingDetector>(detectors.size()); mFullTreeDetectors = new ArrayList<VisitingDetector>(detectors.size()); @@ -182,7 +183,7 @@ public class JavaVisitor { } } - void visitFile(JavaContext context, File file) { + void visitFile(@NonNull JavaContext context, @NonNull File file) { context.parser = mParser; Node compilationUnit = null; @@ -233,20 +234,22 @@ public class JavaVisitor { public final Detector mDetector; public final JavaScanner mJavaScanner; - public VisitingDetector(Detector detector, JavaScanner javaScanner) { + public VisitingDetector(@NonNull Detector detector, @NonNull JavaScanner javaScanner) { mDetector = detector; mJavaScanner = javaScanner; } + @NonNull public Detector getDetector() { return mDetector; } + @NonNull public JavaScanner getJavaScanner() { return mJavaScanner; } - public void setContext(JavaContext context) { + public void setContext(@NonNull JavaContext context) { mContext = context; // The visitors are one-per-context, so clear them out here and construct @@ -254,6 +257,7 @@ public class JavaVisitor { mVisitor = null; } + @NonNull AstVisitor getVisitor() { if (mVisitor == null) { mVisitor = mDetector.createJavaVisitor(mContext); @@ -1106,7 +1110,7 @@ public class JavaVisitor { } @Override - public boolean visitVariableReference(VariableReference node) { + public boolean visitVariableReference(@NonNull VariableReference node) { if (mVisitResources) { if (node.astIdentifier().getDescription().equals("R") && //$NON-NLS-1$ node.getParent() instanceof Select && @@ -1128,7 +1132,7 @@ public class JavaVisitor { } @Override - public boolean visitMethodInvocation(MethodInvocation node) { + public boolean visitMethodInvocation(@NonNull MethodInvocation node) { if (mVisitMethods) { String methodName = node.astName().getDescription(); List<VisitingDetector> list = mMethodDetectors.get(methodName); diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/Lint.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/Lint.java index ac28b47..e3df54f 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/Lint.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/Lint.java @@ -19,6 +19,8 @@ package com.android.tools.lint.client.api; import static com.android.tools.lint.detector.api.LintConstants.DOT_CLASS; import static com.android.tools.lint.detector.api.LintConstants.DOT_JAVA; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.resources.ResourceFolderType; import com.android.tools.lint.client.api.LintListener.EventType; import com.android.tools.lint.detector.api.Category; @@ -80,8 +82,7 @@ public class Lint { * @param registry The registry containing issues to be checked * @param client the tool wrapping the analyzer, such as an IDE or a CLI */ - public Lint(IssueRegistry registry, LintClient client) { - assert client != null; + public Lint(@NonNull IssueRegistry registry, @NonNull LintClient client) { mRegistry = registry; mClient = new LintClientWrapper(client); } @@ -99,7 +100,7 @@ public class Lint { * @param scope the scope of the analysis; detectors with a wider scope will * not be run. If null, the scope will be inferred from the files. */ - public void analyze(List<File> files, EnumSet<Scope> scope) { + public void analyze(@NonNull List<File> files, @Nullable EnumSet<Scope> scope) { mCanceled = false; mScope = scope; @@ -158,7 +159,7 @@ public class Lint { fireEvent(mCanceled ? EventType.CANCELED : EventType.COMPLETED, null); } - private void computeDetectors(Project project) { + private void computeDetectors(@NonNull Project project) { // Ensure that the current visitor is recomputed mCurrentFolderType = null; mCurrentVisitor = null; @@ -212,12 +213,15 @@ public class Lint { } } - private void registerProjectFile(Map<File, Project> fileToProject, File file, - File projectDir, File rootDir) { + private void registerProjectFile( + @NonNull Map<File, Project> fileToProject, + @NonNull File file, + @NonNull File projectDir, + @NonNull File rootDir) { fileToProject.put(file, mClient.getProject(projectDir, rootDir)); } - private Collection<Project> computeProjects(List<File> files) { + private Collection<Project> computeProjects(@NonNull List<File> files) { // Compute list of projects Map<File, Project> fileToProject = new HashMap<File, Project>(); @@ -310,7 +314,10 @@ public class Lint { return roots; } - private void addProjects(File dir, Map<File, Project> fileToProject, File rootDir) { + private void addProjects( + @NonNull File dir, + @NonNull Map<File, Project> fileToProject, + @NonNull File rootDir) { if (mCanceled) { return; } @@ -329,12 +336,11 @@ public class Lint { } } - private boolean isProjectDir(File dir) { + private boolean isProjectDir(@NonNull File dir) { return new File(dir, ANDROID_MANIFEST_XML).exists(); } - private void checkProject(Project project) { - + private void checkProject(@NonNull Project project) { File projectDir = project.getDir(); Context projectContext = new Context(mClient, project, null, projectDir, mScope); @@ -396,8 +402,7 @@ public class Lint { } } - private void runFileDetectors(Project project, Project main) { - + private void runFileDetectors(@NonNull Project project, @Nullable Project main) { // Look up manifest information (but not for library projects) File manifestFile = new File(project.getDir(), ANDROID_MANIFEST_XML); if (!project.isLibrary() && manifestFile.exists()) { @@ -423,7 +428,7 @@ public class Lint { if (mScope.contains(Scope.ALL_RESOURCE_FILES) || mScope.contains(Scope.RESOURCE_FILE)) { List<Detector> checks = union(mScopeDetectors.get(Scope.RESOURCE_FILE), mScopeDetectors.get(Scope.ALL_RESOURCE_FILES)); - if (checks.size() > 0) { + if (checks != null && checks.size() > 0) { List<ResourceXmlDetector> xmlDetectors = new ArrayList<ResourceXmlDetector>(checks.size()); for (Detector detector : checks) { @@ -452,7 +457,7 @@ public class Lint { if (mScope.contains(Scope.JAVA_FILE) || mScope.contains(Scope.ALL_JAVA_FILES)) { List<Detector> checks = union(mScopeDetectors.get(Scope.JAVA_FILE), mScopeDetectors.get(Scope.ALL_JAVA_FILES)); - if (checks.size() > 0) { + if (checks != null && checks.size() > 0) { List<File> sourceFolders = project.getJavaSourceFolders(); checkJava(project, main, sourceFolders, checks); } @@ -493,24 +498,35 @@ public class Lint { } } - private static List<Detector> union(List<Detector> list1, List<Detector> list2) { - int size = (list1 != null ? list1.size() : 0) + (list2 != null ? list2.size() : 0); - // Use set to pick out unique detectors, since it's possible for there to be overlap, - // e.g. the DuplicateIdDetector registers both a cross-resource issue and a - // single-file issue, so it shows up on both scope lists: - Set<Detector> set = new HashSet<Detector>(size); - if (list1 != null) { - set.addAll(list1); - } - if (list2 != null) { - set.addAll(list2); - } + @Nullable + private static List<Detector> union( + @Nullable List<Detector> list1, + @Nullable List<Detector> list2) { + if (list1 == null) { + return list2; + } else if (list2 == null) { + return list1; + } else { + // Use set to pick out unique detectors, since it's possible for there to be overlap, + // e.g. the DuplicateIdDetector registers both a cross-resource issue and a + // single-file issue, so it shows up on both scope lists: + Set<Detector> set = new HashSet<Detector>(list1.size() + list2.size()); + if (list1 != null) { + set.addAll(list1); + } + if (list2 != null) { + set.addAll(list2); + } - return new ArrayList<Detector>(set); + return new ArrayList<Detector>(set); + } } - private void checkClasses(Project project, Project main, - List<File> binFolders, List<Detector> checks) { + private void checkClasses( + @NonNull Project project, + @Nullable Project main, + @NonNull List<File> binFolders, + @NonNull List<Detector> checks) { if (binFolders.size() == 0) { //mClient.log(null, "Warning: Class-file checks are enabled, but no " + // "output folders found. Does the project need to be built first?"); @@ -557,7 +573,7 @@ public class Lint { } } - private void addClassFiles(File dir, List<File> classFiles) { + private void addClassFiles(@NonNull File dir, @NonNull List<File> classFiles) { // Process the resource folder File[] files = dir.listFiles(); if (files != null && files.length > 0) { @@ -572,8 +588,11 @@ public class Lint { } } - private void checkJava(Project project, Project main, - List<File> sourceFolders, List<Detector> checks) { + private void checkJava( + @NonNull Project project, + @Nullable Project main, + @NonNull List<File> sourceFolders, + @NonNull List<Detector> checks) { IJavaParser javaParser = mClient.getJavaParser(); if (javaParser == null) { mClient.log(null, "No java parser provided to lint: not running Java checks"); @@ -600,7 +619,7 @@ public class Lint { } } - private void gatherJavaFiles(File dir, List<File> result) { + private void gatherJavaFiles(@NonNull File dir, @NonNull List<File> result) { File[] files = dir.listFiles(); if (files != null) { for (File file : files) { @@ -617,7 +636,10 @@ public class Lint { private List<ResourceXmlDetector> mCurrentXmlDetectors; private XmlVisitor mCurrentVisitor; - private XmlVisitor getVisitor(ResourceFolderType type, List<ResourceXmlDetector> checks) { + @Nullable + private XmlVisitor getVisitor( + @NonNull ResourceFolderType type, + @NonNull List<ResourceXmlDetector> checks) { if (type != mCurrentFolderType) { mCurrentFolderType = type; @@ -646,8 +668,11 @@ public class Lint { return mCurrentVisitor; } - private void checkResFolder(Project project, Project main, File res, - List<ResourceXmlDetector> checks) { + private void checkResFolder( + @NonNull Project project, + @Nullable Project main, + @NonNull File res, + @NonNull List<ResourceXmlDetector> checks) { assert res.isDirectory(); File[] resourceDirs = res.listFiles(); if (resourceDirs == null) { @@ -671,8 +696,12 @@ public class Lint { } } - private void checkResourceFolder(Project project, Project main, File dir, - ResourceFolderType type, List<ResourceXmlDetector> checks) { + private void checkResourceFolder( + @NonNull Project project, + @Nullable Project main, + @NonNull File dir, + @NonNull ResourceFolderType type, + @NonNull List<ResourceXmlDetector> checks) { // Process the resource folder File[] xmlFiles = dir.listFiles(); if (xmlFiles != null && xmlFiles.length > 0) { @@ -694,8 +723,11 @@ public class Lint { } /** Checks individual resources */ - private void checkIndividualResources(Project project, Project main, - List<ResourceXmlDetector> xmlDetectors, List<File> files) { + private void checkIndividualResources( + @NonNull Project project, + @Nullable Project main, + @NonNull List<ResourceXmlDetector> xmlDetectors, + @NonNull List<File> files) { for (File file : files) { if (file.isDirectory()) { // Is it a resource folder? @@ -733,7 +765,7 @@ public class Lint { * * @param listener the listener to be added */ - public void addLintListener(LintListener listener) { + public void addLintListener(@NonNull LintListener listener) { if (mListeners == null) { mListeners = new ArrayList<LintListener>(1); } @@ -745,7 +777,7 @@ public class Lint { * * @param listener the listener to be removed */ - public void removeLintListener(LintListener listener) { + public void removeLintListener(@NonNull LintListener listener) { mListeners.remove(listener); if (mListeners.size() == 0) { mListeners = null; @@ -753,7 +785,7 @@ public class Lint { } /** Notifies listeners, if any, that the given event has occurred */ - private void fireEvent(LintListener.EventType type, Context context) { + private void fireEvent(@NonNull LintListener.EventType type, @NonNull Context context) { if (mListeners != null) { for (int i = 0, n = mListeners.size(); i < n; i++) { LintListener listener = mListeners.get(i); @@ -771,15 +803,20 @@ public class Lint { * filtered out warnings. */ private static class LintClientWrapper extends LintClient { - private LintClient mDelegate; + @NonNull + private final LintClient mDelegate; - public LintClientWrapper(LintClient delegate) { + public LintClientWrapper(@NonNull LintClient delegate) { mDelegate = delegate; } @Override - public void report(Context context, Issue issue, Location location, String message, - Object data) { + public void report( + @NonNull Context context, + @NonNull Issue issue, + @Nullable Location location, + @NonNull String message, + @Nullable Object data) { Configuration configuration = context.getConfiguration(); if (!configuration.isEnabled(issue)) { if (issue != IssueRegistry.PARSER_ERROR) { @@ -804,52 +841,62 @@ public class Lint { // Everything else just delegates to the embedding lint client @Override - public Configuration getConfiguration(Project project) { + @NonNull + public Configuration getConfiguration(@NonNull Project project) { return mDelegate.getConfiguration(project); } @Override - public void log(Throwable exception, String format, Object... args) { + public void log(@Nullable Throwable exception, @Nullable String format, + @Nullable Object... args) { mDelegate.log(exception, format, args); } @Override - public String readFile(File file) { + @NonNull + public String readFile(@NonNull File file) { return mDelegate.readFile(file); } @Override - public List<File> getJavaSourceFolders(Project project) { + @NonNull + public List<File> getJavaSourceFolders(@NonNull Project project) { return mDelegate.getJavaSourceFolders(project); } @Override - public List<File> getJavaClassFolders(Project project) { + @NonNull + public List<File> getJavaClassFolders(@NonNull Project project) { return mDelegate.getJavaClassFolders(project); } @Override + @Nullable public IDomParser getDomParser() { return mDelegate.getDomParser(); } @Override + @NonNull public Class<? extends Detector> replaceDetector(Class<? extends Detector> detectorClass) { return mDelegate.replaceDetector(detectorClass); } @Override + @NonNull public SdkInfo getSdkInfo(Project project) { return mDelegate.getSdkInfo(project); } @Override - public Project getProject(File dir, File referenceDir) { + @NonNull + public Project getProject(@NonNull File dir, @NonNull File referenceDir) { return mDelegate.getProject(dir, referenceDir); } @Override + @Nullable public IJavaParser getJavaParser() { return mDelegate.getJavaParser(); } 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 10d21ed..91f6fe5 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 @@ -16,6 +16,8 @@ package com.android.tools.lint.client.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.tools.lint.detector.api.Context; import com.android.tools.lint.detector.api.Detector; import com.android.tools.lint.detector.api.Issue; @@ -58,7 +60,7 @@ public abstract class LintClient { * @param project the project to obtain a configuration for * @return a configuration, never null. */ - public Configuration getConfiguration(Project project) { + public Configuration getConfiguration(@NonNull Project project) { return DefaultConfiguration.create(this, project, null); } @@ -80,30 +82,42 @@ public abstract class LintClient { * error message text. See each detector for details on which * data if any is supplied for a given issue. */ - public abstract void report(Context context, Issue issue, Location location, String message, - Object data); + public abstract void report( + @NonNull Context context, + @NonNull Issue issue, + @Nullable Location location, + @NonNull String message, + @Nullable Object data); /** * Send an exception to the log * * @param exception the exception, possibly null - * @param format the error message using {@link String#format} syntax + * @param format the error message using {@link String#format} syntax, possibly null + * (though in that case the exception should not be null) * @param args any arguments for the format string */ - public abstract void log(Throwable exception, String format, Object... args); + public abstract void log( + @Nullable Throwable exception, + @Nullable String format, + @Nullable Object... args); /** * Returns a {@link IDomParser} to use to parse XML * - * @return a new {@link IDomParser} + * @return a new {@link IDomParser}, or null if this client does not support + * XML analysis */ + @Nullable public abstract IDomParser getDomParser(); /** * Returns a {@link IJavaParser} to use to parse Java * - * @return a new {@link IJavaParser} + * @return a new {@link IJavaParser}, or null if this client does not + * support Java analysis */ + @Nullable public abstract IJavaParser getJavaParser(); /** @@ -114,7 +128,9 @@ public abstract class LintClient { * @param detectorClass the class of the detector to be replaced * @return the new detector class, or just the original detector (not null) */ - public Class<? extends Detector> replaceDetector(Class<? extends Detector> detectorClass) { + @NonNull + public Class<? extends Detector> replaceDetector( + @NonNull Class<? extends Detector> detectorClass) { return detectorClass; } @@ -125,7 +141,8 @@ public abstract class LintClient { * @return the string to return, never null (will be empty if there is an * I/O error) */ - public abstract String readFile(File file); + @NonNull + public abstract String readFile(@NonNull File file); /** * Returns the list of source folders for Java source files @@ -133,7 +150,8 @@ public abstract class LintClient { * @param project the project to look up Java source file locations for * @return a list of source folders to search for .java files */ - public List<File> getJavaSourceFolders(Project project) { + @NonNull + public List<File> getJavaSourceFolders(@NonNull Project project) { return getEclipseClasspath(project, "src", "src", "gen"); //$NON-NLS-1$ //$NON-NLS-2$ } @@ -142,7 +160,8 @@ public abstract class LintClient { * @param project the project to look up class file locations for * @return a list of output folders to search for .class files */ - public List<File> getJavaClassFolders(Project project) { + @NonNull + public List<File> getJavaClassFolders(@NonNull Project project) { return getEclipseClasspath(project, "output", "bin"); //$NON-NLS-1$ //$NON-NLS-2$ } @@ -152,7 +171,8 @@ public abstract class LintClient { * @param project the project to look up an {@link SdkInfo} for * @return an {@link SdkInfo} for the project */ - public SdkInfo getSdkInfo(Project project) { + @NonNull + public SdkInfo getSdkInfo(@NonNull Project project) { // By default no per-platform SDK info return new DefaultSdkInfo(); } @@ -161,8 +181,9 @@ public abstract class LintClient { * Considers the given directory as an Eclipse project and returns either * its source or its output folders depending on the {@code attribute} parameter. */ - private List<File> getEclipseClasspath(Project project, String attribute, - String... fallbackPaths) { + @NonNull + private List<File> getEclipseClasspath(@NonNull Project project, @NonNull String attribute, + @NonNull String... fallbackPaths) { List<File> folders = new ArrayList<File>(); File projectDir = project.getDir(); File classpathFile = new File(projectDir, ".classpath"); //$NON-NLS-1$ @@ -220,7 +241,8 @@ public abstract class LintClient { * @param referenceDir See {@link Project#getReferenceDir()}. * @return a project, never null */ - public Project getProject(File dir, File referenceDir) { + @NonNull + public Project getProject(@NonNull File dir, @NonNull File referenceDir) { if (mDirToProject == null) { mDirToProject = new HashMap<File, Project>(); } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintListener.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintListener.java index d6ead4d..49c54a7 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintListener.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/LintListener.java @@ -16,6 +16,7 @@ package com.android.tools.lint.client.api; +import com.android.annotations.NonNull; import com.android.tools.lint.detector.api.Context; import com.google.common.annotations.Beta; @@ -59,5 +60,5 @@ public interface LintListener { * @param type the type of event that occurred * @param context the context providing additional information */ - public void update(EventType type, Context context); + public void update(@NonNull EventType type, @NonNull Context context); } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/SdkInfo.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/SdkInfo.java index 9da87a8..b16747c 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/SdkInfo.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/SdkInfo.java @@ -16,6 +16,8 @@ package com.android.tools.lint.client.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.google.common.annotations.Beta; /** @@ -35,7 +37,7 @@ public abstract class SdkInfo { * @return true if the child view is a sub view of (or the same class as) * the parent view */ - public boolean isSubViewOf(String parentViewFqcn, String childViewFqcn) { + public boolean isSubViewOf(@NonNull String parentViewFqcn, @NonNull String childViewFqcn) { while (!childViewFqcn.equals("android.view.View")) { //$NON-NLS-1$ if (parentViewFqcn.equals(childViewFqcn)) { return true; @@ -58,7 +60,8 @@ public abstract class SdkInfo { * @param fqcn the fully qualified class name of the view * @return the fully qualified class name of the parent view, or null */ - public abstract String getParentViewClass(String fqcn); + @Nullable + public abstract String getParentViewClass(@NonNull String fqcn); /** * Returns the class name of the parent view, or null if the view is the @@ -69,7 +72,8 @@ public abstract class SdkInfo { * package) * @return the view name of the parent */ - public abstract String getParentViewName(String name); + @Nullable + public abstract String getParentViewName(@NonNull String name); // TODO: Add access to resource resolution here. } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/XmlVisitor.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/XmlVisitor.java index 15fd123..ec6bd6a 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/XmlVisitor.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/XmlVisitor.java @@ -16,6 +16,7 @@ package com.android.tools.lint.client.api; +import com.android.annotations.NonNull; import com.android.tools.lint.detector.api.Detector; import com.android.tools.lint.detector.api.Detector.XmlScanner; import com.android.tools.lint.detector.api.LintUtils; @@ -73,7 +74,7 @@ class XmlVisitor { //<T extends List<Detector> & Detector.XmlScanner> XmlVisitor(IDomParser parser, // T xmlDetectors) { // but it makes client code tricky and ugly. - XmlVisitor(IDomParser parser, List<? extends Detector> xmlDetectors) { + XmlVisitor(@NonNull IDomParser parser, @NonNull List<? extends Detector> xmlDetectors) { mParser = parser; mAllDetectors = xmlDetectors; @@ -117,7 +118,7 @@ class XmlVisitor { } } - void visitFile(XmlContext context, File file) { + void visitFile(@NonNull XmlContext context,@NonNull File file) { assert LintUtils.isXmlFile(file); context.parser = mParser; @@ -160,7 +161,7 @@ class XmlVisitor { } } - private void visitElement(XmlContext context, Element element) { + private void visitElement(@NonNull XmlContext context, @NonNull Element element) { List<Detector.XmlScanner> elementChecks = mElementToCheck.get(element.getTagName()); if (elementChecks != null) { assert elementChecks instanceof RandomAccess; diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Category.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Category.java index 88ceb17..a318fc7 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Category.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Category.java @@ -16,6 +16,8 @@ package com.android.tools.lint.detector.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.google.common.annotations.Beta; /** @@ -39,7 +41,11 @@ public final class Category implements Comparable<Category> { * @param explanation an optional explanation of the category * @param priority a sorting priority, with higher being more important */ - private Category(Category parent, String name, String explanation, int priority) { + private Category( + @Nullable Category parent, + @NonNull String name, + @Nullable String explanation, + int priority) { mParent = parent; mName = name; mExplanation = explanation; @@ -53,7 +59,8 @@ public final class Category implements Comparable<Category> { * @param priority a sorting priority, with higher being more important * @return a new category */ - public static Category create(String name, int priority) { + @NonNull + public static Category create(@NonNull String name, int priority) { return new Category(null, name, null, priority); } @@ -66,7 +73,12 @@ public final class Category implements Comparable<Category> { * @param priority a sorting priority, with higher being more important * @return a new category */ - public static Category create(Category parent, String name, String explanation, int priority) { + @NonNull + public static Category create( + @Nullable Category parent, + @NonNull String name, + @Nullable String explanation, + int priority) { return new Category(parent, name, null, priority); } @@ -113,7 +125,7 @@ public final class Category implements Comparable<Category> { } @Override - public int compareTo(Category other) { + public int compareTo(@NonNull Category other) { if (other.mPriority == mPriority) { if (mParent == other) { return 1; @@ -126,22 +138,30 @@ public final class Category implements Comparable<Category> { /** Issues related to correctness */ public static final Category CORRECTNESS = Category.create("Correctness", 10); + /** Issues related to security */ public static final Category SECURITY = Category.create("Security", 9); + /** Issues related to performance */ public static final Category PERFORMANCE = Category.create("Performance", 8); + /** Issues related to usability */ public static final Category USABILITY = Category.create("Usability", 7); + /** Issues related to accessibility */ public static final Category A11Y = Category.create("Accessibility", 6); + /** Issues related to internationalization */ public static final Category I18N = Category.create("Internationalization", 5); // Sub categories + /** Issues related to icons */ public static final Category ICONS = Category.create(USABILITY, "Icons", null, 7); + /** Issues related to typography */ public static final Category TYPOGRAPHY = Category.create(USABILITY, "Typography", null, 8); + /** Issues related to messages/strings */ public static final Category MESSAGES = Category.create(CORRECTNESS, "Messages", null, 10); } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/ClassContext.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/ClassContext.java index 86534f3..09ef05c 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/ClassContext.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/ClassContext.java @@ -19,6 +19,8 @@ package com.android.tools.lint.detector.api; import static com.android.tools.lint.detector.api.LintConstants.DOT_CLASS; import static com.android.tools.lint.detector.api.LintConstants.DOT_JAVA; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.tools.lint.client.api.LintClient; import com.google.common.annotations.Beta; @@ -63,8 +65,15 @@ public class ClassContext extends Context { * @param bytes the bytecode raw data * @param classNode the bytecode object model */ - public ClassContext(LintClient client, Project project, Project main, File file, - EnumSet<Scope> scope, File binDir, byte[] bytes, ClassNode classNode) { + public ClassContext( + @NonNull LintClient client, + @NonNull Project project, + @Nullable Project main, + @NonNull File file, + @NonNull EnumSet<Scope> scope, + @NonNull File binDir, + @NonNull byte[] bytes, + @NonNull ClassNode classNode) { super(client, project, main, file, scope); mBinDir = binDir; mBytes = bytes; @@ -74,8 +83,9 @@ public class ClassContext extends Context { /** * Returns the raw bytecode data for this class file * - * @return the byte array containing the bytecode data, or null + * @return the byte array containing the bytecode data */ + @NonNull public byte[] getBytecode() { return mBytes; } @@ -85,6 +95,7 @@ public class ClassContext extends Context { * * @return the bytecode object model, never null */ + @NonNull public ClassNode getClassNode() { return mClassNode; } @@ -94,6 +105,7 @@ public class ClassContext extends Context { * * @return the source file, or null */ + @Nullable public File getSourceFile() { if (mSourceFile == null && !mSearchedForSource) { mSearchedForSource = true; @@ -135,6 +147,7 @@ public class ClassContext extends Context { * * @return the source contents, or "" */ + @NonNull public String getSourceContents() { if (mSourceContents == null) { File sourceFile = getSourceFile(); @@ -150,8 +163,6 @@ public class ClassContext extends Context { return mSourceContents; } - - /** * Returns a location for the given source line number in this class file's * source file, if available. @@ -163,6 +174,7 @@ public class ClassContext extends Context { * end * @return a location, never null */ + @NonNull public Location getLocationForLine(int line, String patternStart, String patternEnd) { File sourceFile = getSourceFile(); if (sourceFile != null) { diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Context.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Context.java index db6cca9..0c088d8 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Context.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Context.java @@ -16,6 +16,8 @@ package com.android.tools.lint.detector.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.tools.lint.client.api.Configuration; import com.android.tools.lint.client.api.LintClient; import com.android.tools.lint.client.api.SdkInfo; @@ -48,6 +50,7 @@ public class Context { private final LintClient mClient; /** The project containing the file being checked */ + @NonNull private final Project mProject; /** @@ -80,6 +83,7 @@ public class Context { * Slow-running detectors should check this flag via * {@link AtomicBoolean#get()} and abort if canceled */ + @NonNull public final AtomicBoolean canceled = new AtomicBoolean(); /** Map of properties to share results between detectors */ @@ -97,8 +101,12 @@ public class Context { * @param file the file being checked * @param scope the scope for the lint job */ - public Context(LintClient client, Project project, Project main, File file, - EnumSet<Scope> scope) { + public Context( + @NonNull LintClient client, + @NonNull Project project, + @Nullable Project main, + @NonNull File file, + @NonNull EnumSet<Scope> scope) { this.file = file; mClient = client; @@ -113,6 +121,7 @@ public class Context { * * @return the scope, never null */ + @NonNull public EnumSet<Scope> getScope() { return mScope; } @@ -122,6 +131,7 @@ public class Context { * * @return the configuration, never null */ + @NonNull public Configuration getConfiguration() { return mConfiguration; } @@ -131,6 +141,7 @@ public class Context { * * @return the project, never null */ + @NonNull public Project getProject() { return mProject; } @@ -142,6 +153,7 @@ public class Context { * * @return the main project, never null */ + @NonNull public Project getMainProject() { return mMainProject != null ? mMainProject : mProject; } @@ -151,6 +163,7 @@ public class Context { * * @return the client, never null */ + @NonNull public LintClient getClient() { return mClient; } @@ -163,6 +176,7 @@ public class Context { * * @return the contents of the given file, or null if an error occurs. */ + @Nullable public String getContents() { if (mContents == null) { mContents = mClient.readFile(file); @@ -177,6 +191,7 @@ public class Context { * @param name the name of the property * @return the corresponding value, or null */ + @Nullable public Object getProperty(String name) { if (mProperties == null) { return null; @@ -191,12 +206,17 @@ public class Context { * @param name the name of the property * @param value the corresponding value */ - public void setProperty(String name, Object value) { - if (mProperties == null) { - mProperties = new HashMap<String, Object>(); + public void setProperty(@NonNull String name, @Nullable Object value) { + if (value == null) { + if (mProperties != null) { + mProperties.remove(name); + } + } else { + if (mProperties == null) { + mProperties = new HashMap<String, Object>(); + } + mProperties.put(name, value); } - - mProperties.put(name, value); } /** @@ -204,6 +224,7 @@ public class Context { * * @return the SDK info for the current project, never null */ + @NonNull public SdkInfo getSdkInfo() { if (mSdkInfo == null) { mSdkInfo = mClient.getSdkInfo(mProject); @@ -221,7 +242,7 @@ public class Context { * @param issue the issue to check * @return false if the issue has been disabled */ - public boolean isEnabled(Issue issue) { + public boolean isEnabled(@NonNull Issue issue) { return mConfiguration.isEnabled(issue); } @@ -233,7 +254,11 @@ public class Context { * @param message the message for this warning * @param data any associated data, or null */ - public void report(Issue issue, Location location, String message, Object data) { + public void report( + @NonNull Issue issue, + @Nullable Location location, + @NonNull String message, + @Nullable Object data) { mClient.report(this, issue, location, message, data); } @@ -241,10 +266,13 @@ public class Context { * Send an exception to the log. Convenience wrapper around {@link LintClient#log}. * * @param exception the exception, possibly null - * @param format the error message using {@link String#format} syntax + * @param format the error message using {@link String#format} syntax, possibly null * @param args any arguments for the format string */ - public void log(Throwable exception, String format, Object... args) { + public void log( + @Nullable Throwable exception, + @Nullable String format, + @Nullable Object... args) { mClient.log(exception, format, args); } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Detector.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Detector.java index 674b71a..40fe554 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Detector.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Detector.java @@ -16,6 +16,8 @@ package com.android.tools.lint.detector.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.google.common.annotations.Beta; import org.objectweb.asm.tree.ClassNode; @@ -74,7 +76,8 @@ public abstract class Detector { * @param context the {@link Context} for the file being analyzed * @return a visitor, or null. */ - AstVisitor createJavaVisitor(JavaContext context); + @Nullable + AstVisitor createJavaVisitor(@NonNull JavaContext context); /** * Return the types of AST nodes that the visitor returned from @@ -94,6 +97,7 @@ public abstract class Detector { * * @return the list of applicable node types (AST node classes), or null */ + @Nullable List<Class<? extends lombok.ast.Node>> getApplicableNodeTypes(); /** @@ -115,6 +119,7 @@ public abstract class Detector { * * @return a set of applicable method names, or null. */ + @Nullable List<String> getApplicableMethodNames(); /** @@ -131,7 +136,10 @@ public abstract class Detector { * {@link #createJavaVisitor(JavaContext)}, or null * @param node the {@link MethodInvocation} node for the invoked method */ - void visitMethod(JavaContext context, AstVisitor visitor, MethodInvocation node); + void visitMethod( + @NonNull JavaContext context, + @Nullable AstVisitor visitor, + @NonNull MethodInvocation node); /** * Returns whether this detector cares about Android resource references @@ -160,8 +168,12 @@ public abstract class Detector { * @param name the resource name, such as "main" from * {@code R.layout.main} */ - void visitResourceReference(JavaContext context, AstVisitor visitor, - VariableReference node, String type, String name); + void visitResourceReference( + @NonNull JavaContext context, + @Nullable AstVisitor visitor, + @NonNull VariableReference node, + @NonNull String type, + @NonNull String name); } /** Specialized interface for detectors that scan Java class files */ @@ -173,7 +185,7 @@ public abstract class Detector { * the file * @param classNode the root class node */ - void checkClass(ClassContext context, ClassNode classNode); + void checkClass(@NonNull ClassContext context, @NonNull ClassNode classNode); } /** Specialized interface for detectors that scan XML files */ @@ -184,28 +196,28 @@ public abstract class Detector { * @param context information about the document being analyzed * @param document the document to examine */ - void visitDocument(XmlContext context, Document document); + void visitDocument(@NonNull XmlContext context, @NonNull Document document); /** * Visit the given element. * @param context information about the document being analyzed * @param element the element to examine */ - void visitElement(XmlContext context, Element element); + void visitElement(@NonNull XmlContext context, @NonNull Element element); /** * Visit the given element after its children have been analyzed. * @param context information about the document being analyzed * @param element the element to examine */ - void visitElementAfter(XmlContext context, Element element); + void visitElementAfter(@NonNull XmlContext context, @NonNull Element element); /** * Visit the given attribute. * @param context information about the document being analyzed * @param attribute the attribute node to examine */ - void visitAttribute(XmlContext context, Attr attribute); + void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute); /** * Returns the list of elements that this detector wants to analyze. If non @@ -219,6 +231,7 @@ public abstract class Detector { * {@link XmlScanner#ALL} marker to indicate that every single * element should be analyzed. */ + @Nullable Collection<String> getApplicableElements(); /** @@ -233,6 +246,7 @@ public abstract class Detector { * {@link XmlScanner#ALL} marker to indicate that every single * attribute should be analyzed. */ + @Nullable Collection<String> getApplicableAttributes(); /** @@ -240,7 +254,9 @@ public abstract class Detector { * {@link #getApplicableAttributes()} to indicate that the check should be * invoked on all elements or all attributes */ - public static final List<String> ALL = new ArrayList<String>(0); + @NonNull + public static final List<String> ALL = new ArrayList<String>(0); // NOT Collections.EMPTY! + // We want to distinguish this from just an *empty* list returned by the caller! } /** @@ -251,7 +267,7 @@ public abstract class Detector { * * @param context the context describing the work to be done */ - public void run(Context context) { + public void run(@NonNull Context context) { } /** @@ -261,7 +277,7 @@ public abstract class Detector { * @param file the file in the context to check * @return true if this detector applies to the given context and file */ - public boolean appliesTo(Context context, File file) { + public boolean appliesTo(@NonNull Context context, @NonNull File file) { return false; } @@ -271,7 +287,7 @@ public abstract class Detector { * @param context the context for the check referencing the project, lint * client, etc */ - public void beforeCheckProject(Context context) { + public void beforeCheckProject(@NonNull Context context) { } /** @@ -281,7 +297,7 @@ public abstract class Detector { * @param context the context for the check referencing the project, lint * client, etc */ - public void afterCheckProject(Context context) { + public void afterCheckProject(@NonNull Context context) { } /** @@ -290,7 +306,7 @@ public abstract class Detector { * @param context the context for the check referencing the project, lint * client, etc */ - public void beforeCheckLibraryProject(Context context) { + public void beforeCheckLibraryProject(@NonNull Context context) { } /** @@ -300,7 +316,7 @@ public abstract class Detector { * @param context the context for the check referencing the project, lint * client, etc */ - public void afterCheckLibraryProject(Context context) { + public void afterCheckLibraryProject(@NonNull Context context) { } /** @@ -310,7 +326,7 @@ public abstract class Detector { * @param context the context for the check referencing the file to be * checked, the project, etc. */ - public void beforeCheckFile(Context context) { + public void beforeCheckFile(@NonNull Context context) { } /** @@ -320,7 +336,7 @@ public abstract class Detector { * @param context the context for the check referencing the file to be * checked, the project, etc. */ - public void afterCheckFile(Context context) { + public void afterCheckFile(@NonNull Context context) { } /** @@ -328,12 +344,13 @@ public abstract class Detector { * * @return the expected speed of this detector */ + @NonNull public abstract Speed getSpeed(); // ---- Dummy implementations to make implementing XmlScanner easier: ---- @SuppressWarnings("javadoc") - public void visitDocument(XmlContext context, Document document) { + public void visitDocument(@NonNull XmlContext context, @NonNull Document document) { // This method must be overridden if your detector does // not return something from getApplicableElements or // getApplicableATtributes @@ -341,28 +358,30 @@ public abstract class Detector { } @SuppressWarnings("javadoc") - public void visitElement(XmlContext context, Element element) { + public void visitElement(@NonNull XmlContext context, @NonNull Element element) { // This method must be overridden if your detector returns // tag names from getApplicableElements assert false; } @SuppressWarnings("javadoc") - public void visitElementAfter(XmlContext context, Element element) { + public void visitElementAfter(@NonNull XmlContext context, @NonNull Element element) { } @SuppressWarnings("javadoc") - public void visitAttribute(XmlContext context, Attr attribute) { + public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) { // This method must be overridden if your detector returns // attribute names from getApplicableAttributes assert false; } @SuppressWarnings("javadoc") + @Nullable public Collection<String> getApplicableElements() { return null; } + @Nullable @SuppressWarnings("javadoc") public Collection<String> getApplicableAttributes() { return null; @@ -370,23 +389,24 @@ public abstract class Detector { // ---- Dummy implementations to make implementing JavaScanner easier: ---- - @SuppressWarnings("javadoc") + @Nullable @SuppressWarnings("javadoc") public List<String> getApplicableMethodNames() { return null; } - @SuppressWarnings("javadoc") - public AstVisitor createJavaVisitor(JavaContext context) { + @Nullable @SuppressWarnings("javadoc") + public AstVisitor createJavaVisitor(@NonNull JavaContext context) { return null; } - @SuppressWarnings("javadoc") + @Nullable @SuppressWarnings("javadoc") public List<Class<? extends lombok.ast.Node>> getApplicableNodeTypes() { return null; } @SuppressWarnings("javadoc") - public void visitMethod(JavaContext context, AstVisitor visitor, MethodInvocation node) { + public void visitMethod(@NonNull JavaContext context, @Nullable AstVisitor visitor, + @NonNull MethodInvocation node) { } @SuppressWarnings("javadoc") @@ -395,14 +415,13 @@ public abstract class Detector { } @SuppressWarnings("javadoc") - public void visitResourceReference(JavaContext context, AstVisitor visitor, - VariableReference node, String type, String name) { + public void visitResourceReference(@NonNull JavaContext context, @Nullable AstVisitor visitor, + @NonNull VariableReference node, @NonNull String type, @NonNull String name) { } // ---- Dummy implementations to make implementing a ClassScanner easier: ---- @SuppressWarnings("javadoc") - public void checkClass(ClassContext context, ClassNode classNode) { - + public void checkClass(@NonNull ClassContext context, @NonNull ClassNode classNode) { } } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Issue.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Issue.java index fd1ae3d..3e49bc4 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Issue.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Issue.java @@ -16,6 +16,8 @@ package com.android.tools.lint.detector.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.tools.lint.client.api.Configuration; import com.google.common.annotations.Beta; @@ -48,9 +50,15 @@ public final class Issue implements Comparable<Issue> { private final Class<? extends Detector> mClass; // Use factory methods - private Issue(String id, String description, String explanation, Category category, - int priority, Severity severity, Class<? extends Detector> detectorClass, - EnumSet<Scope> scope) { + private Issue( + @NonNull String id, + @NonNull String description, + @NonNull String explanation, + @NonNull Category category, + int priority, + @NonNull Severity severity, + @NonNull Class<? extends Detector> detectorClass, + @NonNull EnumSet<Scope> scope) { super(); mId = id; mDescription = description; @@ -77,9 +85,16 @@ public final class Issue implements Comparable<Issue> { * @param scope the scope of files required to analyze this issue * @return a new {@link Issue} */ - public static Issue create(String id, String description, String explanation, - Category category, int priority, Severity severity, - Class<? extends Detector> detectorClass, EnumSet<Scope> scope) { + @NonNull + public static Issue create( + @NonNull String id, + @NonNull String description, + @NonNull String explanation, + @NonNull Category category, + int priority, + @NonNull Severity severity, + @NonNull Class<? extends Detector> detectorClass, + @NonNull EnumSet<Scope> scope) { return new Issue(id, description, explanation, category, priority, severity, detectorClass, scope); } @@ -91,6 +106,7 @@ public final class Issue implements Comparable<Issue> { * * @return the associated fixed id, never null and always unique */ + @NonNull public String getId() { return mId; } @@ -100,6 +116,7 @@ public final class Issue implements Comparable<Issue> { * * @return a quick summary of the issue, never null */ + @NonNull public String getDescription() { return mDescription; } @@ -112,15 +129,17 @@ public final class Issue implements Comparable<Issue> { * * @return an explanation of the issue, never null. */ + @NonNull public String getExplanation() { return mExplanation; } /** - * The category, or null if no category has been assigned + * The primary category of the issue * - * @return the category, or null if no category has been assigned + * @return the primary category of the issue, never null */ + @NonNull public Category getCategory() { return mCategory; } @@ -150,6 +169,7 @@ public final class Issue implements Comparable<Issue> { * * @return the severity of the issues found by this detector */ + @NonNull public Severity getDefaultSeverity() { return mSeverity; } @@ -159,6 +179,7 @@ public final class Issue implements Comparable<Issue> { * * @return a link to more information, or null */ + @Nullable public String getMoreInfo() { return mMoreInfoUrl; } @@ -179,6 +200,7 @@ public final class Issue implements Comparable<Issue> { * * @return the required scope */ + @NonNull public EnumSet<Scope> getScope() { return mScope; } @@ -193,7 +215,7 @@ public final class Issue implements Comparable<Issue> { * @param other the {@link Issue} to compare this issue to */ @Override - public int compareTo(Issue other) { + public int compareTo(@NonNull Issue other) { return getId().compareTo(other.getId()); } @@ -203,7 +225,8 @@ public final class Issue implements Comparable<Issue> { * @param moreInfoUrl url string * @return this, for constructor chaining */ - public Issue setMoreInfo(String moreInfoUrl) { + @NonNull + public Issue setMoreInfo(@NonNull String moreInfoUrl) { mMoreInfoUrl = moreInfoUrl; return this; } @@ -214,6 +237,7 @@ public final class Issue implements Comparable<Issue> { * @param enabledByDefault whether the issue should be enabled by default * @return this, for constructor chaining */ + @NonNull public Issue setEnabledByDefault(boolean enabledByDefault) { mEnabledByDefault = enabledByDefault; return this; @@ -224,6 +248,7 @@ public final class Issue implements Comparable<Issue> { * * @return the class of the detector to use to find this issue */ + @NonNull public Class<? extends Detector> getDetectorClass() { return mClass; } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/JavaContext.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/JavaContext.java index 2d360d2..b14b4ab 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/JavaContext.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/JavaContext.java @@ -16,6 +16,8 @@ package com.android.tools.lint.detector.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.tools.lint.client.api.IJavaParser; import com.android.tools.lint.client.api.LintClient; @@ -50,8 +52,12 @@ public class JavaContext extends Context { * @param file the file to be analyzed * @param scope the scope used for analysis */ - public JavaContext(LintClient client, Project project, Project main, File file, - EnumSet<Scope> scope) { + public JavaContext( + @NonNull LintClient client, + @NonNull Project project, + @Nullable Project main, + @NonNull File file, + @NonNull EnumSet<Scope> scope) { super(client, project, main, file, scope); } @@ -61,7 +67,8 @@ public class JavaContext extends Context { * @param node the AST node to get a location for * @return a location for the given node */ - public Location getLocation(Node node) { + @NonNull + public Location getLocation(@NonNull Node node) { if (parser != null) { return parser.getLocation(this, node); } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LayoutDetector.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LayoutDetector.java index c74b92a..c61d7c2 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LayoutDetector.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LayoutDetector.java @@ -27,6 +27,7 @@ import static com.android.tools.lint.detector.api.LintConstants.ATTR_PADDING_TOP import static com.android.tools.lint.detector.api.LintConstants.VALUE_FILL_PARENT; import static com.android.tools.lint.detector.api.LintConstants.VALUE_MATCH_PARENT; +import com.android.annotations.NonNull; import com.android.resources.ResourceFolderType; import com.google.common.annotations.Beta; @@ -42,24 +43,24 @@ import org.w3c.dom.Element; @Beta public abstract class LayoutDetector extends ResourceXmlDetector { @Override - public boolean appliesTo(ResourceFolderType folderType) { + public boolean appliesTo(@NonNull ResourceFolderType folderType) { return folderType == ResourceFolderType.LAYOUT; } - private static boolean isFillParent(Element element, String dimension) { + private static boolean isFillParent(@NonNull Element element, @NonNull String dimension) { String width = element.getAttributeNS(ANDROID_URI, dimension); return width.equals(VALUE_MATCH_PARENT) || width.equals(VALUE_FILL_PARENT); } - protected static boolean isWidthFillParent(Element element) { + protected static boolean isWidthFillParent(@NonNull Element element) { return isFillParent(element, ATTR_LAYOUT_WIDTH); } - protected static boolean isHeightFillParent(Element element) { + protected static boolean isHeightFillParent(@NonNull Element element) { return isFillParent(element, ATTR_LAYOUT_HEIGHT); } - protected boolean hasPadding(Element root) { + protected boolean hasPadding(@NonNull Element root) { return root.hasAttributeNS(ANDROID_URI, ATTR_PADDING) || root.hasAttributeNS(ANDROID_URI, ATTR_PADDING_LEFT) || root.hasAttributeNS(ANDROID_URI, ATTR_PADDING_RIGHT) diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java index f6cfcba..69cb591 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java @@ -20,6 +20,8 @@ import static com.android.tools.lint.detector.api.LintConstants.DOT_XML; import static com.android.tools.lint.detector.api.LintConstants.ID_RESOURCE_PREFIX; import static com.android.tools.lint.detector.api.LintConstants.NEW_ID_RESOURCE_PREFIX; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.resources.FolderTypeRelationship; import com.android.resources.ResourceFolderType; import com.android.resources.ResourceType; @@ -50,7 +52,8 @@ public class LintUtils { * @param maxItems the maximum number of items to print * @return a comma separated list */ - public static String formatList(List<String> strings, int maxItems) { + @NonNull + public static String formatList(@NonNull List<String> strings, int maxItems) { StringBuilder sb = new StringBuilder(20 * strings.size()); for (int i = 0, n = strings.size(); i < n; i++) { @@ -75,7 +78,7 @@ public class LintUtils { * @param type the resource type to check * @return true if the given type corresponds to a file-type resource */ - public static boolean isFileBasedResourceType(ResourceType type) { + public static boolean isFileBasedResourceType(@NonNull ResourceType type) { List<ResourceFolderType> folderTypes = FolderTypeRelationship.getRelatedFolders(type); for (ResourceFolderType folderType : folderTypes) { if (folderType != ResourceFolderType.VALUES) { @@ -94,7 +97,7 @@ public class LintUtils { * @param file the file to be checked * @return true if the given file is an xml file */ - public static boolean isXmlFile(File file) { + public static boolean isXmlFile(@NonNull File file) { String string = file.getName(); return string.regionMatches(true, string.length() - DOT_XML.length(), DOT_XML, 0, DOT_XML.length()); @@ -109,7 +112,7 @@ public class LintUtils { * @return true if {@code string} ends with {@code suffix}, * case-insensitively. */ - public static boolean endsWith(String string, String suffix) { + public static boolean endsWith(@NonNull String string, @NonNull String suffix) { return string.regionMatches(true /* ignoreCase */, string.length() - suffix.length(), suffix, 0, suffix.length()); } @@ -120,7 +123,7 @@ public class LintUtils { * @param fileName the file name to extract the basename from * @return the basename (the filename without the file extension) */ - public static String getBaseName(String fileName) { + public static String getBaseName(@NonNull String fileName) { int extension = fileName.indexOf('.'); if (extension > 0) { return fileName.substring(0, extension); @@ -135,7 +138,8 @@ public class LintUtils { * @param node the parent node * @return a list of element children, never null */ - public static List<Element> getChildren(Node node) { + @NonNull + public static List<Element> getChildren(@NonNull Node node) { NodeList childNodes = node.getChildNodes(); List<Element> children = new ArrayList<Element>(childNodes.getLength()); for (int i = 0, n = childNodes.getLength(); i < n; i++) { @@ -154,7 +158,7 @@ public class LintUtils { * @param node the parent node * @return the count of element children */ - public static int getChildCount(Node node) { + public static int getChildCount(@NonNull Node node) { NodeList childNodes = node.getChildNodes(); int childCount = 0; for (int i = 0, n = childNodes.getLength(); i < n; i++) { @@ -173,7 +177,8 @@ public class LintUtils { * @param id the id to strip * @return the stripped id, never null */ - public static String stripIdPrefix(String id) { + @NonNull + public static String stripIdPrefix(@Nullable String id) { if (id == null) { return ""; } else if (id.startsWith(NEW_ID_RESOURCE_PREFIX)) { @@ -196,7 +201,7 @@ public class LintUtils { * @param t the second string to compare * @return the edit distance between the two strings */ - public static int editDistance(String s, String t) { + public static int editDistance(@NonNull String s, @NonNull String t) { int m = s.length(); int n = t.length(); int[][] d = new int[m + 1][n + 1]; diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Location.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Location.java index da79244..4cac0ff 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Location.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Location.java @@ -16,6 +16,8 @@ package com.android.tools.lint.detector.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.google.common.annotations.Beta; import java.io.File; @@ -46,10 +48,10 @@ public class Location { * @param file the associated file (but see the documentation for * {@link #getFile()} for more information on what the file * represents) - * @param start the starting position, never null + * @param start the starting position, or null * @param end the ending position, or null */ - protected Location(File file, Position start, Position end) { + protected Location(@NonNull File file, @Nullable Position start, @Nullable Position end) { super(); this.mFile = file; this.mStart = start; @@ -66,6 +68,7 @@ public class Location { * * @return the file handle for the location */ + @NonNull public File getFile() { return mFile; } @@ -73,8 +76,9 @@ public class Location { /** * The start position of the range * - * @return the start position of the range, never null + * @return the start position of the range, or null */ + @Nullable public Position getStart() { return mStart; } @@ -84,6 +88,7 @@ public class Location { * * @return the start position of the range, may be null for an empty range */ + @Nullable public Position getEnd() { return mEnd; } @@ -94,6 +99,7 @@ public class Location { * * @return a secondary location or null */ + @Nullable public Location getSecondary() { return mSecondary; } @@ -103,7 +109,7 @@ public class Location { * * @param secondary a secondary location associated with this location */ - public void setSecondary(Location secondary) { + public void setSecondary(@NonNull Location secondary) { this.mSecondary = secondary; } @@ -117,7 +123,7 @@ public class Location { * * @param message the message to apply to this location */ - public void setMessage(String message) { + public void setMessage(@NonNull String message) { mMessage = message; } @@ -132,6 +138,7 @@ public class Location { * * @return the custom message for this location, or null */ + @Nullable public String getMessage() { return mMessage; } @@ -142,7 +149,8 @@ public class Location { * @param file the file to create a location for * @return a new location */ - public static Location create(File file) { + @NonNull + public static Location create(@NonNull File file) { return new Location(file, null /*start*/, null /*end*/); } @@ -155,7 +163,11 @@ public class Location { * @param end the ending position * @return a new location */ - public static Location create(File file, Position start, Position end) { + @NonNull + public static Location create( + @NonNull File file, + @NonNull Position start, + @NonNull Position end) { return new Location(file, start, end); } @@ -169,7 +181,12 @@ public class Location { * @param endOffset the ending offset * @return a new location */ - public static Location create(File file, String contents, int startOffset, int endOffset) { + @NonNull + public static Location create( + @NonNull File file, + @Nullable String contents, + int startOffset, + int endOffset) { if (startOffset < 0 || endOffset < startOffset) { throw new IllegalArgumentException("Invalid offsets"); } @@ -212,7 +229,8 @@ public class Location { * @param line the line number (0-based) for the position * @return a new location */ - public static Location create(File file, String contents, int line) { + @NonNull + public static Location create(@NonNull File file, @NonNull String contents, int line) { return create(file, contents, line, null, null); } @@ -231,8 +249,9 @@ public class Location { * the pattern * @return a new location */ - public static Location create(File file, String contents, int line, - String patternStart, String patternEnd) { + @NonNull + public static Location create(@NonNull File file, @NonNull String contents, int line, + @Nullable String patternStart, @Nullable String patternEnd) { int currentLine = 0; int offset = 0; while (currentLine < line) { @@ -284,6 +303,7 @@ public class Location { * * @return create a location for this handle */ + @NonNull Location resolve(); } @@ -301,7 +321,7 @@ public class Location { * @param startOffset the start offset within the file * @param endOffset the end offset within the file */ - public DefaultLocationHandle(Context context, int startOffset, int endOffset) { + public DefaultLocationHandle(@NonNull Context context, int startOffset, int endOffset) { mFile = context.file; mContents = context.getContents(); mStartOffset = startOffset; @@ -309,6 +329,7 @@ public class Location { } @Override + @NonNull public Location resolve() { return Location.create(mFile, mContents, mStartOffset, mEndOffset); } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java index 7303462..32ac071 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java @@ -26,6 +26,8 @@ import static com.android.tools.lint.detector.api.LintConstants.PROJECT_PROPERTI import static com.android.tools.lint.detector.api.LintConstants.TAG_USES_SDK; import static com.android.tools.lint.detector.api.LintConstants.VALUE_TRUE; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.tools.lint.client.api.Configuration; import com.android.tools.lint.client.api.LintClient; import com.google.common.annotations.Beta; @@ -81,12 +83,19 @@ public class Project { * @param referenceDir See {@link #getReferenceDir()}. * @return a new {@link Project} */ - public static Project create(LintClient client, File dir, File referenceDir) { + @NonNull + public static Project create( + @NonNull LintClient client, + @NonNull File dir, + @NonNull File referenceDir) { return new Project(client, dir, referenceDir); } /** Creates a new Project. Use one of the factory methods to create. */ - private Project(LintClient client, File dir, File referenceDir) { + private Project( + @NonNull LintClient client, + @NonNull File dir, + @NonNull File referenceDir) { mClient = client; mDir = dir; mReferenceDir = referenceDir; @@ -161,7 +170,7 @@ public class Project { } @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { if (this == obj) return true; if (obj == null) @@ -183,7 +192,7 @@ public class Project { * * @param file the file to be checked */ - public void addFile(File file) { + public void addFile(@NonNull File file) { if (mFiles == null) { mFiles = new ArrayList<File>(); } @@ -196,6 +205,7 @@ public class Project { * * @return the subset of files to be checked, or null for the whole project */ + @Nullable public List<File> getSubset() { return mFiles; } @@ -205,6 +215,7 @@ public class Project { * * @return a list of source folders to search for .java files */ + @NonNull public List<File> getJavaSourceFolders() { if (mJavaSourceFolders == null) { mJavaSourceFolders = mClient.getJavaSourceFolders(this); @@ -217,6 +228,7 @@ public class Project { * Returns the list of output folders for class files * @return a list of output folders to search for .class files */ + @NonNull public List<File> getJavaClassFolders() { if (mJavaClassFolders == null) { mJavaClassFolders = mClient.getJavaClassFolders(this); @@ -232,7 +244,8 @@ public class Project { * @param file the file under this project to check * @return the path relative to the reference directory (often the project directory) */ - public String getDisplayPath(File file) { + @NonNull + public String getDisplayPath(@NonNull File file) { String path = file.getPath(); String referencePath = mReferenceDir.getPath(); if (path.startsWith(referencePath)) { @@ -253,7 +266,8 @@ public class Project { * @param file the file under this project to check * @return the path relative to the project */ - public String getRelativePath(File file) { + @NonNull + public String getRelativePath(@NonNull File file) { String path = file.getPath(); String referencePath = mDir.getPath(); if (path.startsWith(referencePath)) { @@ -273,6 +287,7 @@ public class Project { * * @return the dir */ + @NonNull public File getDir() { return mDir; } @@ -286,6 +301,7 @@ public class Project { * * @return the reference directory, never null */ + @NonNull public File getReferenceDir() { return mReferenceDir; } @@ -295,6 +311,7 @@ public class Project { * * @return the configuration associated with this project */ + @NonNull public Configuration getConfiguration() { if (mConfiguration == null) { mConfiguration = mClient.getConfiguration(this); @@ -307,6 +324,7 @@ public class Project { * * @return the application package, or null if unknown */ + @Nullable public String getPackage() { //assert !mLibrary; // Should call getPackage on the master project, not the library // Assertion disabled because you might be running lint on a standalone library project. @@ -345,7 +363,7 @@ public class Project { * * @param document the DOM document for the manifest XML document */ - public void readManifest(Document document) { + public void readManifest(@NonNull Document document) { assert !mLibrary; // Should call readManifest on the master project, not the library Element root = document.getDocumentElement(); if (root == null) { @@ -403,6 +421,7 @@ public class Project { * @return the list of library projects referenced by this project, never * null */ + @NonNull public List<Project> getDirectLibraries() { return mDirectLibraries; } @@ -412,6 +431,7 @@ public class Project { * * @return the transitive closure of the library projects for this project */ + @NonNull public List<Project> getAllLibraries() { if (mAllLibraries == null) { if (mDirectLibraries.size() == 0) { @@ -432,7 +452,7 @@ public class Project { * * @param collection the collection to add the projects into */ - private void addLibraryProjects(Collection<Project> collection) { + private void addLibraryProjects(@NonNull Collection<Project> collection) { for (Project library : mDirectLibraries) { collection.add(library); // Recurse diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/ResourceXmlDetector.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/ResourceXmlDetector.java index 0c941dd..68685c6 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/ResourceXmlDetector.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/ResourceXmlDetector.java @@ -16,6 +16,7 @@ package com.android.tools.lint.detector.api; +import com.android.annotations.NonNull; import com.android.resources.ResourceFolderType; import com.google.common.annotations.Beta; @@ -32,7 +33,7 @@ import java.io.File; @Beta public abstract class ResourceXmlDetector extends Detector implements Detector.XmlScanner { @Override - public boolean appliesTo(Context context, File file) { + public boolean appliesTo(@NonNull Context context, @NonNull File file) { return LintUtils.isXmlFile(file); } @@ -46,12 +47,12 @@ public abstract class ResourceXmlDetector extends Detector implements Detector.X * @return true if this detector can apply to resources in folders of the * given type */ - public boolean appliesTo(ResourceFolderType folderType) { + public boolean appliesTo(@NonNull ResourceFolderType folderType) { return true; } @Override - public void run(Context context) { + public void run(@NonNull Context context) { // The infrastructure should never call this method on an xml detector since // it will run the various visitors instead assert false; diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Scope.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Scope.java index e095498..5141b16 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Scope.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Scope.java @@ -17,6 +17,7 @@ package com.android.tools.lint.detector.api; import com.google.common.annotations.Beta; +import com.android.annotations.NonNull; import java.util.EnumSet; @@ -87,7 +88,7 @@ public enum Scope { * @param scopes the scope set to check * @return true if the scope set references a single file */ - public static boolean checkSingleFile(EnumSet<Scope> scopes) { + public static boolean checkSingleFile(@NonNull EnumSet<Scope> scopes) { return scopes.size() == 1 && (scopes.contains(JAVA_FILE) || scopes.contains(CLASS_FILE) diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Severity.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Severity.java index 27840de..e2add3a 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Severity.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Severity.java @@ -16,6 +16,7 @@ package com.android.tools.lint.detector.api; +import com.android.annotations.NonNull; import com.google.common.annotations.Beta; /** @@ -50,7 +51,7 @@ public enum Severity { private String mDisplay; - private Severity(String display) { + private Severity(@NonNull String display) { mDisplay = display; } @@ -59,6 +60,7 @@ public enum Severity { * * @return a description of the severity */ + @NonNull public String getDescription() { return mDisplay; } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Speed.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Speed.java index 79de400..8c20a19 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Speed.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/Speed.java @@ -16,6 +16,7 @@ package com.android.tools.lint.detector.api; +import com.android.annotations.NonNull; import com.google.common.annotations.Beta; /** @@ -37,7 +38,7 @@ public enum Speed { private String mDisplayName; - Speed(String displayName) { + Speed(@NonNull String displayName) { mDisplayName = displayName; } @@ -47,6 +48,7 @@ public enum Speed { * * @return the description of the speed to display to the user */ + @NonNull public String getDisplayName() { return mDisplayName; } diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/XmlContext.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/XmlContext.java index c682cc8..cd2ee3a 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/XmlContext.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/XmlContext.java @@ -16,6 +16,8 @@ package com.android.tools.lint.detector.api; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.tools.lint.client.api.IDomParser; import com.android.tools.lint.client.api.LintClient; import com.google.common.annotations.Beta; @@ -51,8 +53,12 @@ public class XmlContext extends Context { * @param file the file being checked * @param scope the scope for the lint job */ - public XmlContext(LintClient client, Project project, Project main, File file, - EnumSet<Scope> scope) { + public XmlContext( + @NonNull LintClient client, + @NonNull Project project, + @Nullable Project main, + @NonNull File file, + @NonNull EnumSet<Scope> scope) { super(client, project, main, file, scope); } @@ -62,7 +68,8 @@ public class XmlContext extends Context { * @param node the node to look up the location for * @return the location for the node */ - public Location getLocation(Node node) { + @NonNull + public Location getLocation(@NonNull Node node) { if (parser != null) { return parser.getLocation(this, node); } |