mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-13 10:15:53 +00:00
Support for javadoc copying in Getter/Setter generation for javac, as well as updates to all relevant documentation
This commit is contained in:
1 parent
a6c1be550f
commit
0d5fea94da
7 files changed
+134
-1
No files matched your search
@@ -2,6 +2,7 @@ Lombok Changelog
|
||||
----------------
|
||||
|
||||
### v0.11.9 (Edgy Guinea Pig)
|
||||
* FEATURE: javadoc on fields will now be copied to generated getters / setters. There are ways to specify separate javadoc for the field, the setter, and the getter, and `@param` and `@return` are handled appropriately. Addresses feature request [Issue #59](https://code.google.com/p/projectlombok/issues/detail?id=59). [@Getter and @Setter documentation](http://projectlombok.org/features/GetterSetter.html).
|
||||
* CHANGE: The desugaring of @Getter(lazy=true) is now less object creation intensive. Documentation has been updated to reflect what the new desugaring looks like. [@Getter(lazy=true) documentation](http://projectlombok.org/features/GetterLazy.html).
|
||||
* PROMOTION: `@Value` has been promoted from experimental to the main package with no changes. The 'old' experimental one is still around but is deprecated, and is an alias for the new main package one. [@Value documentation](http://projectlombok.org/features/Value.html).
|
||||
* FEATURE: {Experimental} `@Builder` support. One of our earliest feature request issues, [Issue #16](https://code.google.com/p/projectlombok/issues/detail?id=16), has finally been addressed. [@Builder documentation](http://projectlombok.org/features/experimental/Builder.html).
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,41 @@
|
||||
public class GetterSetterExample {
|
||||
/**
|
||||
* Age of the person. Water is wet.
|
||||
*/
|
||||
private int age = 10;
|
||||
|
||||
/**
|
||||
* Name of the person.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
@Override public String toString() {
|
||||
return String.format("%s (age: %d)", name, age);
|
||||
}
|
||||
|
||||
/**
|
||||
* Age of the person. Water is wet.
|
||||
*
|
||||
* @return The current value of this person's age. Circles are round.
|
||||
*/
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
/**
|
||||
* Age of the person. Water is wet.
|
||||
*
|
||||
* @param age New value for this person's age. Sky is blue.
|
||||
*/
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the name of this person.
|
||||
*
|
||||
* @param name The new value.
|
||||
*/
|
||||
protected void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,21 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class GetterSetterExample {
|
||||
/**
|
||||
* Age of the person. Water is wet.
|
||||
*
|
||||
* @param age New value for this person's age. Sky is blue.
|
||||
* @return The current value of this person's age. Circles are round.
|
||||
*/
|
||||
@Getter @Setter private int age = 10;
|
||||
|
||||
/**
|
||||
* Name of the person.
|
||||
* -- SETTER --
|
||||
* Changes the name of this person.
|
||||
*
|
||||
* @param name The new value.
|
||||
*/
|
||||
@Setter(AccessLevel.PROTECTED) private String name;
|
||||
|
||||
@Override public String toString() {
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
behaviour of a <code>@Getter</code>, <code>@Setter</code> or <code>@Data</code> annotation on a class.
|
||||
</p><p>
|
||||
To put annotations on the generated method, you can use <code>onMethod=@_({@AnnotationsHere})</code>; to put annotations on the only parameter of a generated setter method, you can use <code>onParam=@_({@AnnotationsHere})</code>. Be careful though! This is an experimental feature. For more details see the documentation on the <a href="experimental/onX.html">onX</a> feature.
|
||||
</p><p>
|
||||
<em>NEW in lombok v1.12.0:</em> javadoc on the field will now be copied to generated getters and setters. Normally, all text is copied, and <code>@return</code> is <em>moved</em> to the getter, whilst <code>@param</code> lines are <em>moved</em> to the setter. Moved means: Deleted from the field's javadoc. It is also possible to define unique text for each getter/setter. To do that, you create a 'section' named <code>GETTER</code> and/or <code>SETTER</code>. A section is a line in your javadoc containing 2 or more dashes, then the text 'GETTER' or 'SETTER', followed by 2 or more dashes, and nothing else on the line. If you use sections, <code>@return</code> and <code>@param</code> stripping for that section is no longer done (move the <code>@return</code> or <code>@param</code> line into the section).
|
||||
</p>
|
||||
</div>
|
||||
<div class="snippets">
|
||||
|
||||
Reference in new issue
Block a user