
io.vertx.codegen.doc.Doc Maven / Gradle / Ivy
package io.vertx.codegen.doc;
import io.vertx.codegen.type.TypeMirrorFactory;
import javax.annotation.processing.Messager;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Documention of a program element, the documentation is a composed of a:
*
*
* - a first sentence
* - an optional body
* - a list of block tags
*
*
* @author Julien Viet
*/
public class Doc {
private static final Pattern TAG_START = Pattern.compile("\n\\p{javaWhitespace}*@([^\\p{javaWhitespace}]+)", Pattern.MULTILINE);
private static final Pattern BODY_START = Pattern.compile("\n{2,}");
/**
* Create and returns a doc object for the specified javadoc argument.
*
* @param javadoc the javadoc
* @return the doc object
*/
public static Doc create(String javadoc) {
Matcher matcher = TAG_START.matcher(javadoc);
List blockTags = new ArrayList<>();
String first;
if (matcher.find()) {
first = javadoc.substring(0, matcher.start());
while (true) {
String name = matcher.group(1);
int prev = matcher.end() + 1;
if (matcher.find()) {
blockTags.add(new Tag(name, javadoc.substring(prev, matcher.start())));
} else {
blockTags.add(new Tag(name, javadoc.substring(prev)));
break;
}
}
} else {
first = javadoc;
}
matcher = BODY_START.matcher(first);
String body = null;
if (matcher.find()) {
body = first.substring(matcher.end());
first = first.substring(0, matcher.start());
}
return new Doc(first, body, blockTags);
}
final Text firstSentence;
final Text body;
final List blockTags;
public Doc(Text firstSentence) {
this(firstSentence, null);
}
public Doc(Text firstSentence, Text body) {
this(firstSentence, body, Collections.emptyList());
}
public Doc(Text firstSentence, Text body, List blockTags) {
this.firstSentence = firstSentence;
this.body = body;
this.blockTags = blockTags;
}
public Doc(String firstSentence) {
this(firstSentence, null);
}
public Doc(String firstSentence, String body) {
this(firstSentence, body, Collections.emptyList());
}
public Doc(String firstSentence, String body, List blockTags) {
this.firstSentence = new Text(firstSentence);
this.body = body != null ? new Text(body) : null;
this.blockTags = blockTags;
}
/**
* @return the tokens of this comment
*/
public List getTokens() {
if (body != null) {
ArrayList tokens = new ArrayList<>(firstSentence.tokens.size() + 2 + body.tokens.size());
tokens.addAll(firstSentence.tokens);
tokens.add(new Token.LineBreak("\n"));
tokens.add(new Token.LineBreak("\n"));
tokens.addAll(body.tokens);
return tokens;
} else {
return firstSentence.getTokens();
}
}
public Text getFirstSentence() {
return firstSentence;
}
public Text getBody() {
return body;
}
public List getBlockTags() {
return blockTags;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(firstSentence);
if (body != null) {
sb.append("\n\n").append(body);
}
for (Tag blockTag : blockTags) {
sb.append("\n").append(blockTag);
}
return sb.toString();
}
/**
* Doc factory.
*/
public static class Factory {
private final Messager messager;
private final Elements elementUtils;
private final Types typeUtils;
private final TypeMirrorFactory typeFactory;
private final TypeElement ownerElt;
public Factory(Messager messager, Elements elementUtils, Types typeUtils, TypeMirrorFactory typeFactory, TypeElement ownerElt) {
this.messager = messager;
this.elementUtils = elementUtils;
this.typeUtils = typeUtils;
this.typeFactory = typeFactory;
this.ownerElt = ownerElt;
}
/**
* When the {@code elt} argument has a comment, this comment is parsed and returned as a {@link Doc}
* object.
*
* @param elt the element
* @return the comment object
*/
public Doc createDoc(Element elt) {
String docComment = elementUtils.getDocComment(elt);
if (docComment != null) {
Doc doc = Doc.create(docComment);
// Rewrite the link token with more contextual type info
Function mapper = Token.tagMapper(elementUtils, typeUtils, ownerElt);
//
return new Doc(
doc.getFirstSentence().map(mapper),
doc.getBody() != null ? doc.getBody().map(mapper) : null,
doc.getBlockTags()
);
} else {
return null;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy