aboutsummaryrefslogtreecommitdiffstats
path: root/lint
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2012-01-10 12:31:43 -0800
committerTor Norbye <tnorbye@google.com>2012-01-10 14:39:32 -0800
commitb1283f2cc2dd403fa9f92407d4dfac37eddd520d (patch)
tree8ccbc3cf337c1338494289cea044b5bc4d327e9c /lint
parent37d5a9bbdc2895921cd0f636777efe2d3bad4e5b (diff)
downloadsdk-b1283f2cc2dd403fa9f92407d4dfac37eddd520d.zip
sdk-b1283f2cc2dd403fa9f92407d4dfac37eddd520d.tar.gz
sdk-b1283f2cc2dd403fa9f92407d4dfac37eddd520d.tar.bz2
Add annotations to the Lint API
Change-Id: I6222f3ef2909174d9111dcfc037a2e74ad093acd
Diffstat (limited to 'lint')
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/Configuration.java26
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultConfiguration.java58
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java13
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/IDomParser.java13
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/IJavaParser.java13
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/IssueRegistry.java21
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/JavaVisitor.java16
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/Lint.java155
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/LintClient.java52
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/LintListener.java3
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/SdkInfo.java10
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/XmlVisitor.java7
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/Category.java28
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/ClassContext.java22
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/Context.java50
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/Detector.java81
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/Issue.java45
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/JavaContext.java13
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/LayoutDetector.java11
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintUtils.java23
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/Location.java45
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/Project.java36
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/ResourceXmlDetector.java7
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/Scope.java3
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/Severity.java4
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/Speed.java4
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/XmlContext.java13
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);
}