Good documentation is essential not only for open source software. It is often a criteria in picking the right library/framework for companies. So documenting your interfaces should be equally prioritised as writting readable code. Javaparser can help you with this task. Not by writing the documentation for us :), but to find undocumented interfaces for instance.
Javaparser lets us define visitors where we can hook up into different parts of our source code, for example into class or interface declarations.
We define two visitors as inner classes. One visits ClassOrInterfaceDeclaration
's and checks for javadoc if it is a public
interface. The other visits methods and checks there for javadoc comments.
private class InterfaceVisitor extends VoidVisitorAdapter<CompilationUnit> {
@Override
public void visit(ClassOrInterfaceDeclaration n, CompilationUnit arg) {
if (n.isInterface()) {
if (n.getModifiers().contains(Modifier.PUBLIC)) {
String packageName = arg.getPackageDeclaration()
.map(NodeWithName::getNameAsString)
.orElse("<default>");
if (!n.getJavadocComment().isPresent()) {
Out.println(packageName + "." + n.getNameAsString() + " at " +
n.getRange().map(Range::toString).orElse("-1/-1") + " misses javadoc!");
}
InterfaceMethodVisitor visitor = new InterfaceMethodVisitor(packageName);
n.accept(visitor, n);
}
}
super.visit(n, arg);
}
}
private class InterfaceMethodVisitor extends VoidVisitorAdapter<ClassOrInterfaceDeclaration> {
private String packageName;
public InterfaceMethodVisitor(String packageName) {
this.packageName = packageName;
}
@Override
public void visit(MethodDeclaration n, ClassOrInterfaceDeclaration arg) {
if (!n.getJavadocComment().isPresent()) {
String signature = packageName + "." + arg.getNameAsString() + "#" + n.getDeclarationAsString();
Out.println(signature + " at " + n.getRange().map(Range::toString).orElse("-1/-1") + " misses javadoc!");
}
super.visit(n, arg);
}
}
The main method looks a bit different this time. I extracted all the parsing and validation code into a new Inspection
class. TEMPLATE
is a TriConsumer (see Consumer, BiConsumer) which takes
care of the argument vector and inner validation.
public class InterfaceDocumentation {
public static void main(String[] args) throws IOException {
Inspection.TEMPLATE.accept(args, /*saveModification*/false,
sourceRoot -> new InterfaceDocumentation().run(sourceRoot.getCompilationUnits()));
}
private void run(List<CompilationUnit> units) {
InterfaceVisitor visitor = new InterfaceVisitor();
units.forEach(unit -> unit.accept(visitor, unit));
}
...
}
Check out the whole javaparser-goodness
project on github.