aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2013-01-15 11:56:36 -0800
committerTor Norbye <tnorbye@google.com>2013-01-22 09:54:43 -0800
commitb12a5138665cffe63bf1251e3edb4e5eca2c4409 (patch)
tree51a0fa1831061eacc1460963705abf18067f07c9
parent8856a5c1a60a5c904dc06df920de5729e6bfd620 (diff)
downloadsdk-b12a5138665cffe63bf1251e3edb4e5eca2c4409.zip
sdk-b12a5138665cffe63bf1251e3edb4e5eca2c4409.tar.gz
sdk-b12a5138665cffe63bf1251e3edb4e5eca2c4409.tar.bz2
Fix other file visitor to handle incremental analysis properly
The other file visitor would unconditionally scan the full project contents for each scope, even when project.getSubset() (used for incremental analysis in IDEs) was non null. Also avoid NPE when lint is scanning a java file without a package declaration. Change-Id: I74e813b41c2e32acac879b277dc974619156adbd
-rw-r--r--lint/libs/lint_api/src/main/java/com/android/tools/lint/client/api/OtherFileVisitor.java117
-rw-r--r--lint/libs/lint_api/src/main/java/com/android/tools/lint/detector/api/Issue.java1
-rw-r--r--lint/libs/lint_checks/src/main/java/com/android/tools/lint/checks/OverdrawDetector.java8
3 files changed, 99 insertions, 27 deletions
diff --git a/lint/libs/lint_api/src/main/java/com/android/tools/lint/client/api/OtherFileVisitor.java b/lint/libs/lint_api/src/main/java/com/android/tools/lint/client/api/OtherFileVisitor.java
index adc36de..573d4f0 100644
--- a/lint/libs/lint_api/src/main/java/com/android/tools/lint/client/api/OtherFileVisitor.java
+++ b/lint/libs/lint_api/src/main/java/com/android/tools/lint/client/api/OtherFileVisitor.java
@@ -15,19 +15,29 @@
*/
package com.android.tools.lint.client.api;
+import static com.android.SdkConstants.ANDROID_MANIFEST_XML;
+import static com.android.SdkConstants.DOT_CLASS;
+import static com.android.SdkConstants.DOT_JAVA;
+import static com.android.SdkConstants.DOT_XML;
+import static com.android.SdkConstants.FD_ASSETS;
+import static com.android.tools.lint.detector.api.Detector.OtherFileScanner;
+
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.Project;
import com.android.tools.lint.detector.api.Scope;
+import com.android.utils.SdkUtils;
import com.google.common.collect.Lists;
import java.io.File;
-import java.util.*;
-
-import static com.android.SdkConstants.FD_ASSETS;
-import static com.android.tools.lint.detector.api.Detector.OtherFileScanner;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
/**
* Visitor for "other" files: files that aren't java sources,
@@ -64,40 +74,95 @@ class OtherFileVisitor {
scopes.addAll(applicable);
}
+ List<File> subset = project.getSubset();
+
if (scopes.contains(Scope.RESOURCE_FILE)) {
- List<File> files = Lists.newArrayListWithExpectedSize(100);
- for (File res : project.getResourceFolders()) {
- collectFiles(files, res);
- }
- File assets = new File(projectFolder, FD_ASSETS);
- if (assets.exists()) {
- collectFiles(files, assets);
- }
- if (!files.isEmpty()) {
- mFiles.put(Scope.RESOURCE_FILE, files);
+ if (subset != null && !subset.isEmpty()) {
+ List<File> files = new ArrayList<File>(subset.size());
+ for (File file : subset) {
+ if (SdkUtils.endsWith(file.getPath(), DOT_XML) &&
+ !file.getName().equals(ANDROID_MANIFEST_XML)) {
+ files.add(file);
+ }
+ }
+ if (!files.isEmpty()) {
+ mFiles.put(Scope.RESOURCE_FILE, files);
+ }
+ } else {
+ List<File> files = Lists.newArrayListWithExpectedSize(100);
+ for (File res : project.getResourceFolders()) {
+ collectFiles(files, res);
+ }
+ File assets = new File(projectFolder, FD_ASSETS);
+ if (assets.exists()) {
+ collectFiles(files, assets);
+ }
+ if (!files.isEmpty()) {
+ mFiles.put(Scope.RESOURCE_FILE, files);
+ }
}
}
if (scopes.contains(Scope.JAVA_FILE)) {
- List<File> files = Lists.newArrayListWithExpectedSize(100);
- for (File srcFolder : project.getJavaSourceFolders()) {
- collectFiles(files, srcFolder);
+ if (subset != null && !subset.isEmpty()) {
+ List<File> files = new ArrayList<File>(subset.size());
+ for (File file : subset) {
+ if (file.getPath().endsWith(DOT_JAVA)) {
+ files.add(file);
+ }
+ }
+ if (!files.isEmpty()) {
+ mFiles.put(Scope.JAVA_FILE, files);
+ }
+ } else {
+ List<File> files = Lists.newArrayListWithExpectedSize(100);
+ for (File srcFolder : project.getJavaSourceFolders()) {
+ collectFiles(files, srcFolder);
+ }
+ if (!files.isEmpty()) {
+ mFiles.put(Scope.JAVA_FILE, files);
+ }
}
- mFiles.put(Scope.JAVA_FILE, files);
}
if (scopes.contains(Scope.CLASS_FILE)) {
- List<File> files = Lists.newArrayListWithExpectedSize(100);
- for (File classFolder : project.getJavaClassFolders()) {
- collectFiles(files, classFolder);
+ if (subset != null && !subset.isEmpty()) {
+ List<File> files = new ArrayList<File>(subset.size());
+ for (File file : subset) {
+ if (file.getPath().endsWith(DOT_CLASS)) {
+ files.add(file);
+ }
+ }
+ if (!files.isEmpty()) {
+ mFiles.put(Scope.CLASS_FILE, files);
+ }
+ } else {
+ List<File> files = Lists.newArrayListWithExpectedSize(100);
+ for (File classFolder : project.getJavaClassFolders()) {
+ collectFiles(files, classFolder);
+ }
+ if (!files.isEmpty()) {
+ mFiles.put(Scope.CLASS_FILE, files);
+ }
}
- mFiles.put(Scope.JAVA_FILE, files);
}
if (scopes.contains(Scope.MANIFEST)) {
- File manifestFile = project.getManifestFile();
- if (manifestFile != null) {
- mFiles.put(Scope.MANIFEST, Collections.<File>singletonList(manifestFile));
+ if (subset != null && !subset.isEmpty()) {
+ List<File> files = new ArrayList<File>(subset.size());
+ for (File file : subset) {
+ if (file.getName().equals(ANDROID_MANIFEST_XML)) {
+ files.add(file);
+ }
+ }
+ if (!files.isEmpty()) {
+ mFiles.put(Scope.MANIFEST, files);
+ }
+ } else {
+ File manifestFile = project.getManifestFile();
+ if (manifestFile != null) {
+ mFiles.put(Scope.MANIFEST, Collections.<File>singletonList(manifestFile));
+ }
}
}
@@ -115,7 +180,7 @@ class OtherFileVisitor {
if (!applicable.isEmpty()) {
for (File file : files) {
Context context = new Context(driver, project, main, file);
- for (Detector detector : mDetectors) {
+ for (Detector detector : applicable) {
detector.beforeCheckFile(context);
detector.run(context);
detector.afterCheckFile(context);
diff --git a/lint/libs/lint_api/src/main/java/com/android/tools/lint/detector/api/Issue.java b/lint/libs/lint_api/src/main/java/com/android/tools/lint/detector/api/Issue.java
index e5856b9..ceca9ca 100644
--- a/lint/libs/lint_api/src/main/java/com/android/tools/lint/detector/api/Issue.java
+++ b/lint/libs/lint_api/src/main/java/com/android/tools/lint/detector/api/Issue.java
@@ -335,6 +335,7 @@ public final class Issue implements Comparable<Issue> {
* @param required the collection of scopes
* @return this, for constructor chaining
*/
+ @NonNull
public Issue setAnalysisScopes(@Nullable List<EnumSet<Scope>> required) {
mAnalysisScopes = required;
diff --git a/lint/libs/lint_checks/src/main/java/com/android/tools/lint/checks/OverdrawDetector.java b/lint/libs/lint_checks/src/main/java/com/android/tools/lint/checks/OverdrawDetector.java
index e73a4b5..6627411 100644
--- a/lint/libs/lint_checks/src/main/java/com/android/tools/lint/checks/OverdrawDetector.java
+++ b/lint/libs/lint_checks/src/main/java/com/android/tools/lint/checks/OverdrawDetector.java
@@ -75,6 +75,7 @@ import lombok.ast.CompilationUnit;
import lombok.ast.Expression;
import lombok.ast.ForwardingAstVisitor;
import lombok.ast.MethodInvocation;
+import lombok.ast.PackageDeclaration;
import lombok.ast.Select;
import lombok.ast.StrictListAccessor;
import lombok.ast.VariableReference;
@@ -497,7 +498,12 @@ public class OverdrawDetector extends LayoutDetector implements Detector.JavaSca
String packageName = "";
if (node.getParent() instanceof CompilationUnit) {
CompilationUnit compilationUnit = (CompilationUnit) node.getParent();
- packageName = compilationUnit.astPackageDeclaration().getPackageName();
+ PackageDeclaration packageDeclaration = compilationUnit.astPackageDeclaration();
+ if (packageDeclaration == null) {
+ // No package declaration: ignore this one
+ return true;
+ }
+ packageName = packageDeclaration.getPackageName();
}
mClassFqn = (!packageName.isEmpty() ? (packageName + '.') : "") + name;