aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2013-07-08 05:50:08 +0200
committerReinier Zwitserloot <reinier@zwitserloot.com>2013-07-08 21:20:20 +0200
commit0d5fea94da2bfb72ea886a7379ad35e124489692 (patch)
tree71924095522c0e00521d85f19e67e4f56d4f80b1 /src/core/lombok/javac
parenta6c1be550fd1911084faaf7f54ae7bbbd5673642 (diff)
downloadlombok-0d5fea94da2bfb72ea886a7379ad35e124489692.tar.gz
lombok-0d5fea94da2bfb72ea886a7379ad35e124489692.tar.bz2
lombok-0d5fea94da2bfb72ea886a7379ad35e124489692.zip
Support for javadoc copying in Getter/Setter generation for javac, as well as updates to all relevant documentation
Diffstat (limited to 'src/core/lombok/javac')
-rw-r--r--src/core/lombok/javac/handlers/HandleGetter.java1
-rw-r--r--src/core/lombok/javac/handlers/HandleSetter.java4
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java91
3 files changed, 95 insertions, 1 deletions
diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java
index 413404c0..51642f86 100644
--- a/src/core/lombok/javac/handlers/HandleGetter.java
+++ b/src/core/lombok/javac/handlers/HandleGetter.java
@@ -253,6 +253,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> {
if (toClearOfMarkers != null) recursiveSetGeneratedBy(toClearOfMarkers, null);
decl.mods.annotations = decl.mods.annotations.appendList(delegates);
+ copyJavadoc(field, decl, CopyJavadoc.GETTER);
return decl;
}
diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java
index 29728eae..282e6c2f 100644
--- a/src/core/lombok/javac/handlers/HandleSetter.java
+++ b/src/core/lombok/javac/handlers/HandleSetter.java
@@ -252,8 +252,10 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> {
annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(chainDots(field, "java", "lang", "Deprecated"), List.<JCExpression>nil()));
}
- return recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType,
+ JCMethodDecl decl = recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType,
methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source);
+ copyJavadoc(field, decl, CopyJavadoc.SETTER);
+ return decl;
}
private static class JCNoType extends Type implements NoType {
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 1784be90..87493e39 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.AccessLevel;
@@ -1163,4 +1164,94 @@ public class JavacHandlerUtil {
// This is somewhat unsafe, but it's better than outright throwing an exception here. Returning null will just cause an exception down the pipeline.
return (JCExpression) in;
}
+
+ private static final Pattern SECTION_FINDER = Pattern.compile("^\\s*\\**\\s*[-*][-*]+\\s*(GETTER|SETTER)\\s*[-*][-*]+\\s*\\**\\s*$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
+
+ private static String stripLinesWithTagFromJavadoc(String javadoc, String regexpFragment) {
+ Pattern p = Pattern.compile("^\\s*\\**\\s*" + regexpFragment + "\\s*\\**\\s*$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
+ Matcher m = p.matcher(javadoc);
+ return m.replaceAll("");
+ }
+
+ private static String[] splitJavadocOnSectionIfPresent(String javadoc, String sectionName) {
+ Matcher m = SECTION_FINDER.matcher(javadoc);
+ int getterSectionHeaderStart = -1;
+ int getterSectionStart = -1;
+ int getterSectionEnd = -1;
+ while (m.find()) {
+ if (m.group(1).equalsIgnoreCase(sectionName)) {
+ getterSectionStart = m.end() + 1;
+ getterSectionHeaderStart = m.start();
+ } else if (getterSectionStart != -1) {
+ getterSectionEnd = m.start();
+ }
+ }
+
+ if (getterSectionStart != -1) {
+ if (getterSectionEnd != -1) {
+ return new String[] {javadoc.substring(getterSectionStart, getterSectionEnd), javadoc.substring(0, getterSectionHeaderStart) + javadoc.substring(getterSectionEnd)};
+ } else {
+ return new String[] {javadoc.substring(getterSectionStart), javadoc.substring(0, getterSectionHeaderStart)};
+ }
+ }
+
+ return null;
+ }
+
+ public static enum CopyJavadoc {
+ VERBATIM, GETTER {
+ @Override public String[] split(String javadoc) {
+ // step 1: Check if there is a 'GETTER' section. If yes, that becomes the new one and we strip that from the original.
+ String[] out = splitJavadocOnSectionIfPresent(javadoc, "GETTER");
+ if (out != null) return out;
+ // failing that, create a copy, but strip @return from the original and @param from the copy.
+ String copy = javadoc;
+ javadoc = stripLinesWithTagFromJavadoc(javadoc, "@returns?\\s+.*");
+ copy = stripLinesWithTagFromJavadoc(copy, "@param(?:eter)?\\s+.*");
+ return new String[] {copy, javadoc};
+ }
+ },
+ SETTER {
+ @Override public String[] split(String javadoc) {
+ // step 1: Check if there is a 'SETTER' section. If yes, that becomes the new one and we strip that from the original.
+ String[] out = splitJavadocOnSectionIfPresent(javadoc, "SETTER");
+ if (out != null) return out;
+ // failing that, create a copy, but strip @param from the original and @return from the copy.
+ String copy = javadoc;
+ javadoc = stripLinesWithTagFromJavadoc(javadoc, "@param(?:eter)?\\s+.*");
+ copy = stripLinesWithTagFromJavadoc(copy, "@returns?\\s+.*");
+ return new String[] {copy, javadoc};
+ }
+ };
+
+ /** Splits the javadoc into the section to be copied (ret[0]) and the section to replace the original with (ret[1]) */
+ public String[] split(String javadoc) {
+ return new String[] {javadoc, javadoc};
+ }
+ }
+
+ /**
+ * Copies javadoc on one node to the other.
+ *
+ * in 'GETTER' copyMode, first a 'GETTER' segment is searched for. If it exists, that will become the javadoc for the 'to' node, and this section is
+ * stripped out of the 'from' node. If no 'GETTER' segment is found, then the entire javadoc is taken minus any {@code @param} lines. any {@code @return} lines
+ * are stripped from 'from'.
+ *
+ * in 'SETTER' mode, stripping works similarly to 'GETTER' mode, except {@code param} are copied and stripped from the original and {@code @return} are skipped.
+ */
+ public static void copyJavadoc(JavacNode from, JCTree to, CopyJavadoc copyMode) {
+ if (copyMode == null) copyMode = CopyJavadoc.VERBATIM;
+ try {
+ JCCompilationUnit cu = ((JCCompilationUnit) from.top().get());
+ if (cu.docComments != null) {
+ String javadoc = cu.docComments.get(from.get());
+
+ if (javadoc != null) {
+ String[] filtered = copyMode.split(javadoc);
+ cu.docComments.put(to, filtered[0]);
+ cu.docComments.put(from.get(), filtered[1]);
+ }
+ }
+ } catch (Exception ignore) {}
+ }
}