diff --git a/docgen/pom.xml b/docgen/pom.xml new file mode 100644 index 00000000..17728230 --- /dev/null +++ b/docgen/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + + + error-prone-support + tech.picnic.error-prone-support + 0.3.1-SNAPSHOT + + + docgen + + + Picnic :: Error Prone Support :: Docgen + Docgen. + + + + ${groupId.error-prone} + error_prone_annotations + provided + + + ${groupId.error-prone} + error_prone_check_api + + + ${groupId.error-prone} + error_prone_core + + + com.google.auto.service + auto-service-annotations + provided + + + com.google.auto.value + auto-value-annotations + + + com.google.code.findbugs + jsr305 + provided + + + com.google.guava + guava + + + com.fasterxml.jackson.core + jackson-databind + + + + \ No newline at end of file diff --git a/docgen/src/main/java/tech/picnic/errorprone/plugin/BugPatternData.java b/docgen/src/main/java/tech/picnic/errorprone/plugin/BugPatternData.java new file mode 100644 index 00000000..de3c057a --- /dev/null +++ b/docgen/src/main/java/tech/picnic/errorprone/plugin/BugPatternData.java @@ -0,0 +1,56 @@ +package tech.picnic.errorprone.plugin; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.auto.value.AutoValue; +import com.google.errorprone.BugPattern; +import com.google.errorprone.BugPattern.LinkType; +import com.google.errorprone.BugPattern.SeverityLevel; +import java.util.Arrays; + +@AutoValue +abstract class BugPatternData { + static BugPatternData create(BugPattern annotation, String name) { + return new AutoValue_BugPatternData( + name, + Arrays.toString(annotation.altNames()), + annotation.linkType(), + annotation.link(), + Arrays.toString(annotation.tags()), + annotation.summary(), + annotation.explanation(), + annotation.severity(), + annotation.disableable()); + } + + @JsonProperty + abstract String name(); + + // Should be String[] + @JsonProperty + abstract String altNames(); + + @JsonProperty + abstract LinkType linkType(); + + @JsonProperty + abstract String link(); + + @JsonProperty + // Should be String[] + abstract String tags(); + + @JsonProperty + abstract String summary(); + + @JsonProperty + abstract String explanation(); + + @JsonProperty + abstract SeverityLevel severityLevel(); + + @JsonProperty + abstract boolean disableable(); + + // SuppressionAnnotations? + // DocumentSuppression? +} diff --git a/docgen/src/main/java/tech/picnic/errorprone/plugin/Docgen.java b/docgen/src/main/java/tech/picnic/errorprone/plugin/Docgen.java new file mode 100644 index 00000000..d72df66e --- /dev/null +++ b/docgen/src/main/java/tech/picnic/errorprone/plugin/Docgen.java @@ -0,0 +1,25 @@ +package tech.picnic.errorprone.plugin; + +import com.google.auto.service.AutoService; +import com.sun.source.util.JavacTask; +import com.sun.source.util.Plugin; +import com.sun.tools.javac.api.BasicJavacTask; + +/** + * A variant of {@code com.google.errorprone.refaster.RefasterRuleCompiler} that outputs a {@code + * fully/qualified/Class.refaster} file for each compiled {@code fully.qualified.Class} that + * contains a Refaster template. + */ +@AutoService(Plugin.class) +public final class Docgen implements Plugin { + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void init(JavacTask javacTask, String... args) { + javacTask.addTaskListener( + new DocgenTaskListener(((BasicJavacTask) javacTask).getContext(), args[0])); + } +} diff --git a/docgen/src/main/java/tech/picnic/errorprone/plugin/DocgenTaskListener.java b/docgen/src/main/java/tech/picnic/errorprone/plugin/DocgenTaskListener.java new file mode 100644 index 00000000..225484d2 --- /dev/null +++ b/docgen/src/main/java/tech/picnic/errorprone/plugin/DocgenTaskListener.java @@ -0,0 +1,65 @@ +package tech.picnic.errorprone.plugin; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.google.errorprone.BugPattern; +import com.google.errorprone.util.ASTHelpers; +import com.sun.source.tree.ClassTree; +import com.sun.source.util.TaskEvent; +import com.sun.source.util.TaskEvent.Kind; +import com.sun.source.util.TaskListener; +import com.sun.tools.javac.api.JavacTrees; +import com.sun.tools.javac.main.JavaCompiler; +import com.sun.tools.javac.util.Context; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +/** XXX: Fill in. */ +final class DocgenTaskListener implements TaskListener { + private final Context context; + + private final String basePath; + + private final ObjectMapper mapper = + new ObjectMapper() + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) + .configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); + + DocgenTaskListener(Context context, String path) { + this.context = context; + this.basePath = path.substring(path.indexOf('=') + 1); + } + + @Override + @SuppressWarnings("SystemOut") + public void finished(TaskEvent taskEvent) { + if (taskEvent.getKind() != Kind.ANALYZE || JavaCompiler.instance(context).errorCount() > 0) { + return; + } + + ClassTree tree = JavacTrees.instance(context).getTree(taskEvent.getTypeElement()); + if (tree == null || !isBugPattern(tree)) { + return; + } + + BugPattern annotation = taskEvent.getTypeElement().getAnnotation(BugPattern.class); + BugPatternData bugPatternData = + BugPatternData.create(annotation, taskEvent.getTypeElement().getSimpleName().toString()); + + System.out.println("Analysing: " + taskEvent.getTypeElement().getSimpleName()); + File file = new File(basePath + "/bugpattern-data.jsonl"); + + try (FileWriter fileWriter = new FileWriter(file, true)) { + mapper.writeValue(fileWriter, bugPatternData); + fileWriter.write("\n"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static boolean isBugPattern(ClassTree tree) { + return ASTHelpers.hasDirectAnnotationWithSimpleName(tree, BugPattern.class.getSimpleName()); + } +} diff --git a/docgen/src/main/java/tech/picnic/errorprone/plugin/package-info.java b/docgen/src/main/java/tech/picnic/errorprone/plugin/package-info.java new file mode 100644 index 00000000..4fea2123 --- /dev/null +++ b/docgen/src/main/java/tech/picnic/errorprone/plugin/package-info.java @@ -0,0 +1,4 @@ +/** A Java compiler plugin that XXX: fill in. */ +@com.google.errorprone.annotations.CheckReturnValue +@javax.annotation.ParametersAreNonnullByDefault +package tech.picnic.errorprone.plugin; diff --git a/pom.xml b/pom.xml index 1375394a..89aa2cfe 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,7 @@ + docgen error-prone-contrib refaster-compiler refaster-runner @@ -820,6 +821,11 @@ error_prone_core ${version.error-prone} + + com.google.auto.value + auto-value + ${version.auto-value} + com.google.auto.service auto-service @@ -1299,6 +1305,31 @@ + + docgen + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + ${project.groupId} + docgen + ${project.version} + + + + -Xplugin:Docgen -XdocsOutputDirectory=${project.build.directory} + + + + + + + error-prone-fork