Skip to content

Commit

Permalink
Add Android Lint parser
Browse files Browse the repository at this point in the history
  • Loading branch information
panpanini committed Apr 27, 2016
1 parent 8a3d860 commit 05a11ed
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package se.bjurr.violations.lib.parsers;

import static com.google.common.base.Charsets.UTF_8;
import static com.google.common.collect.Lists.newArrayList;
import static se.bjurr.violations.lib.model.SEVERITY.ERROR;
import static se.bjurr.violations.lib.model.SEVERITY.INFO;
import static se.bjurr.violations.lib.model.SEVERITY.WARN;
import static se.bjurr.violations.lib.model.Violation.violationBuilder;
import static se.bjurr.violations.lib.reports.Reporter.ANDROIDLINT;
import static se.bjurr.violations.lib.reports.Reporter.LINT;

import java.io.File;
import java.util.List;

import se.bjurr.violations.lib.model.SEVERITY;
import se.bjurr.violations.lib.model.Violation;

import com.google.common.base.Optional;
import com.google.common.io.Files;

public class AndroidLintParser extends ViolationsParser {

@Override
public List<Violation> parseFile(File file) throws Exception {
String string = Files.toString(file, UTF_8);
List<Violation> violations = newArrayList();
List<String> issues = getChunks(string, "<issue", "</issue>");
for (String issueChunk : issues) {
String location = getChunks(issueChunk, "<location", "/>").get(0); // only ever going to be one location

String filename = getAttribute(location, "file");
Optional<Integer> line = findIntegerAttribute(location, "line");
Optional<Integer> charAttrib = findIntegerAttribute(location, "column");
String severity = getAttribute(issueChunk, "severity");

String id = getAttribute(issueChunk, "id");
String message = getAttribute(issueChunk, "message");
String summary = getAttribute(issueChunk, "summary").trim();
String explanation = getAttribute(issueChunk, "explanation");

String rule = getAttribute(issueChunk, "category");

violations.add(//
violationBuilder()//
.setReporter(ANDROIDLINT)//
.setStartLine(line.or(0))//
.setColumn(charAttrib.orNull())//
.setFile(filename)//
.setSeverity(toSeverity(severity))//
.setRule(rule)//
.setMessage(id + ": " + summary + "\n" + message + "\n" + explanation)//
.build()//
);

}
return violations;
}

public SEVERITY toSeverity(String severity) {
if (severity.equalsIgnoreCase("ERROR")) {
return ERROR;
}
if (severity.equalsIgnoreCase("WARNING")) {
return WARN;
}
return INFO;
}
}
18 changes: 3 additions & 15 deletions src/main/java/se/bjurr/violations/lib/reports/Reporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,7 @@
import java.util.logging.Logger;

import se.bjurr.violations.lib.model.Violation;
import se.bjurr.violations.lib.parsers.CPPCheckParser;
import se.bjurr.violations.lib.parsers.CSSLintParser;
import se.bjurr.violations.lib.parsers.CheckStyleParser;
import se.bjurr.violations.lib.parsers.CppLintParser;
import se.bjurr.violations.lib.parsers.FindbugsParser;
import se.bjurr.violations.lib.parsers.Flake8Parser;
import se.bjurr.violations.lib.parsers.JSHintParser;
import se.bjurr.violations.lib.parsers.LintParser;
import se.bjurr.violations.lib.parsers.PMDParser;
import se.bjurr.violations.lib.parsers.PerlCriticParser;
import se.bjurr.violations.lib.parsers.PiTestParser;
import se.bjurr.violations.lib.parsers.ResharperParser;
import se.bjurr.violations.lib.parsers.ViolationsParser;
import se.bjurr.violations.lib.parsers.XMLLintParser;
import se.bjurr.violations.lib.parsers.*;

public enum Reporter {
CHECKSTYLE(new CheckStyleParser()), //
Expand All @@ -36,7 +23,8 @@ public enum Reporter {
CPPLINT(new CppLintParser()), //
XMLLINT(new XMLLintParser()), //
PERLCRITIC(new PerlCriticParser()), //
PITEST(new PiTestParser());
PITEST(new PiTestParser()), //
ANDROIDLINT(new AndroidLintParser());

private static Logger LOG = Logger.getLogger(Reporter.class.getSimpleName());
private ViolationsParser violationsParser;
Expand Down
70 changes: 70 additions & 0 deletions src/test/java/se/bjurr/violations/lib/AndroidLintTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package se.bjurr.violations.lib;

import org.junit.Test;
import se.bjurr.violations.lib.model.Violation;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static se.bjurr.violations.lib.TestUtils.getRootFolder;
import static se.bjurr.violations.lib.ViolationsReporterApi.violationsReporterApi;
import static se.bjurr.violations.lib.model.SEVERITY.ERROR;
import static se.bjurr.violations.lib.model.SEVERITY.WARN;
import static se.bjurr.violations.lib.model.Violation.violationBuilder;
import static se.bjurr.violations.lib.reports.Reporter.ANDROIDLINT;

/**
* Created by matthew on 27/04/16.
*/
public class AndroidLintTest {



@Test
public void testThatViolationsCanBeParsed() {

String rootFolder = getRootFolder();

List<Violation> actual = violationsReporterApi() //
.withPattern(".*/androidlint/.*\\.xml$") //
.inFolder(rootFolder)
.findAll(ANDROIDLINT) //
.violations();

assertThat(actual) //
.containsExactly(
violationBuilder() //
.setReporter(ANDROIDLINT) //
.setFile("app/src/main/res/layout/fragment_main.xml") //
.setSource(null) //
.setStartLine(10) //
.setEndLine(10) //
.setColumn(9) //
.setRule("Correctness") //
.setMessage("ScrollViewSize: ScrollView size validation\n" +
"This LinearLayout should use `android:layout_height=&quot;wrap_content&quot;`\n" +
"ScrollView children must set their `layout_width` or `layout_height` attributes to `wrap_content` rather than `fill_parent` or `match_parent` in the scrolling dimension") //
.setSeverity(WARN) //
.build(), //
violationBuilder() //
.setReporter(ANDROIDLINT) //
.setFile(".gradle/caches/modules-2/files-2.1/com.squareup.okio/okio/1.4.0/5b72bf48563ea8410e650de14aa33ff69a3e8c35/okio-1.4.0.jar") //
.setSource(null) //
.setStartLine(0) //
.setEndLine(0) //
.setColumn(null) //
.setRule("Correctness") //
.setMessage("InvalidPackage: Package not included in Android\n" +
"Invalid package reference in library; not included in Android: `java.nio.file`. Referenced from `okio.Okio`.\n" +
"This check scans through libraries looking for calls to APIs that are not included in Android.\n" +
" \n" +
" When you create Android projects, the classpath is set up such that you can only access classes in the API packages that are included in Android. However, if you add other projects to your libs/ folder, there is no guarantee that those .jar files were built with an Android specific classpath, and in particular, they could be accessing unsupported APIs such as java.applet.\n" +
" \n" +
" This check scans through library jars and looks for references to API packages that are not included in Android and flags these. This is only an error if your code calls one of the library classes which wind up referencing the unsupported package.") //
.setSeverity(ERROR) //
.build() //
);


}
}
36 changes: 36 additions & 0 deletions src/test/resources/androidlint/lint-results.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<issues format="4" by="lint 25.1.1">

<issue
id="ScrollViewSize"
severity="Warning"
message="This LinearLayout should use `android:layout_height=&quot;wrap_content&quot;`"
category="Correctness"
priority="7"
summary="ScrollView size validation"
explanation="ScrollView children must set their `layout_width` or `layout_height` attributes to `wrap_content` rather than `fill_parent` or `match_parent` in the scrolling dimension"
errorLine1=" android:layout_height=&quot;match_parent&quot;"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
quickfix="studio,adt">
<location
file="app/src/main/res/layout/fragment_main.xml"
line="10"
column="9"/>
</issue>

<issue
id="InvalidPackage"
severity="Error"
message="Invalid package reference in library; not included in Android: `java.nio.file`. Referenced from `okio.Okio`."
category="Correctness"
priority="6"
summary="Package not included in Android"
explanation="This check scans through libraries looking for calls to APIs that are not included in Android.
When you create Android projects, the classpath is set up such that you can only access classes in the API packages that are included in Android. However, if you add other projects to your libs/ folder, there is no guarantee that those .jar files were built with an Android specific classpath, and in particular, they could be accessing unsupported APIs such as java.applet.
This check scans through library jars and looks for references to API packages that are not included in Android and flags these. This is only an error if your code calls one of the library classes which wind up referencing the unsupported package.">
<location
file=".gradle/caches/modules-2/files-2.1/com.squareup.okio/okio/1.4.0/5b72bf48563ea8410e650de14aa33ff69a3e8c35/okio-1.4.0.jar"/>
</issue>
</issues>

0 comments on commit 05a11ed

Please sign in to comment.