aboutsummaryrefslogtreecommitdiff
path: root/gradle/src/main/groovy/com/android/build/gradle/internal/LintGradleClient.java
diff options
context:
space:
mode:
Diffstat (limited to 'gradle/src/main/groovy/com/android/build/gradle/internal/LintGradleClient.java')
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/LintGradleClient.java119
1 files changed, 116 insertions, 3 deletions
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/LintGradleClient.java b/gradle/src/main/groovy/com/android/build/gradle/internal/LintGradleClient.java
index 6ebb37f..3bf7b8d 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/LintGradleClient.java
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/LintGradleClient.java
@@ -17,24 +17,45 @@
package com.android.build.gradle.internal;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.build.gradle.BasePlugin;
+import com.android.builder.model.AndroidProject;
+import com.android.builder.model.Variant;
import com.android.tools.lint.LintCliClient;
import com.android.tools.lint.LintCliFlags;
+import com.android.tools.lint.Warning;
+import com.android.tools.lint.client.api.IssueRegistry;
+import com.android.tools.lint.client.api.LintRequest;
+import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.Project;
import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
public class LintGradleClient extends LintCliClient {
+ private final AndroidProject mModelProject;
+ private final String mVariantName;
+ private final BasePlugin mPlugin;
private List<File> mCustomRules = Lists.newArrayList();
- private BasePlugin mPlugin;
- public LintGradleClient(@NonNull LintCliFlags flags, @NonNull BasePlugin plugin) {
+ public LintGradleClient(
+ @NonNull IssueRegistry registry,
+ @NonNull LintCliFlags flags,
+ @NonNull BasePlugin plugin,
+ @NonNull AndroidProject modelProject,
+ @Nullable String variantName) {
super(flags);
mPlugin = plugin;
+ mModelProject = modelProject;
+ mVariantName = variantName;
+ mRegistry = registry;
}
@NonNull
@@ -53,7 +74,9 @@ public class LintGradleClient extends LintCliClient {
@Override
protected Project createProject(@NonNull File dir, @NonNull File referenceDir) {
- return new LintGradleProject(this, dir, referenceDir);
+ // Should not be called by lint since we supply an explicit set of projects
+ // to the LintRequest
+ throw new IllegalStateException();
}
@Override
@@ -64,4 +87,94 @@ public class LintGradleClient extends LintCliClient {
}
return super.getSdkHome();
}
+
+ @Override
+ @NonNull
+ protected LintRequest createLintRequest(@NonNull List<File> files) {
+ return new LintGradleRequest(this, mModelProject, mPlugin, mVariantName, files);
+ }
+
+ /** Run lint with the given registry and return the resulting warnings */
+ @NonNull
+ public List<Warning> run(@NonNull IssueRegistry registry) throws IOException {
+ run(registry, Collections.<File>emptyList());
+ return mWarnings;
+ }
+
+ /**
+ * Given a list of results from separate variants, merge them into a single
+ * list of warnings, and mark their
+ * @param warningMap a map from variant to corresponding warnings
+ * @param project the project model
+ * @return a merged list of issues
+ */
+ @NonNull
+ public static List<Warning> merge(
+ @NonNull Map<Variant,List<Warning>> warningMap,
+ @NonNull AndroidProject project) {
+ // Easy merge?
+ if (warningMap.size() == 1) {
+ return warningMap.values().iterator().next();
+ }
+ int maxCount = 0;
+ for (List<Warning> warnings : warningMap.values()) {
+ int size = warnings.size();
+ maxCount = Math.max(size, maxCount);
+ }
+ if (maxCount == 0) {
+ return Collections.emptyList();
+ }
+
+ int totalVariantCount = project.getVariants().size();
+
+ List<Warning> merged = Lists.newArrayListWithExpectedSize(2 * maxCount);
+
+ // Map fro issue to message to line number to file name to canonical warning
+ Map<Issue,Map<String, Map<Integer, Map<String, Warning>>>> map =
+ Maps.newHashMapWithExpectedSize(2 * maxCount);
+
+ for (Map.Entry<Variant,List<Warning>> entry : warningMap.entrySet()) {
+ Variant variant = entry.getKey();
+ List<Warning> warnings = entry.getValue();
+ for (Warning warning : warnings) {
+ Map<String,Map<Integer,Map<String,Warning>>> messageMap = map.get(warning.issue);
+ if (messageMap == null) {
+ messageMap = Maps.newHashMap();
+ map.put(warning.issue, messageMap);
+ }
+ Map<Integer, Map<String, Warning>> lineMap = messageMap.get(warning.message);
+ if (lineMap == null) {
+ lineMap = Maps.newHashMap();
+ messageMap.put(warning.message, lineMap);
+ }
+ Map<String, Warning> fileMap = lineMap.get(warning.line);
+ if (fileMap == null) {
+ fileMap = Maps.newHashMap();
+ lineMap.put(warning.line, fileMap);
+ }
+ String fileName = warning.file != null ? warning.file.getName() : "<unknown>";
+ Warning canonical = fileMap.get(fileName);
+ if (canonical == null) {
+ canonical = warning;
+ fileMap.put(fileName, canonical);
+ canonical.variants = Sets.newHashSet();
+ canonical.gradleProject = project;
+ }
+ merged.add(canonical);
+ canonical.variants.add(variant);
+ }
+ }
+
+ // Clear out variants on any nodes that don't define all
+ for (Warning warning : merged) {
+ if (warning.variants != null && warning.variants.size() == totalVariantCount) {
+ // If this error is present in all variants, just clear it out
+ warning.variants = null;
+ }
+
+ }
+
+ Collections.sort(merged);
+ return merged;
+ }
}