Skip to content

Commit

Permalink
OGP taglets
Browse files Browse the repository at this point in the history
  • Loading branch information
btj committed Feb 12, 2020
0 parents commit 80ccc59
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 0 deletions.
10 changes: 10 additions & 0 deletions ogptaglets/.classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-12">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
3 changes: 3 additions & 0 deletions ogptaglets/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/bin/
.DS_Store
/doc/
17 changes: 17 additions & 0 deletions ogptaglets/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ogptaglets</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
14 changes: 14 additions & 0 deletions ogptaglets/.settings/org.eclipse.jdt.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=12
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=12
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=12
22 changes: 22 additions & 0 deletions ogptaglets/src/ogptaglets/InvariantsTaglet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ogptaglets;

import java.util.Set;

public class InvariantsTaglet extends OGPTaglet {

@Override
public Set<Location> getAllowedLocations() {
return Set.of(Location.FIELD, Location.TYPE);
}

@Override
public String getName() {
return "invar";
}

@Override
public String getTitle() {
return "Invariants";
}

}
88 changes: 88 additions & 0 deletions ogptaglets/src/ogptaglets/OGPTaglet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package ogptaglets;

import java.util.List;

import javax.lang.model.element.Element;

import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.UnknownBlockTagTree;

import jdk.javadoc.doclet.Taglet;

public abstract class OGPTaglet implements Taglet {

@Override
public boolean isInlineTag() {
return false;
}

public abstract String getTitle();

public static String renderContent(List<? extends DocTree> contentTrees) {
return renderContent(contentTrees, "<pre style='padding: 16px; background: #f8f8f8'>", "</pre>");
}

public static String renderContent(List<? extends DocTree> contentTrees, String prolog, String epilog) {
StringBuilder contentBuilder = new StringBuilder();
for (DocTree child : contentTrees)
contentBuilder.append(child.toString());
String content = contentBuilder.toString();
int bar = content.indexOf('|');
String informalPart;
String formalPart;
if (0 <= bar) {
informalPart = content.substring(0, bar);
int lineStart = bar + 1;
StringBuilder formalPartBuilder = new StringBuilder();
for (;;) {
if (lineStart < content.length() && content.charAt(lineStart) == ' ')
lineStart++;
int linefeed = content.indexOf('\n', lineStart);
if (linefeed < 0) {
formalPartBuilder.append(content, lineStart, content.length());
break;
}
formalPartBuilder.append(content, lineStart, linefeed + 1);
lineStart = linefeed + 1;
eatWhitespace:
while (lineStart < content.length()) {
switch (content.charAt(lineStart)) {
case ' ':
case '\t':
case '\r':
case '\n':
lineStart++;
break;
case '|':
lineStart++;
break eatWhitespace;
default:
break eatWhitespace;
}
}
}
formalPart = formalPartBuilder.toString();
} else {
informalPart = content;
formalPart = null;
}
String result = informalPart.replace("&", "&amp;").replace("<", "&lt;");
if (formalPart != null)
result += prolog + formalPart.replace("&", "&amp;").replace("<", "&lt;") + epilog;
return result;
}

@Override
public String toString(List<? extends DocTree> tags, Element element) {
StringBuilder builder = new StringBuilder();
builder.append("<dt><span class='throwsLabel'>" + getTitle() + ":</span></dt>");
for (DocTree docTree : tags) {
builder.append("<dd>");
UnknownBlockTagTree tree = (UnknownBlockTagTree)docTree;
builder.append(renderContent(tree.getContent()));
builder.append("</dd>");
}
return builder.toString();
}

}
22 changes: 22 additions & 0 deletions ogptaglets/src/ogptaglets/PostconditionsTaglet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ogptaglets;

import java.util.Set;

public class PostconditionsTaglet extends OGPTaglet {

@Override
public Set<Location> getAllowedLocations() {
return Set.of(Location.CONSTRUCTOR, Location.METHOD);
}

@Override
public String getName() {
return "post";
}

@Override
public String getTitle() {
return "Postconditions";
}

}
22 changes: 22 additions & 0 deletions ogptaglets/src/ogptaglets/PreconditionsTaglet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ogptaglets;

import java.util.Set;

public class PreconditionsTaglet extends OGPTaglet {

@Override
public Set<Location> getAllowedLocations() {
return Set.of(Location.CONSTRUCTOR, Location.METHOD);
}

@Override
public String getName() {
return "pre";
}

@Override
public String getTitle() {
return "Preconditions";
}

}
79 changes: 79 additions & 0 deletions ogptaglets/src/ogptaglets/ThrowsTaglet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package ogptaglets;

import java.util.List;
import java.util.Set;

import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;

import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.ReferenceTree;
import com.sun.source.doctree.ThrowsTree;
import com.sun.source.util.DocTreePath;
import com.sun.source.util.TreePath;

import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment;

public class ThrowsTaglet extends OGPTaglet {

private DocletEnvironment environment;

@Override
public void init(DocletEnvironment environment, Doclet doclet) {
super.init(environment, doclet);
this.environment = environment;
}

@Override
public Set<Location> getAllowedLocations() {
return Set.of(Location.CONSTRUCTOR, Location.METHOD);
}

@Override
public String getName() {
return "throws";
}

@Override
public String getTitle() {
return "Throws";
}

private String referenceToString(Element referringElement, ReferenceTree rt) {
fallback:
{
TreePath referringElementPath = environment.getDocTrees().getPath(referringElement);
if (referringElementPath == null) break fallback;
DocCommentTree commentTree = environment.getDocTrees().getDocCommentTree(referringElement);
if (commentTree == null) break fallback;
DocTreePath referencePath = DocTreePath.getPath(referringElementPath, commentTree, rt);
Element referencedElement = environment.getDocTrees().getElement(referencePath);
if (referencedElement.toString().startsWith("java."))
return "<a href='https://docs.oracle.com/en/java/javase/13/docs/api/java.base/" + referencedElement.toString().replace('.', '/') + ".html'>" + rt.toString() + "</a>";
else {
// Assume the exception type is included in the JavaDoc currently being generated
PackageElement currentPackage = environment.getElementUtils().getPackageOf(referringElement);
String path = (currentPackage.isUnnamed() ? "" : currentPackage.toString().replace('.', '/').replaceAll("\\w+", "..") + "/") + referencedElement.toString().replace('.', '/') + ".html";
return "<a href='" + path + "'>" + rt.toString() + "</a>";
}
}
return rt.toString();
}

@Override
public String toString(List<? extends DocTree> tags, Element element) {
StringBuilder builder = new StringBuilder();
builder.append("<dt><span class='throwsLabel'>" + getTitle() + ":</span></dt>");
for (DocTree docTree : tags) {
builder.append("<dd>");
ThrowsTree tree = (ThrowsTree)docTree;
builder.append("<code>" + referenceToString(element, tree.getExceptionName()) + "</code> - ");
builder.append(renderContent(tree.getDescription()));
builder.append("</dd>");
}
return builder.toString();
}

}

0 comments on commit 80ccc59

Please sign in to comment.