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