Merge branch 'builderUpdate'

This commit is contained in:
Reinier Zwitserloot committed 2015-11-17 02:15:31 +01:00
commit 0bd688d7e6
41 files changed
+1005 -208

No files matched your search

+2
View File
@@ -3,6 +3,7 @@ Lombok contributors in alphabetical order:
Christian Sterzl <christian.sterzl@gmail.com>
DaveLaw <project.lombok@apconsult.de>
Dawid Rusin <dawidrusin90@gmail.com>
Enrique da Costa Cambio <enrique.dacostacambio@gmail.com>
Jappe van der Hel <jappe.vanderhel@gmail.com>
Luan Nico <luannico27@gmail.com>
Maarten Mulders <mthmulders@users.noreply.github.com>
@@ -12,6 +13,7 @@ Reinier Zwitserloot <reinier@zwitserloot.com>
Robbert Jan Grootjans <grootjans@gmail.com>
Roel Spilker <r.spilker@gmail.com>
Sander Koning <askoning@gmail.com>
Szymon Pacanowski <spacanowski@gmail.com>
Taiki Sugawara <buzz.taiki@gmail.com>
Yun Zhi Lin <yun@yunspace.com>
+3
View File
@@ -2,6 +2,9 @@ Lombok Changelog
----------------
### v1.16.7 "Edgy Guinea Pig"
* FEATURE: `@Builder` updates: It now generates `clearFieldName()` methods if `@Singular` is used. [Issue #967](https://github.com/rzwitserloot/lombok/issues/967).
* FEATURE: `@Builder` updates: The annotation can now be put on instance methods. [Issue #63](https://github.com/rzwitserloot/lombok/issues/63).
* FEATURE: `@Builder` updates: `@Singular` now supports guava's ImmutableTable [Issue #937](https://github.com/rzwitserloot/lombok/issues/937).
* FEATURE: A `lombok.config` key can now be used to make your fields `final` and/or `private`... __everywhere__. We'll be monitoring the performance impact of this for a while. We'll touch every source file if you turn these on, and even if you don't, we have to call into the lombok config system for every file.
* BUGFIX: `@Value` and `@FieldDefaults` no longer make uninitialized static fields final. [Issue #928](https://github.com/rzwitserloot/lombok/issues/928).
* BUGFIX: When using delombok, a source file with only `@NonNull` annotations on parameters as lombok feature would not get properly delomboked. [Issue #950](https://github.com/rzwitserloot/lombok/issues/950).
+8 -8
View File
@@ -31,21 +31,21 @@ import java.lang.annotation.Target;
* The builder annotation creates a so-called 'builder' aspect to the class that is annotated or the class
* that contains a member which is annotated with {@code @Builder}.
* <p>
* If a member is annotated, it must be either a constructor or a static method. If a class is annotated,
* If a member is annotated, it must be either a constructor or a method. If a class is annotated,
* then a private constructor is generated with all fields as arguments
* (as if {@code @AllArgsConstructor(AccessLevel.PRIVATE)} is present
* on the class), and it is as if this constructor has been annotated with {@code @Builder} instead.
* <p>
* The effect of {@code @Builder} is that an inner class is generated named <code><strong>T</strong>Builder</code>,
* with a private constructor. Instances of <code><strong>T</strong>Builder</code> are made with the static
* with a private constructor. Instances of <code><strong>T</strong>Builder</code> are made with the
* method named {@code builder()} which is also generated for you in the class itself (not in the builder class).
* <p>
* The <code><strong>T</strong>Builder</code> class contains 1 method for each parameter of the annotated
* constructor / static method (each field, when annotating a class), which returns the builder itself.
* constructor / method (each field, when annotating a class), which returns the builder itself.
* The builder also has a <code>build()</code> method which returns a completed instance of the original type,
* created by passing all parameters as set via the various other methods in the builder to the constructor
* or static method that was annotated with {@code @Builder}. The return type of this method will be the same
* as the relevant class, unless a static method has been annotated, in which case it'll be equal to the
* or method that was annotated with {@code @Builder}. The return type of this method will be the same
* as the relevant class, unless a method has been annotated, in which case it'll be equal to the
* return type of that method.
* <p>
* Complete documentation is found at <a href="https://projectlombok.org/features/experimental/Builder.html">the project lombok features page for &#64;Builder</a>.
@@ -107,10 +107,10 @@ import java.lang.annotation.Target;
@Target({TYPE, METHOD, CONSTRUCTOR})
@Retention(SOURCE)
public @interface Builder {
/** Name of the static method that creates a new builder instance. Default: {@code builder}. */
/** Name of the method that creates a new builder instance. Default: {@code builder}. */
String builderMethodName() default "builder";
/** Name of the instance method in the builder class that creates an instance of your {@code @Builder}-annotated class. */
/** Name of the method in the builder class that creates an instance of your {@code @Builder}-annotated class. */
String buildMethodName() default "build";
/**
@@ -118,7 +118,7 @@ public @interface Builder {
*
* Default for {@code @Builder} on types and constructors: {@code (TypeName)Builder}.
* <p>
* Default for {@code @Builder} on static methods: {@code (ReturnTypeName)Builder}.
* Default for {@code @Builder} on methods: {@code (ReturnTypeName)Builder}.
*/
String builderClassName() default "";
+1
View File
@@ -45,6 +45,7 @@ public final class GuavaTypeMap {
m.put("com.google.common.collect.ImmutableSortedMap", "ImmutableSortedMap");
m.put("com.google.common.collect.ImmutableList", "ImmutableList");
m.put("com.google.common.collect.ImmutableCollection", "ImmutableList");
m.put("com.google.common.collect.ImmutableTable", "ImmutableTable");
TYPE_TO_GUAVA_TYPE = Collections.unmodifiableMap(m);
}
@@ -49,6 +49,7 @@ import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
@@ -163,6 +164,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
EclipseNode fillParametersFrom = parent.get() instanceof AbstractMethodDeclaration ? parent : null;
boolean addCleaning = false;
boolean isStatic = true;
if (parent.get() instanceof TypeDeclaration) {
tdParent = parent;
@@ -212,11 +214,8 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
} else if (parent.get() instanceof MethodDeclaration) {
MethodDeclaration md = (MethodDeclaration) parent.get();
tdParent = parent.up();
if (!md.isStatic()) {
annotationNode.addError("@Builder is only supported on types, constructors, and static methods.");
return;
}
isStatic = md.isStatic();
if (toBuilder) {
final String TO_BUILDER_NOT_SUPPORTED = "@Builder(toBuilder=true) is only supported if you return your own type.";
char[] token;
@@ -322,7 +321,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
builderClassName = new String(token) + "Builder";
}
} else {
annotationNode.addError("@Builder is only supported on types, constructors, and static methods.");
annotationNode.addError("@Builder is only supported on types, constructors, and methods.");
return;
}
@@ -342,8 +341,16 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
EclipseNode builderType = findInnerClass(tdParent, builderClassName);
if (builderType == null) {
builderType = makeBuilderClass(tdParent, builderClassName, typeParams, ast);
builderType = makeBuilderClass(isStatic, tdParent, builderClassName, typeParams, ast);
} else {
TypeDeclaration builderTypeDeclaration = (TypeDeclaration) builderType.get();
if (isStatic && (builderTypeDeclaration.modifiers & ClassFileConstants.AccStatic) == 0) {
annotationNode.addError("Existing Builder must be a static inner class.");
return;
} else if (!isStatic && (builderTypeDeclaration.modifiers & ClassFileConstants.AccStatic) != 0) {
annotationNode.addError("Existing Builder must be a non-static inner class.");
return;
}
sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderType, annotationNode);
/* generate errors for @Singular BFDs that have one already defined node. */ {
for (BuilderFieldData bfd : builderFields) {
@@ -398,7 +405,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
if (methodExists(buildMethodName, builderType, -1) == MemberExistsResult.NOT_EXISTS) {
MethodDeclaration md = generateBuildMethod(buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, addCleaning, ast);
MethodDeclaration md = generateBuildMethod(isStatic, buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, addCleaning, ast);
if (md != null) injectMethod(builderType, md);
}
@@ -417,7 +424,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
MethodDeclaration md = generateBuilderMethod(builderMethodName, builderClassName, tdParent, typeParams, ast);
MethodDeclaration md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, tdParent, typeParams, ast);
if (md != null) injectMethod(tdParent, md);
}
@@ -507,7 +514,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return decl;
}
public MethodDeclaration generateBuildMethod(String name, char[] staticName, TypeReference returnType, List<BuilderFieldData> builderFields, EclipseNode type, TypeReference[] thrownExceptions, boolean addCleaning, ASTNode source) {
public MethodDeclaration generateBuildMethod(boolean isStatic, String name, char[] staticName, TypeReference returnType, List<BuilderFieldData> builderFields, EclipseNode type, TypeReference[] thrownExceptions, boolean addCleaning, ASTNode source) {
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
List<Statement> statements = new ArrayList<Statement>();
@@ -552,7 +559,10 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
} else {
MessageSend invoke = new MessageSend();
invoke.selector = staticName;
invoke.receiver = new SingleNameReference(type.up().getName().toCharArray(), 0);
if (isStatic)
invoke.receiver = new SingleNameReference(type.up().getName().toCharArray(), 0);
else
invoke.receiver = new QualifiedThisReference(new SingleTypeReference(type.up().getName().toCharArray(), 0) , 0, 0);
TypeParameter[] tps = ((TypeDeclaration) type.get()).typeParameters;
if (tps != null) {
TypeReference[] trs = new TypeReference[tps.length];
@@ -573,13 +583,14 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return out;
}
public MethodDeclaration generateBuilderMethod(String builderMethodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
public MethodDeclaration generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
out.selector = builderMethodName.toCharArray();
out.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic;
out.modifiers = ClassFileConstants.AccPublic;
if (isStatic) out.modifiers |= ClassFileConstants.AccStatic;
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
out.returnType = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p);
out.typeParameters = copyTypeParams(typeParams, source);
@@ -661,11 +672,12 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return null;
}
public EclipseNode makeBuilderClass(EclipseNode tdParent, String builderClassName, TypeParameter[] typeParams, ASTNode source) {
public EclipseNode makeBuilderClass(boolean isStatic, EclipseNode tdParent, String builderClassName, TypeParameter[] typeParams, ASTNode source) {
TypeDeclaration parent = (TypeDeclaration) tdParent.get();
TypeDeclaration builder = new TypeDeclaration(parent.compilationResult);
builder.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
builder.modifiers |= ClassFileConstants.AccPublic | ClassFileConstants.AccStatic;
builder.modifiers |= ClassFileConstants.AccPublic;
if (isStatic) builder.modifiers |= ClassFileConstants.AccStatic;
builder.typeParameters = copyTypeParams(typeParams, source);
builder.name = builderClassName.toCharArray();
builder.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
@@ -32,14 +32,27 @@ public class EclipseGuavaMapSingularizer extends EclipseGuavaSingularizer {
// TODO cgcc.ImmutableClassToInstanceMap
// TODO cgcc.ImmutableRangeMap
private static final LombokImmutableList<String> SUFFIXES =
LombokImmutableList.of("key", "value");
private static final LombokImmutableList<String> SUPPORTED_TYPES = LombokImmutableList.of(
"com.google.common.collect.ImmutableMap",
"com.google.common.collect.ImmutableBiMap",
"com.google.common.collect.ImmutableSortedMap"
);
@Override public LombokImmutableList<String> getSupportedTypes() {
return LombokImmutableList.of(
"com.google.common.collect.ImmutableMap",
"com.google.common.collect.ImmutableBiMap",
"com.google.common.collect.ImmutableSortedMap");
return SUPPORTED_TYPES;
}
@Override protected boolean isMap() {
return true;
@Override protected LombokImmutableList<String> getArgumentSuffixes() {
return SUFFIXES;
}
@Override protected String getAddMethodName() {
return "put";
}
@Override protected String getAddAllTypeName() {
return "java.util.Map";
}
}
@@ -28,18 +28,29 @@ import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
@ProviderFor(EclipseSingularizer.class)
public class EclipseGuavaSetListSingularizer extends EclipseGuavaSingularizer {
// TODO com.google.common.collect.ImmutableTable
// TODO com.google.common.collect.ImmutableRangeSet
// TODO com.google.common.collect.ImmutableMultiset and com.google.common.collect.ImmutableSortedMultiset
private static final LombokImmutableList<String> SUFFIXES = LombokImmutableList.of("");
private static final LombokImmutableList<String> SUPPORTED_TYPES = LombokImmutableList.of(
"com.google.common.collect.ImmutableCollection",
"com.google.common.collect.ImmutableList",
"com.google.common.collect.ImmutableSet",
"com.google.common.collect.ImmutableSortedSet"
);
@Override public LombokImmutableList<String> getSupportedTypes() {
return LombokImmutableList.of(
"com.google.common.collect.ImmutableCollection",
"com.google.common.collect.ImmutableList",
"com.google.common.collect.ImmutableSet",
"com.google.common.collect.ImmutableSortedSet");
return SUPPORTED_TYPES;
}
@Override protected boolean isMap() {
return false;
@Override protected LombokImmutableList<String> getArgumentSuffixes() {
return SUFFIXES;
}
@Override protected String getAddMethodName() {
return "add";
}
@Override protected String getAddAllTypeName() {
return "java.lang.Iterable";
}
}
@@ -29,6 +29,7 @@ import java.util.Collections;
import java.util.List;
import lombok.core.GuavaTypeMap;
import lombok.core.LombokImmutableList;
import lombok.core.handlers.HandlerUtil;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
@@ -56,14 +57,9 @@ import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
protected static final char[][] JAVA_UTIL_MAP = {
{'j', 'a', 'v', 'a'}, {'u', 't', 'i', 'l'}, {'M', 'a', 'p'}
};
protected String getSimpleTargetTypeName(SingularData data) {
return GuavaTypeMap.getGuavaTypeName(data.getTargetFqn());
}
@@ -74,8 +70,6 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
return "builder".toCharArray();
}
protected abstract boolean isMap();
protected char[][] makeGuavaTypeName(String simpleName, boolean addBuilder) {
char[][] tokenizedName = new char[addBuilder ? 6 : 5][];
tokenizedName[0] = new char[] {'c', 'o', 'm'};
@@ -88,9 +82,10 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
}
@Override public List<EclipseNode> generateFields(SingularData data, EclipseNode builderType) {
char[][] tokenizedName = makeGuavaTypeName(getSimpleTargetTypeName(data), true);
String simpleTypeName = getSimpleTargetTypeName(data);
char[][] tokenizedName = makeGuavaTypeName(simpleTypeName, true);
TypeReference type = new QualifiedTypeReference(tokenizedName, NULL_POSS);
type = addTypeArgs(isMap() ? 2 : 1, false, builderType, type, data.getTypeArgs());
type = addTypeArgs(getTypeArgumentsCount(), false, builderType, type, data.getTypeArgs());
FieldDeclaration buildField = new FieldDeclaration(data.getPluralName(), 0, -1);
buildField.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
@@ -109,12 +104,34 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
generatePluralMethod(returnType, returnStatement, data, builderType, fluent);
returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
generateClearMethod(returnType, returnStatement, data, builderType);
}
void generateClearMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = ClassFileConstants.AccPublic;
FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
thisDotField.receiver = new ThisReference(0, 0);
Assignment a = new Assignment(thisDotField, new NullLiteral(0, 0), 0);
md.selector = HandlerUtil.buildAccessorName("clear", new String(data.getPluralName())).toCharArray();
md.statements = returnStatement != null ? new Statement[] {a, returnStatement} : new Statement[] {a};
md.returnType = returnType;
injectMethod(builderType, md);
}
void generateSingularMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
boolean mapMode = isMap();
char[] keyName = !mapMode ? data.getSingularName() : (new String(data.getSingularName()) + "$key").toCharArray();
char[] valueName = !mapMode ? null : (new String(data.getSingularName()) + "$value").toCharArray();
LombokImmutableList<String> suffixes = getArgumentSuffixes();
char[][] names = new char[suffixes.size()][];
for (int i = 0; i < suffixes.size(); i++) {
String s = suffixes.get(i);
char[] n = data.getSingularName();
names[i] = s.isEmpty() ? n : s.toCharArray();
}
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
@@ -126,40 +143,28 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
thisDotField.receiver = new ThisReference(0, 0);
MessageSend thisDotFieldDotAdd = new MessageSend();
if (mapMode) {
thisDotFieldDotAdd.arguments = new Expression[] {
new SingleNameReference(keyName, 0L),
new SingleNameReference(valueName, 0L)};
} else {
thisDotFieldDotAdd.arguments = new Expression[] {new SingleNameReference(keyName, 0L)};
thisDotFieldDotAdd.arguments = new Expression[suffixes.size()];
for (int i = 0; i < suffixes.size(); i++) {
thisDotFieldDotAdd.arguments[i] = new SingleNameReference(names[i], 0L);
}
thisDotFieldDotAdd.receiver = thisDotField;
thisDotFieldDotAdd.selector = (mapMode ? "put" : "add").toCharArray();
thisDotFieldDotAdd.selector = getAddMethodName().toCharArray();
statements.add(thisDotFieldDotAdd);
if (returnStatement != null) statements.add(returnStatement);
md.statements = statements.toArray(new Statement[statements.size()]);
if (mapMode) {
TypeReference keyType = cloneParamType(0, data.getTypeArgs(), builderType);
Argument keyParam = new Argument(keyName, 0, keyType, 0);
TypeReference valueType = cloneParamType(1, data.getTypeArgs(), builderType);
Argument valueParam = new Argument(valueName, 0, valueType, 0);
md.arguments = new Argument[] {keyParam, valueParam};
} else {
TypeReference paramType = cloneParamType(0, data.getTypeArgs(), builderType);
Argument param = new Argument(keyName, 0, paramType, 0);
md.arguments = new Argument[] {param};
md.arguments = new Argument[suffixes.size()];
for (int i = 0; i < suffixes.size(); i++) {
TypeReference tr = cloneParamType(i, data.getTypeArgs(), builderType);
md.arguments[i] = new Argument(names[i], 0, tr, 0);
}
md.returnType = returnType;
md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName(mapMode ? "put" : "add", new String(data.getSingularName())).toCharArray();
md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName(getAddMethodName(), new String(data.getSingularName())).toCharArray();
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
void generatePluralMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
boolean mapMode = isMap();
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = ClassFileConstants.AccPublic;
@@ -172,40 +177,36 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
MessageSend thisDotFieldDotAddAll = new MessageSend();
thisDotFieldDotAddAll.arguments = new Expression[] {new SingleNameReference(data.getPluralName(), 0L)};
thisDotFieldDotAddAll.receiver = thisDotField;
thisDotFieldDotAddAll.selector = (mapMode ? "putAll" : "addAll").toCharArray();
thisDotFieldDotAddAll.selector = (getAddMethodName() + "All").toCharArray();
statements.add(thisDotFieldDotAddAll);
if (returnStatement != null) statements.add(returnStatement);
md.statements = statements.toArray(new Statement[statements.size()]);
TypeReference paramType;
if (mapMode) {
paramType = new QualifiedTypeReference(JAVA_UTIL_MAP, NULL_POSS);
paramType = addTypeArgs(2, true, builderType, paramType, data.getTypeArgs());
} else {
paramType = new QualifiedTypeReference(TypeConstants.JAVA_LANG_ITERABLE, NULL_POSS);
paramType = addTypeArgs(1, true, builderType, paramType, data.getTypeArgs());
}
paramType = new QualifiedTypeReference(fromQualifiedName(getAddAllTypeName()), NULL_POSS);
paramType = addTypeArgs(getTypeArgumentsCount(), true, builderType, paramType, data.getTypeArgs());
Argument param = new Argument(data.getPluralName(), 0, paramType, 0);
md.arguments = new Argument[] {param};
md.returnType = returnType;
md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName(mapMode ? "putAll" : "addAll", new String(data.getPluralName())).toCharArray();
md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName(getAddMethodName() + "All", new String(data.getPluralName())).toCharArray();
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
@Override public void appendBuildCode(SingularData data, EclipseNode builderType, List<Statement> statements, char[] targetVariableName) {
boolean mapMode = isMap();
TypeReference varType = new QualifiedTypeReference(fromQualifiedName(data.getTargetFqn()), NULL_POSS);
varType = addTypeArgs(mapMode ? 2 : 1, false, builderType, varType, data.getTypeArgs());
String simpleTypeName = getSimpleTargetTypeName(data);
int agrumentsCount = getTypeArgumentsCount();
varType = addTypeArgs(agrumentsCount, false, builderType, varType, data.getTypeArgs());
MessageSend emptyInvoke; {
//ImmutableX.of()
emptyInvoke = new MessageSend();
emptyInvoke.selector = new char[] {'o', 'f'};
emptyInvoke.receiver = new QualifiedNameReference(makeGuavaTypeName(getSimpleTargetTypeName(data), false), NULL_POSS, 0, 0);
emptyInvoke.typeArguments = createTypeArgs(mapMode ? 2 : 1, false, builderType, data.getTypeArgs());
emptyInvoke.receiver = new QualifiedNameReference(makeGuavaTypeName(simpleTypeName, false), NULL_POSS, 0, 0);
emptyInvoke.typeArguments = createTypeArgs(agrumentsCount, false, builderType, data.getTypeArgs());
}
MessageSend invokeBuild; {
@@ -244,4 +245,12 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
createBuilderInvoke.selector = getBuilderMethodName(data);
return new IfStatement(cond, new Assignment(thisDotField2, createBuilderInvoke, 0), 0, 0);
}
protected abstract LombokImmutableList<String> getArgumentSuffixes();
protected abstract String getAddMethodName();
protected abstract String getAddAllTypeName();
protected int getTypeArgumentsCount() {
return getArgumentSuffixes().size();
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2015 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package lombok.eclipse.handlers.singulars;
import org.mangosdk.spi.ProviderFor;
import lombok.core.LombokImmutableList;
import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
@ProviderFor(EclipseSingularizer.class)
public class EclipseGuavaTableSingularizer extends EclipseGuavaSingularizer {
private static final LombokImmutableList<String> SUFFIXES =
LombokImmutableList.of("rowKey", "columnKey", "value");
private static final LombokImmutableList<String> SUPPORTED_TYPES =
LombokImmutableList.of("com.google.common.collect.ImmutableTable");
@Override public LombokImmutableList<String> getSupportedTypes() {
return SUPPORTED_TYPES;
}
@Override protected LombokImmutableList<String> getArgumentSuffixes() {
return SUFFIXES;
}
@Override protected String getAddMethodName() {
return "put";
}
@Override protected String getAddAllTypeName() {
return "com.google.common.collect.Table";
}
}
@@ -34,11 +34,15 @@ import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
@@ -96,6 +100,29 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
generatePluralMethod(returnType, returnStatement, data, builderType, fluent);
returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
generateClearMethod(returnType, returnStatement, data, builderType);
}
private void generateClearMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = ClassFileConstants.AccPublic;
FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
thisDotField.receiver = new ThisReference(0, 0);
FieldReference thisDotField2 = new FieldReference(data.getPluralName(), 0L);
thisDotField2.receiver = new ThisReference(0, 0);
md.selector = HandlerUtil.buildAccessorName("clear", new String(data.getPluralName())).toCharArray();
MessageSend clearMsg = new MessageSend();
clearMsg.receiver = thisDotField2;
clearMsg.selector = "clear".toCharArray();
Statement clearStatement = new IfStatement(new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.NOT_EQUAL), clearMsg, 0, 0);
md.statements = returnStatement != null ? new Statement[] {clearStatement, returnStatement} : new Statement[] {clearStatement};
md.returnType = returnType;
injectMethod(builderType, md);
}
void generateSingularMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
@@ -32,13 +32,17 @@ import java.util.List;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
@@ -141,6 +145,40 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
generatePluralMethod(returnType, returnStatement, data, builderType, fluent);
returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
generateClearMethod(returnType, returnStatement, data, builderType);
}
private void generateClearMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = ClassFileConstants.AccPublic;
String pN = new String(data.getPluralName());
char[] keyFieldName = (pN + "$key").toCharArray();
char[] valueFieldName = (pN + "$value").toCharArray();
FieldReference thisDotField = new FieldReference(keyFieldName, 0L);
thisDotField.receiver = new ThisReference(0, 0);
FieldReference thisDotField2 = new FieldReference(keyFieldName, 0L);
thisDotField2.receiver = new ThisReference(0, 0);
FieldReference thisDotField3 = new FieldReference(valueFieldName, 0L);
thisDotField3.receiver = new ThisReference(0, 0);
md.selector = HandlerUtil.buildAccessorName("clear", new String(data.getPluralName())).toCharArray();
MessageSend clearMsg1 = new MessageSend();
clearMsg1.receiver = thisDotField2;
clearMsg1.selector = "clear".toCharArray();
MessageSend clearMsg2 = new MessageSend();
clearMsg2.receiver = thisDotField3;
clearMsg2.selector = "clear".toCharArray();
Block clearMsgs = new Block(2);
clearMsgs.statements = new Statement[] {clearMsg1, clearMsg2};
Statement clearStatement = new IfStatement(new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.NOT_EQUAL), clearMsgs, 0, 0);
md.statements = returnStatement != null ? new Statement[] {clearStatement, returnStatement} : new Statement[] {clearStatement};
md.returnType = returnType;
injectMethod(builderType, md);
}
private void generateSingularMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
+8 -8
View File
@@ -31,21 +31,21 @@ import java.lang.annotation.Target;
* The builder annotation creates a so-called 'builder' aspect to the class that is annotated or the class
* that contains a member which is annotated with {@code @Builder}.
* <p>
* If a member is annotated, it must be either a constructor or a static method. If a class is annotated,
* If a member is annotated, it must be either a constructor or a method. If a class is annotated,
* then a private constructor is generated with all fields as arguments
* (as if {@code @AllArgsConstructor(AccessLevel.PRIVATE)} is present
* on the class), and it is as if this constructor has been annotated with {@code @Builder} instead.
* <p>
* The effect of {@code @Builder} is that an inner class is generated named <code><strong>T</strong>Builder</code>,
* with a private constructor. Instances of <code><strong>T</strong>Builder</code> are made with the static
* with a private constructor. Instances of <code><strong>T</strong>Builder</code> are made with the
* method named {@code builder()} which is also generated for you in the class itself (not in the builder class).
* <p>
* The <code><strong>T</strong>Builder</code> class contains 1 method for each parameter of the annotated
* constructor / static method (each field, when annotating a class), which returns the builder itself.
* constructor / method (each field, when annotating a class), which returns the builder itself.
* The builder also has a <code>build()</code> method which returns a completed instance of the original type,
* created by passing all parameters as set via the various other methods in the builder to the constructor
* or static method that was annotated with {@code @Builder}. The return type of this method will be the same
* as the relevant class, unless a static method has been annotated, in which case it'll be equal to the
* or method that was annotated with {@code @Builder}. The return type of this method will be the same
* as the relevant class, unless a method has been annotated, in which case it'll be equal to the
* return type of that method.
* <p>
* Complete documentation is found at <a href="https://projectlombok.org/features/experimental/Builder.html">the project lombok features page for &#64;Builder</a>.
@@ -110,15 +110,15 @@ import java.lang.annotation.Target;
@Retention(SOURCE)
@Deprecated
public @interface Builder {
/** Name of the static method that creates a new builder instance. Default: {@code builder}. */
/** Name of the method that creates a new builder instance. Default: {@code builder}. */
String builderMethodName() default "builder";
/** Name of the instance method in the builder class that creates an instance of your {@code @Builder}-annotated class. */
/** Name of the method in the builder class that creates an instance of your {@code @Builder}-annotated class. */
String buildMethodName() default "build";
/** Name of the builder class.
* Default for {@code @Builder} on types and constructors: {@code (TypeName)Builder}.
* Default for {@code @Builder} on static methods: {@code (ReturnTypeName)Builder}.
* Default for {@code @Builder} on methods: {@code (ReturnTypeName)Builder}.
*/
String builderClassName() default "";
@@ -24,6 +24,8 @@ package lombok.javac.handlers;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import javax.lang.model.element.Modifier;
import org.mangosdk.spi.ProviderFor;
import com.sun.tools.javac.code.Flags;
@@ -124,11 +126,12 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCExpression returnType;
List<JCTypeParameter> typeParams = List.nil();
List<JCExpression> thrownExceptions = List.nil();
Name nameOfStaticBuilderMethod;
Name nameOfBuilderMethod;
JavacNode tdParent;
JavacNode fillParametersFrom = parent.get() instanceof JCMethodDecl ? parent : null;
boolean addCleaning = false;
boolean isStatic = true;
if (parent.get() instanceof JCClassDecl) {
tdParent = parent;
@@ -157,7 +160,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams);
typeParams = td.typarams;
thrownExceptions = List.nil();
nameOfStaticBuilderMethod = null;
nameOfBuilderMethod = null;
if (builderClassName.isEmpty()) builderClassName = td.name.toString() + "Builder";
} else if (fillParametersFrom != null && fillParametersFrom.getName().toString().equals("<init>")) {
JCMethodDecl jmd = (JCMethodDecl) fillParametersFrom.get();
@@ -171,21 +174,18 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams);
typeParams = td.typarams;
thrownExceptions = jmd.thrown;
nameOfStaticBuilderMethod = null;
nameOfBuilderMethod = null;
if (builderClassName.isEmpty()) builderClassName = td.name.toString() + "Builder";
} else if (fillParametersFrom != null) {
tdParent = parent.up();
JCClassDecl td = (JCClassDecl) tdParent.get();
JCMethodDecl jmd = (JCMethodDecl) fillParametersFrom.get();
if ((jmd.mods.flags & Flags.STATIC) == 0) {
annotationNode.addError("@Builder is only supported on types, constructors, and static methods.");
return;
}
isStatic = (jmd.mods.flags & Flags.STATIC) != 0;
JCExpression fullReturnType = jmd.restype;
returnType = fullReturnType;
typeParams = jmd.typarams;
thrownExceptions = jmd.thrown;
nameOfStaticBuilderMethod = jmd.name;
nameOfBuilderMethod = jmd.name;
if (returnType instanceof JCTypeApply) {
returnType = ((JCTypeApply) returnType).clazz;
}
@@ -278,7 +278,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
}
} else {
annotationNode.addError("@Builder is only supported on types, constructors, and static methods.");
annotationNode.addError("@Builder is only supported on types, constructors, and methods.");
return;
}
@@ -298,8 +298,16 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JavacNode builderType = findInnerClass(tdParent, builderClassName);
if (builderType == null) {
builderType = makeBuilderClass(tdParent, builderClassName, typeParams, ast);
builderType = makeBuilderClass(isStatic, tdParent, builderClassName, typeParams, ast);
} else {
JCClassDecl builderTypeDeclaration = (JCClassDecl) builderType.get();
if (isStatic && !builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) {
annotationNode.addError("Existing Builder must be a static inner class.");
return;
} else if (!isStatic && builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) {
annotationNode.addError("Existing Builder must be a non-static inner class.");
return;
}
sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderType, annotationNode);
/* generate errors for @Singular BFDs that have one already defined node. */ {
for (BuilderFieldData bfd : builderFields) {
@@ -351,7 +359,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
if (methodExists(buildMethodName, builderType, -1) == MemberExistsResult.NOT_EXISTS) {
JCMethodDecl md = generateBuildMethod(buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, ast, addCleaning);
JCMethodDecl md = generateBuildMethod(isStatic, buildMethodName, nameOfBuilderMethod, returnType, builderFields, builderType, thrownExceptions, ast, addCleaning);
if (md != null) injectMethod(builderType, md);
}
@@ -367,7 +375,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
if (addCleaning) injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
JCMethodDecl md = generateBuilderMethod(builderMethodName, builderClassName, tdParent, typeParams);
JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, tdParent, typeParams);
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
if (md != null) injectMethod(tdParent, md);
}
@@ -488,7 +496,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
*/
}
private JCMethodDecl generateBuildMethod(String name, Name staticName, JCExpression returnType, java.util.List<BuilderFieldData> builderFields, JavacNode type, List<JCExpression> thrownExceptions, JCTree source, boolean addCleaning) {
private JCMethodDecl generateBuildMethod(boolean isStatic, String buildName, Name builderName, JCExpression returnType, java.util.List<BuilderFieldData> builderFields, JavacNode type, List<JCExpression> thrownExceptions, JCTree source, boolean addCleaning) {
JavacTreeMaker maker = type.getTreeMaker();
JCExpression call;
@@ -516,16 +524,19 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
statements.append(maker.Exec(maker.Assign(maker.Select(maker.Ident(type.toName("this")), type.toName("$lombokUnclean")), maker.Literal(CTC_BOOLEAN, true))));
}
if (staticName == null) {
if (builderName == null) {
call = maker.NewClass(null, List.<JCExpression>nil(), returnType, args.toList(), null);
statements.append(maker.Return(call));
} else {
ListBuffer<JCExpression> typeParams = new ListBuffer<JCExpression>();
for (JCTypeParameter tp : ((JCClassDecl) type.get()).typarams) {
typeParams.append(maker.Ident(tp.name));
}
JCExpression fn = maker.Select(maker.Ident(((JCClassDecl) type.up().get()).name), staticName);
JCExpression callee = maker.Ident(((JCClassDecl) type.up().get()).name);
if (!isStatic)
callee = maker.Select(callee, type.up().toName("this"));
JCExpression fn = maker.Select(callee, builderName);
call = maker.Apply(typeParams.toList(), fn, args.toList());
if (returnType instanceof JCPrimitiveTypeTree && CTC_VOID.equals(typeTag(returnType))) {
statements.append(maker.Exec(call));
@@ -536,10 +547,10 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCBlock body = maker.Block(0, statements.toList());
return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName(name), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null);
return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName(buildName), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null);
}
public JCMethodDecl generateBuilderMethod(String builderMethodName, String builderClassName, JavacNode type, List<JCTypeParameter> typeParams) {
public JCMethodDecl generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, JavacNode type, List<JCTypeParameter> typeParams) {
JavacTreeMaker maker = type.getTreeMaker();
ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
@@ -551,7 +562,9 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCStatement statement = maker.Return(call);
JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
return maker.MethodDef(maker.Modifiers(Flags.STATIC | Flags.PUBLIC), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(maker, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
int modifiers = Flags.PUBLIC;
if (isStatic) modifiers |= Flags.STATIC;
return maker.MethodDef(maker.Modifiers(modifiers), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(maker, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
}
public void generateBuilderFields(JavacNode builderType, java.util.List<BuilderFieldData> builderFields, JCTree source) {
@@ -615,9 +628,11 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
return null;
}
public JavacNode makeBuilderClass(JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast) {
public JavacNode makeBuilderClass(boolean isStatic, JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast) {
JavacTreeMaker maker = tdParent.getTreeMaker();
JCModifiers mods = maker.Modifiers(Flags.PUBLIC | Flags.STATIC);
int modifiers = Flags.PUBLIC;
if (isStatic) modifiers |= Flags.STATIC;
JCModifiers mods = maker.Modifiers(modifiers);
JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(maker, typeParams), null, List.<JCExpression>nil(), List.<JCTree>nil());
return injectType(tdParent, builder);
}
@@ -32,14 +32,27 @@ public class JavacGuavaMapSingularizer extends JavacGuavaSingularizer {
// TODO cgcc.ImmutableClassToInstanceMap
// TODO cgcc.ImmutableRangeMap
private static final LombokImmutableList<String> SUFFIXES =
LombokImmutableList.of("key", "value");
private static final LombokImmutableList<String> SUPPORTED_TYPES = LombokImmutableList.of(
"com.google.common.collect.ImmutableMap",
"com.google.common.collect.ImmutableBiMap",
"com.google.common.collect.ImmutableSortedMap"
);
@Override public LombokImmutableList<String> getSupportedTypes() {
return LombokImmutableList.of(
"com.google.common.collect.ImmutableMap",
"com.google.common.collect.ImmutableBiMap",
"com.google.common.collect.ImmutableSortedMap");
return SUPPORTED_TYPES;
}
@Override protected boolean isMap() {
return true;
@Override protected LombokImmutableList<String> getArgumentSuffixes() {
return SUFFIXES;
}
@Override protected String getAddMethodName() {
return "put";
}
@Override protected String getAddAllTypeName() {
return "java.util.Map";
}
}
@@ -1,16 +1,16 @@
/*
* Copyright (C) 2015 The Project Lombok Authors.
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -21,25 +21,36 @@
*/
package lombok.javac.handlers.singulars;
import org.mangosdk.spi.ProviderFor;
import lombok.core.LombokImmutableList;
import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
import org.mangosdk.spi.ProviderFor;
@ProviderFor(JavacSingularizer.class)
public class JavacGuavaSetListSingularizer extends JavacGuavaSingularizer {
// TODO com.google.common.collect.ImmutableTable
// TODO com.google.common.collect.ImmutableRangeSet
// TODO com.google.common.collect.ImmutableMultiset and com.google.common.collect.ImmutableSortedMultiset
private static final LombokImmutableList<String> SUFFIXES = LombokImmutableList.of("");
private static final LombokImmutableList<String> SUPPORTED_TYPES = LombokImmutableList.of(
"com.google.common.collect.ImmutableCollection",
"com.google.common.collect.ImmutableList",
"com.google.common.collect.ImmutableSet",
"com.google.common.collect.ImmutableSortedSet"
);
@Override public LombokImmutableList<String> getSupportedTypes() {
return LombokImmutableList.of(
"com.google.common.collect.ImmutableCollection",
"com.google.common.collect.ImmutableList",
"com.google.common.collect.ImmutableSet",
"com.google.common.collect.ImmutableSortedSet");
return SUPPORTED_TYPES;
}
@Override protected boolean isMap() {
return false;
@Override protected LombokImmutableList<String> getArgumentSuffixes() {
return SUFFIXES;
}
@Override protected String getAddMethodName() {
return "add";
}
@Override protected String getAddAllTypeName() {
return "java.lang.Iterable";
}
}
@@ -1,16 +1,16 @@
/*
* Copyright (C) 2015 The Project Lombok Authors.
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -27,6 +27,7 @@ import static lombok.javac.handlers.JavacHandlerUtil.*;
import java.util.Collections;
import lombok.core.GuavaTypeMap;
import lombok.core.LombokImmutableList;
import lombok.core.handlers.HandlerUtil;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
@@ -58,12 +59,11 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
return "builder";
}
protected abstract boolean isMap();
@Override public java.util.List<JavacNode> generateFields(SingularData data, JavacNode builderType, JCTree source) {
JavacTreeMaker maker = builderType.getTreeMaker();
JCExpression type = JavacHandlerUtil.chainDots(builderType, "com", "google", "common", "collect", getSimpleTargetTypeName(data), "Builder");
type = addTypeArgs(isMap() ? 2 : 1, false, builderType, type, data.getTypeArgs(), source);
String simpleTypeName = getSimpleTargetTypeName(data);
JCExpression type = JavacHandlerUtil.chainDots(builderType, "com", "google", "common", "collect", simpleTypeName, "Builder");
type = addTypeArgs(getTypeArgumentsCount(), false, builderType, type, data.getTypeArgs(), source);
JCVariableDecl buildField = maker.VarDef(maker.Modifiers(Flags.PRIVATE), data.getPluralName(), type, null);
return Collections.singletonList(injectFieldAndMarkGenerated(builderType, buildField));
@@ -74,75 +74,94 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
JCExpression returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
JCStatement returnStatement = chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
generateSingularMethod(maker, returnType, returnStatement, data, builderType, source, fluent);
returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
returnStatement = chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
generatePluralMethod(maker, returnType, returnStatement, data, builderType, source, fluent);
returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
returnStatement = chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
generateClearMethod(maker, returnType, returnStatement, data, builderType, source);
}
private void generateClearMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source) {
JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
List<JCTypeParameter> typeParams = List.nil();
List<JCExpression> thrown = List.nil();
List<JCVariableDecl> params = List.nil();
JCExpression thisDotField = maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName());
JCStatement clearField = maker.Exec(maker.Assign(thisDotField, maker.Literal(CTC_BOT, null)));
List<JCStatement> statements = returnStatement != null ? List.of(clearField, returnStatement) : List.of(clearField);
JCBlock body = maker.Block(0, statements);
Name methodName = builderType.toName(HandlerUtil.buildAccessorName("clear", data.getPluralName().toString()));
JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, params, thrown, body, null);
injectMethod(builderType, method);
}
void generateSingularMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
List<JCTypeParameter> typeParams = List.nil();
List<JCExpression> thrown = List.nil();
boolean mapMode = isMap();
Name keyName = !mapMode ? data.getSingularName() : builderType.toName(data.getSingularName() + "$key");
Name valueName = !mapMode ? null : builderType.toName(data.getSingularName() + "$value");
LombokImmutableList<String> suffixes = getArgumentSuffixes();
Name[] names = new Name[suffixes.size()];
for (int i = 0; i < suffixes.size(); i++) {
String s = suffixes.get(i);
Name n = data.getSingularName();
names[i] = s.isEmpty() ? n : builderType.toName(s);
}
JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, mapMode, source));
JCExpression thisDotFieldDotAdd = chainDots(builderType, "this", data.getPluralName().toString(), mapMode ? "put" : "add");
List<JCExpression> invokeAddExpr;
if (mapMode) {
invokeAddExpr = List.<JCExpression>of(maker.Ident(keyName), maker.Ident(valueName));
} else {
invokeAddExpr = List.<JCExpression>of(maker.Ident(keyName));
statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, source));
JCExpression thisDotFieldDotAdd = chainDots(builderType, "this", data.getPluralName().toString(), getAddMethodName());
ListBuffer<JCExpression> invokeAddExprBuilder = new ListBuffer<JCExpression>();
for (int i = 0; i < suffixes.size(); i++) {
invokeAddExprBuilder.append(maker.Ident(names[i]));
}
List<JCExpression> invokeAddExpr = invokeAddExprBuilder.toList();
JCExpression invokeAdd = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotAdd, invokeAddExpr);
statements.append(maker.Exec(invokeAdd));
if (returnStatement != null) statements.append(returnStatement);
JCBlock body = maker.Block(0, statements.toList());
Name methodName = data.getSingularName();
long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
if (!fluent) methodName = builderType.toName(HandlerUtil.buildAccessorName(mapMode ? "put" : "add", methodName.toString()));
List<JCVariableDecl> params;
if (mapMode) {
JCExpression keyType = cloneParamType(0, maker, data.getTypeArgs(), builderType, source);
JCExpression valueType = cloneParamType(1, maker, data.getTypeArgs(), builderType, source);
JCVariableDecl paramKey = maker.VarDef(maker.Modifiers(paramFlags), keyName, keyType, null);
JCVariableDecl paramValue = maker.VarDef(maker.Modifiers(paramFlags), valueName, valueType, null);
params = List.of(paramKey, paramValue);
} else {
JCExpression paramType = cloneParamType(0, maker, data.getTypeArgs(), builderType, source);
params = List.of(maker.VarDef(maker.Modifiers(paramFlags), data.getSingularName(), paramType, null));
if (!fluent) methodName = builderType.toName(HandlerUtil.buildAccessorName(getAddMethodName(), methodName.toString()));
ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
for (int i = 0; i < suffixes.size(); i++) {
JCExpression pt = cloneParamType(i, maker, data.getTypeArgs(), builderType, source);
JCVariableDecl p = maker.VarDef(maker.Modifiers(paramFlags), names[i], pt, null);
params.append(p);
}
JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, params, thrown, body, null);
JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, params.toList(), thrown, body, null);
injectMethod(builderType, method);
}
protected void generatePluralMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
List<JCTypeParameter> typeParams = List.nil();
List<JCExpression> thrown = List.nil();
boolean mapMode = isMap();
JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, mapMode, source));
JCExpression thisDotFieldDotAddAll = chainDots(builderType, "this", data.getPluralName().toString(), mapMode ? "putAll" : "addAll");
statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, source));
JCExpression thisDotFieldDotAddAll = chainDots(builderType, "this", data.getPluralName().toString(), getAddMethodName() + "All");
JCExpression invokeAddAll = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotAddAll, List.<JCExpression>of(maker.Ident(data.getPluralName())));
statements.append(maker.Exec(invokeAddAll));
if (returnStatement != null) statements.append(returnStatement);
JCBlock body = maker.Block(0, statements.toList());
Name methodName = data.getPluralName();
long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
if (!fluent) methodName = builderType.toName(HandlerUtil.buildAccessorName(mapMode ? "putAll" : "addAll", methodName.toString()));
if (!fluent) methodName = builderType.toName(HandlerUtil.buildAccessorName(getAddMethodName() + "All", methodName.toString()));
JCExpression paramType;
if (mapMode) {
paramType = chainDots(builderType, "java", "util", "Map");
String aaTypeName = getAddAllTypeName();
if (aaTypeName.startsWith("java.lang.") && aaTypeName.indexOf('.', 11) == -1) {
paramType = genJavaLangTypeRef(builderType, aaTypeName.substring(10));
} else {
paramType = genJavaLangTypeRef(builderType, "Iterable");
paramType = chainDotsString(builderType, aaTypeName);
}
paramType = addTypeArgs(mapMode ? 2 : 1, true, builderType, paramType, data.getTypeArgs(), source);
paramType = addTypeArgs(getTypeArgumentsCount(), true, builderType, paramType, data.getTypeArgs(), source);
JCVariableDecl param = maker.VarDef(maker.Modifiers(paramFlags), data.getPluralName(), paramType, null);
JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, List.of(param), thrown, body, null);
injectMethod(builderType, method);
@@ -151,15 +170,15 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
@Override public void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName) {
JavacTreeMaker maker = builderType.getTreeMaker();
List<JCExpression> jceBlank = List.nil();
boolean mapMode = isMap();
JCExpression varType = chainDotsString(builderType, data.getTargetFqn());
varType = addTypeArgs(mapMode ? 2 : 1, false, builderType, varType, data.getTypeArgs(), source);
int agrumentsCount = getTypeArgumentsCount();
varType = addTypeArgs(agrumentsCount, false, builderType, varType, data.getTypeArgs(), source);
JCExpression empty; {
//ImmutableX.of()
JCExpression emptyMethod = chainDots(builderType, "com", "google", "common", "collect", getSimpleTargetTypeName(data), "of");
List<JCExpression> invokeTypeArgs = createTypeArgs(mapMode ? 2 : 1, false, builderType, data.getTypeArgs(), source);
List<JCExpression> invokeTypeArgs = createTypeArgs(agrumentsCount, false, builderType, data.getTypeArgs(), source);
empty = maker.Apply(invokeTypeArgs, emptyMethod, jceBlank);
}
@@ -179,7 +198,7 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
statements.append(jcs);
}
protected JCStatement createConstructBuilderVarIfNeeded(JavacTreeMaker maker, SingularData data, JavacNode builderType, boolean mapMode, JCTree source) {
protected JCStatement createConstructBuilderVarIfNeeded(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) {
List<JCExpression> jceBlank = List.nil();
JCExpression thisDotField = maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName());
@@ -191,4 +210,12 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
return maker.If(cond, thenPart, null);
}
protected abstract LombokImmutableList<String> getArgumentSuffixes();
protected abstract String getAddMethodName();
protected abstract String getAddAllTypeName();
protected int getTypeArgumentsCount() {
return getArgumentSuffixes().size();
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2015 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package lombok.javac.handlers.singulars;
import org.mangosdk.spi.ProviderFor;
import lombok.core.LombokImmutableList;
import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
@ProviderFor(JavacSingularizer.class)
public class JavacGuavaTableSingularizer extends JavacGuavaSingularizer {
private static final LombokImmutableList<String> SUFFIXES =
LombokImmutableList.of("rowKey", "columnKey", "value");
private static final LombokImmutableList<String> SUPPORTED_TYPES =
LombokImmutableList.of("com.google.common.collect.ImmutableTable");
@Override public LombokImmutableList<String> getSupportedTypes() {
return SUPPORTED_TYPES;
}
@Override protected LombokImmutableList<String> getArgumentSuffixes() {
return SUFFIXES;
}
@Override protected String getAddMethodName() {
return "put";
}
@Override protected String getAddAllTypeName() {
return "com.google.common.collect.Table";
}
}
@@ -91,6 +91,30 @@ abstract class JavacJavaUtilListSetSingularizer extends JavacJavaUtilSingularize
returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
returnStatement = chain ? maker.Return(maker.Ident(thisName)) : null;
generatePluralMethod(maker, returnType, returnStatement, data, builderType, source, fluent);
returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
returnStatement = chain ? maker.Return(maker.Ident(thisName)) : null;
generateClearMethod(maker, returnType, returnStatement, data, builderType, source);
}
private void generateClearMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source) {
JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
List<JCTypeParameter> typeParams = List.nil();
List<JCExpression> thrown = List.nil();
List<JCVariableDecl> params = List.nil();
List<JCExpression> jceBlank = List.nil();
JCExpression thisDotField = maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName());
JCExpression thisDotFieldDotClear = maker.Select(maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName()), builderType.toName("clear"));
JCStatement clearCall = maker.Exec(maker.Apply(jceBlank, thisDotFieldDotClear, jceBlank));
JCExpression cond = maker.Binary(CTC_NOT_EQUAL, thisDotField, maker.Literal(CTC_BOT, null));
JCStatement ifSetCallClear = maker.If(cond, clearCall, null);
List<JCStatement> statements = returnStatement != null ? List.of(ifSetCallClear, returnStatement) : List.of(ifSetCallClear);
JCBlock body = maker.Block(0, statements);
Name methodName = builderType.toName(HandlerUtil.buildAccessorName("clear", data.getPluralName().toString()));
JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, params, thrown, body, null);
injectMethod(builderType, method);
}
void generateSingularMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
@@ -115,6 +115,33 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
returnStatement = chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
generatePluralMethod(maker, returnType, returnStatement, data, builderType, source, fluent);
returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
returnStatement = chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
generateClearMethod(maker, returnType, returnStatement, data, builderType, source);
}
private void generateClearMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source) {
JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
List<JCTypeParameter> typeParams = List.nil();
List<JCExpression> thrown = List.nil();
List<JCVariableDecl> params = List.nil();
List<JCExpression> jceBlank = List.nil();
JCExpression thisDotKeyField = chainDots(builderType, "this", data.getPluralName() + "$key");
JCExpression thisDotKeyFieldDotClear = chainDots(builderType, "this", data.getPluralName() + "$key", "clear");
JCExpression thisDotValueFieldDotClear = chainDots(builderType, "this", data.getPluralName() + "$value", "clear");
JCStatement clearKeyCall = maker.Exec(maker.Apply(jceBlank, thisDotKeyFieldDotClear, jceBlank));
JCStatement clearValueCall = maker.Exec(maker.Apply(jceBlank, thisDotValueFieldDotClear, jceBlank));
JCExpression cond = maker.Binary(CTC_NOT_EQUAL, thisDotKeyField, maker.Literal(CTC_BOT, null));
JCBlock clearCalls = maker.Block(0, List.of(clearKeyCall, clearValueCall));
JCStatement ifSetCallClear = maker.If(cond, clearCalls, null);
List<JCStatement> statements = returnStatement != null ? List.of(ifSetCallClear, returnStatement) : List.of(ifSetCallClear);
JCBlock body = maker.Block(0, statements);
Name methodName = builderType.toName(HandlerUtil.buildAccessorName("clear", data.getPluralName().toString()));
JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, params, thrown, body, null);
injectMethod(builderType, method);
}
private void generateSingularMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
@@ -0,0 +1,66 @@
import java.util.List;
class BuilderInstanceMethod<T> {
public String create(int show, final int yes, List<T> also, int $andMe) {
return "" + show + yes + also + $andMe;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public class StringBuilder {
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
private int show;
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
private int yes;
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
private List<T> also;
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
private int $andMe;
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
StringBuilder() {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public StringBuilder show(final int show) {
this.show = show;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public StringBuilder yes(final int yes) {
this.yes = yes;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public StringBuilder also(final List<T> also) {
this.also = also;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public StringBuilder $andMe(final int $andMe) {
this.$andMe = $andMe;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public String build() {
return BuilderInstanceMethod.this.create(show, yes, also, $andMe);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public java.lang.String toString() {
return "BuilderInstanceMethod.StringBuilder(show=" + this.show + ", yes=" + this.yes + ", also=" + this.also + ", $andMe=" + this.$andMe + ")";
}
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public StringBuilder builder() {
return new StringBuilder();
}
}
@@ -2,19 +2,22 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.ImmutableTable;
class BuilderSingularGuavaListsSets<T> {
private ImmutableList<T> cards;
private ImmutableCollection<? extends Number> frogs;
@SuppressWarnings("all")
private ImmutableSet rawSet;
private ImmutableSortedSet<String> passes;
private ImmutableTable<? extends Number, ? extends Number, String> users;
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
BuilderSingularGuavaListsSets(final ImmutableList<T> cards, final ImmutableCollection<? extends Number> frogs, final ImmutableSet rawSet, final ImmutableSortedSet<String> passes) {
BuilderSingularGuavaListsSets(final ImmutableList<T> cards, final ImmutableCollection<? extends Number> frogs, final ImmutableSet rawSet, final ImmutableSortedSet<String> passes, final ImmutableTable<? extends Number, ? extends Number, String> users) {
this.cards = cards;
this.frogs = frogs;
this.rawSet = rawSet;
this.passes = passes;
this.users = users;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
@@ -33,6 +36,9 @@ class BuilderSingularGuavaListsSets<T> {
private com.google.common.collect.ImmutableSortedSet.Builder<String> passes;
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
private com.google.common.collect.ImmutableTable.Builder<Number, Number, String> users;
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
BuilderSingularGuavaListsSetsBuilder() {
}
@java.lang.SuppressWarnings("all")
@@ -51,6 +57,12 @@ class BuilderSingularGuavaListsSets<T> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder<T> clearCards() {
this.cards = null;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder<T> frog(final Number frog) {
if (this.frogs == null) this.frogs = com.google.common.collect.ImmutableList.builder();
this.frogs.add(frog);
@@ -65,6 +77,12 @@ class BuilderSingularGuavaListsSets<T> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder<T> clearFrogs() {
this.frogs = null;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder<T> rawSet(final java.lang.Object rawSet) {
if (this.rawSet == null) this.rawSet = com.google.common.collect.ImmutableSet.builder();
this.rawSet.add(rawSet);
@@ -79,6 +97,12 @@ class BuilderSingularGuavaListsSets<T> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder<T> clearRawSet() {
this.rawSet = null;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder<T> pass(final String pass) {
if (this.passes == null) this.passes = com.google.common.collect.ImmutableSortedSet.naturalOrder();
this.passes.add(pass);
@@ -93,18 +117,45 @@ class BuilderSingularGuavaListsSets<T> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder<T> clearPasses() {
this.passes = null;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder<T> user(final Number rowKey, final Number columnKey, final String value) {
if (this.users == null) this.users = com.google.common.collect.ImmutableTable.builder();
this.users.put(rowKey, columnKey, value);
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder<T> users(final com.google.common.collect.Table<? extends Number, ? extends Number, ? extends String> users) {
if (this.users == null) this.users = com.google.common.collect.ImmutableTable.builder();
this.users.putAll(users);
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder<T> clearUsers() {
this.users = null;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSets<T> build() {
com.google.common.collect.ImmutableList<T> cards = this.cards == null ? com.google.common.collect.ImmutableList.<T>of() : this.cards.build();
com.google.common.collect.ImmutableCollection<Number> frogs = this.frogs == null ? com.google.common.collect.ImmutableList.<Number>of() : this.frogs.build();
com.google.common.collect.ImmutableSet<java.lang.Object> rawSet = this.rawSet == null ? com.google.common.collect.ImmutableSet.<java.lang.Object>of() : this.rawSet.build();
com.google.common.collect.ImmutableSortedSet<String> passes = this.passes == null ? com.google.common.collect.ImmutableSortedSet.<String>of() : this.passes.build();
return new BuilderSingularGuavaListsSets<T>(cards, frogs, rawSet, passes);
com.google.common.collect.ImmutableTable<Number, Number, String> users = this.users == null ? com.google.common.collect.ImmutableTable.<Number, Number, String>of() : this.users.build();
return new BuilderSingularGuavaListsSets<T>(cards, frogs, rawSet, passes, users);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public java.lang.String toString() {
return "BuilderSingularGuavaListsSets.BuilderSingularGuavaListsSetsBuilder(cards=" + this.cards + ", frogs=" + this.frogs + ", rawSet=" + this.rawSet + ", passes=" + this.passes + ")";
return "BuilderSingularGuavaListsSets.BuilderSingularGuavaListsSetsBuilder(cards=" + this.cards + ", frogs=" + this.frogs + ", rawSet=" + this.rawSet + ", passes=" + this.passes + ", users=" + this.users + ")";
}
}
@java.lang.SuppressWarnings("all")
@@ -31,9 +31,9 @@ class BuilderSingularGuavaMaps<K, V> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaMapsBuilder<K, V> battleaxe(final K battleaxe$key, final V battleaxe$value) {
public BuilderSingularGuavaMapsBuilder<K, V> battleaxe(final K key, final V value) {
if (this.battleaxes == null) this.battleaxes = com.google.common.collect.ImmutableMap.builder();
this.battleaxes.put(battleaxe$key, battleaxe$value);
this.battleaxes.put(key, value);
return this;
}
@java.lang.SuppressWarnings("all")
@@ -45,9 +45,15 @@ class BuilderSingularGuavaMaps<K, V> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaMapsBuilder<K, V> vertex(final Integer vertex$key, final V vertex$value) {
public BuilderSingularGuavaMapsBuilder<K, V> clearBattleaxes() {
this.battleaxes = null;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaMapsBuilder<K, V> vertex(final Integer key, final V value) {
if (this.vertices == null) this.vertices = com.google.common.collect.ImmutableSortedMap.naturalOrder();
this.vertices.put(vertex$key, vertex$value);
this.vertices.put(key, value);
return this;
}
@java.lang.SuppressWarnings("all")
@@ -59,9 +65,15 @@ class BuilderSingularGuavaMaps<K, V> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaMapsBuilder<K, V> rawMap(final java.lang.Object rawMap$key, final java.lang.Object rawMap$value) {
public BuilderSingularGuavaMapsBuilder<K, V> clearVertices() {
this.vertices = null;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaMapsBuilder<K, V> rawMap(final java.lang.Object key, final java.lang.Object value) {
if (this.rawMap == null) this.rawMap = com.google.common.collect.ImmutableBiMap.builder();
this.rawMap.put(rawMap$key, rawMap$value);
this.rawMap.put(key, value);
return this;
}
@java.lang.SuppressWarnings("all")
@@ -73,6 +85,12 @@ class BuilderSingularGuavaMaps<K, V> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaMapsBuilder<K, V> clearRawMap() {
this.rawMap = null;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularGuavaMaps<K, V> build() {
com.google.common.collect.ImmutableMap<K, V> battleaxes = this.battleaxes == null ? com.google.common.collect.ImmutableMap.<K, V>of() : this.battleaxes.build();
com.google.common.collect.ImmutableSortedMap<Integer, V> vertices = this.vertices == null ? com.google.common.collect.ImmutableSortedMap.<Integer, V>of() : this.vertices.build();
@@ -44,6 +44,12 @@ class BuilderSingularLists<T> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularListsBuilder<T> clearChildren() {
if (this.children != null) this.children.clear();
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularListsBuilder<T> scarf(final Number scarf) {
if (this.scarves == null) this.scarves = new java.util.ArrayList<Number>();
this.scarves.add(scarf);
@@ -58,6 +64,12 @@ class BuilderSingularLists<T> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularListsBuilder<T> clearScarves() {
if (this.scarves != null) this.scarves.clear();
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularListsBuilder<T> rawList(final java.lang.Object rawList) {
if (this.rawList == null) this.rawList = new java.util.ArrayList<java.lang.Object>();
this.rawList.add(rawList);
@@ -72,6 +84,12 @@ class BuilderSingularLists<T> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularListsBuilder<T> clearRawList() {
if (this.rawList != null) this.rawList.clear();
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularLists<T> build() {
java.util.List<T> children;
switch (this.children == null ? 0 : this.children.size()) {
@@ -57,6 +57,14 @@ class BuilderSingularMaps<K, V> {
return this;
}
@SuppressWarnings("all")
public BuilderSingularMapsBuilder<K, V> clearWomen() {
if (this.women$key != null) {
this.women$key.clear();
this.women$value.clear();
}
return this;
}
@SuppressWarnings("all")
public BuilderSingularMapsBuilder<K, V> man(K manKey, Number manValue) {
if (this.men$key == null) {
this.men$key = new java.util.ArrayList<K>();
@@ -79,6 +87,14 @@ class BuilderSingularMaps<K, V> {
return this;
}
@SuppressWarnings("all")
public BuilderSingularMapsBuilder<K, V> clearMen() {
if (this.men$key != null) {
this.men$key.clear();
this.men$value.clear();
}
return this;
}
@SuppressWarnings("all")
public BuilderSingularMapsBuilder<K, V> rawMap(Object rawMapKey, Object rawMapValue) {
if (this.rawMap$key == null) {
this.rawMap$key = new java.util.ArrayList<Object>();
@@ -101,6 +117,14 @@ class BuilderSingularMaps<K, V> {
return this;
}
@SuppressWarnings("all")
public BuilderSingularMapsBuilder<K, V> clearRawMap() {
if (this.rawMap$key != null) {
this.rawMap$key.clear();
this.rawMap$value.clear();
}
return this;
}
@SuppressWarnings("all")
public BuilderSingularMapsBuilder<K, V> stringMap(String stringMapKey, V stringMapValue) {
if (this.stringMap$key == null) {
this.stringMap$key = new java.util.ArrayList<String>();
@@ -123,6 +147,14 @@ class BuilderSingularMaps<K, V> {
return this;
}
@SuppressWarnings("all")
public BuilderSingularMapsBuilder<K, V> clearStringMap() {
if (this.stringMap$key != null) {
this.stringMap$key.clear();
this.stringMap$value.clear();
}
return this;
}
@SuppressWarnings("all")
public BuilderSingularMaps<K, V> build() {
java.util.Map<K, V> women;
switch (this.women$key == null ? 0 : this.women$key.size()) {
@@ -42,6 +42,12 @@ class BuilderSingularNoAuto {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularNoAutoBuilder clearThings() {
if (this.things != null) this.things.clear();
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularNoAutoBuilder widget(final String widget) {
if (this.widgets == null) this.widgets = new java.util.ArrayList<String>();
this.widgets.add(widget);
@@ -56,6 +62,12 @@ class BuilderSingularNoAuto {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularNoAutoBuilder clearWidgets() {
if (this.widgets != null) this.widgets.clear();
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularNoAutoBuilder items(final String items) {
if (this.items == null) this.items = new java.util.ArrayList<String>();
this.items.add(items);
@@ -70,6 +82,12 @@ class BuilderSingularNoAuto {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularNoAutoBuilder clearItems() {
if (this.items != null) this.items.clear();
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularNoAuto build() {
java.util.List<String> things;
switch (this.things == null ? 0 : this.things.size()) {
@@ -44,9 +44,15 @@ class BuilderSingularRedirectToGuava {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularRedirectToGuavaBuilder thing(final Integer thing$key, final Number thing$value) {
public BuilderSingularRedirectToGuavaBuilder clearDangerMice() {
this.dangerMice = null;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularRedirectToGuavaBuilder thing(final Integer key, final Number value) {
if (this.things == null) this.things = com.google.common.collect.ImmutableSortedMap.naturalOrder();
this.things.put(thing$key, thing$value);
this.things.put(key, value);
return this;
}
@java.lang.SuppressWarnings("all")
@@ -58,6 +64,12 @@ class BuilderSingularRedirectToGuava {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularRedirectToGuavaBuilder clearThings() {
this.things = null;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularRedirectToGuavaBuilder doohickey(final Class<?> doohickey) {
if (this.doohickeys == null) this.doohickeys = com.google.common.collect.ImmutableList.builder();
this.doohickeys.add(doohickey);
@@ -72,6 +84,12 @@ class BuilderSingularRedirectToGuava {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularRedirectToGuavaBuilder clearDoohickeys() {
this.doohickeys = null;
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularRedirectToGuava build() {
java.util.Set<String> dangerMice = this.dangerMice == null ? com.google.common.collect.ImmutableSet.<String>of() : this.dangerMice.build();
java.util.NavigableMap<Integer, Number> things = this.things == null ? com.google.common.collect.ImmutableSortedMap.<Integer, Number>of() : this.things.build();
@@ -49,6 +49,12 @@ class BuilderSingularSets<T> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularSetsBuilder<T> clearDangerMice() {
if (this.dangerMice != null) this.dangerMice.clear();
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularSetsBuilder<T> octopus(final Number octopus) {
if (this.octopodes == null) this.octopodes = new java.util.ArrayList<Number>();
this.octopodes.add(octopus);
@@ -63,6 +69,12 @@ class BuilderSingularSets<T> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularSetsBuilder<T> clearOctopodes() {
if (this.octopodes != null) this.octopodes.clear();
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularSetsBuilder<T> rawSet(final java.lang.Object rawSet) {
if (this.rawSet == null) this.rawSet = new java.util.ArrayList<java.lang.Object>();
this.rawSet.add(rawSet);
@@ -77,6 +89,12 @@ class BuilderSingularSets<T> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularSetsBuilder<T> clearRawSet() {
if (this.rawSet != null) this.rawSet.clear();
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularSetsBuilder<T> stringSet(final String stringSet) {
if (this.stringSet == null) this.stringSet = new java.util.ArrayList<String>();
this.stringSet.add(stringSet);
@@ -91,6 +109,12 @@ class BuilderSingularSets<T> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularSetsBuilder<T> clearStringSet() {
if (this.stringSet != null) this.stringSet.clear();
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderSingularSets<T> build() {
java.util.Set<T> dangerMice;
switch (this.dangerMice == null ? 0 : this.dangerMice.size()) {
@@ -68,6 +68,12 @@ class BuilderWithToBuilder<T> {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderWithToBuilderBuilder<T> clearBars() {
if (this.bars != null) this.bars.clear();
return this;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public BuilderWithToBuilder<T> build() {
java.util.List<T> bars;
switch (this.bars == null ? 0 : this.bars.size()) {
@@ -0,0 +1,43 @@
import java.util.List;
class BuilderInstanceMethod<T> {
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") class StringBuilder {
private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") int show;
private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") int yes;
private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") List<T> also;
private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") int $andMe;
@java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") StringBuilder() {
super();
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") StringBuilder show(final int show) {
this.show = show;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") StringBuilder yes(final int yes) {
this.yes = yes;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") StringBuilder also(final List<T> also) {
this.also = also;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") StringBuilder $andMe(final int $andMe) {
this.$andMe = $andMe;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") String build() {
return BuilderInstanceMethod.this.create(show, yes, also, $andMe);
}
public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() {
return (((((((("BuilderInstanceMethod.StringBuilder(show=" + this.show) + ", yes=") + this.yes) + ", also=") + this.also) + ", $andMe=") + this.$andMe) + ")");
}
}
BuilderInstanceMethod() {
super();
}
public @lombok.Builder String create(int show, final int yes, List<T> also, int $andMe) {
return (((("" + show) + yes) + also) + $andMe);
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") StringBuilder builder() {
return new StringBuilder();
}
}
@@ -2,6 +2,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.ImmutableTable;
import lombok.Singular;
@lombok.Builder class BuilderSingularGuavaListsSets<T> {
public static @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") class BuilderSingularGuavaListsSetsBuilder<T> {
@@ -9,6 +10,7 @@ import lombok.Singular;
private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") com.google.common.collect.ImmutableList.Builder<Number> frogs;
private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") com.google.common.collect.ImmutableSet.Builder<java.lang.Object> rawSet;
private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") com.google.common.collect.ImmutableSortedSet.Builder<String> passes;
private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") com.google.common.collect.ImmutableTable.Builder<Number, Number, String> users;
@java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder() {
super();
}
@@ -24,6 +26,10 @@ import lombok.Singular;
this.cards.addAll(cards);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder<T> clearCards() {
this.cards = null;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder<T> frog(Number frog) {
if ((this.frogs == null))
this.frogs = com.google.common.collect.ImmutableList.builder();
@@ -36,6 +42,10 @@ import lombok.Singular;
this.frogs.addAll(frogs);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder<T> clearFrogs() {
this.frogs = null;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder<T> rawSet(java.lang.Object rawSet) {
if ((this.rawSet == null))
this.rawSet = com.google.common.collect.ImmutableSet.builder();
@@ -48,6 +58,10 @@ import lombok.Singular;
this.rawSet.addAll(rawSet);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder<T> clearRawSet() {
this.rawSet = null;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder<T> pass(String pass) {
if ((this.passes == null))
this.passes = com.google.common.collect.ImmutableSortedSet.naturalOrder();
@@ -60,27 +74,50 @@ import lombok.Singular;
this.passes.addAll(passes);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder<T> clearPasses() {
this.passes = null;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder<T> user(Number rowKey, Number columnKey, String value) {
if ((this.users == null))
this.users = com.google.common.collect.ImmutableTable.builder();
this.users.put(rowKey, columnKey, value);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder<T> users(com.google.common.collect.Table<? extends Number, ? extends Number, ? extends String> users) {
if ((this.users == null))
this.users = com.google.common.collect.ImmutableTable.builder();
this.users.putAll(users);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder<T> clearUsers() {
this.users = null;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSets<T> build() {
com.google.common.collect.ImmutableList<T> cards = ((this.cards == null) ? com.google.common.collect.ImmutableList.<T>of() : this.cards.build());
com.google.common.collect.ImmutableCollection<Number> frogs = ((this.frogs == null) ? com.google.common.collect.ImmutableList.<Number>of() : this.frogs.build());
com.google.common.collect.ImmutableSet<java.lang.Object> rawSet = ((this.rawSet == null) ? com.google.common.collect.ImmutableSet.<java.lang.Object>of() : this.rawSet.build());
com.google.common.collect.ImmutableSortedSet<String> passes = ((this.passes == null) ? com.google.common.collect.ImmutableSortedSet.<String>of() : this.passes.build());
return new BuilderSingularGuavaListsSets<T>(cards, frogs, rawSet, passes);
com.google.common.collect.ImmutableTable<Number, Number, String> users = ((this.users == null) ? com.google.common.collect.ImmutableTable.<Number, Number, String>of() : this.users.build());
return new BuilderSingularGuavaListsSets<T>(cards, frogs, rawSet, passes, users);
}
public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() {
return (((((((("BuilderSingularGuavaListsSets.BuilderSingularGuavaListsSetsBuilder(cards=" + this.cards) + ", frogs=") + this.frogs) + ", rawSet=") + this.rawSet) + ", passes=") + this.passes) + ")");
return (((((((((("BuilderSingularGuavaListsSets.BuilderSingularGuavaListsSetsBuilder(cards=" + this.cards) + ", frogs=") + this.frogs) + ", rawSet=") + this.rawSet) + ", passes=") + this.passes) + ", users=") + this.users) + ")");
}
}
private @Singular ImmutableList<T> cards;
private @Singular ImmutableCollection<? extends Number> frogs;
private @SuppressWarnings("all") @Singular("rawSet") ImmutableSet rawSet;
private @Singular ImmutableSortedSet<String> passes;
@java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSets(final ImmutableList<T> cards, final ImmutableCollection<? extends Number> frogs, final ImmutableSet rawSet, final ImmutableSortedSet<String> passes) {
private @Singular ImmutableTable<? extends Number, ? extends Number, String> users;
@java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSets(final ImmutableList<T> cards, final ImmutableCollection<? extends Number> frogs, final ImmutableSet rawSet, final ImmutableSortedSet<String> passes, final ImmutableTable<? extends Number, ? extends Number, String> users) {
super();
this.cards = cards;
this.frogs = frogs;
this.rawSet = rawSet;
this.passes = passes;
this.users = users;
}
public static @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") <T>BuilderSingularGuavaListsSetsBuilder<T> builder() {
return new BuilderSingularGuavaListsSetsBuilder<T>();
@@ -10,10 +10,10 @@ import lombok.Singular;
@java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder() {
super();
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder<K, V> battleaxe(K battleaxe$key, V battleaxe$value) {
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder<K, V> battleaxe(K key, V value) {
if ((this.battleaxes == null))
this.battleaxes = com.google.common.collect.ImmutableMap.builder();
this.battleaxes.put(battleaxe$key, battleaxe$value);
this.battleaxes.put(key, value);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder<K, V> battleaxes(java.util.Map<? extends K, ? extends V> battleaxes) {
@@ -22,10 +22,14 @@ import lombok.Singular;
this.battleaxes.putAll(battleaxes);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder<K, V> vertex(Integer vertex$key, V vertex$value) {
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder<K, V> clearBattleaxes() {
this.battleaxes = null;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder<K, V> vertex(Integer key, V value) {
if ((this.vertices == null))
this.vertices = com.google.common.collect.ImmutableSortedMap.naturalOrder();
this.vertices.put(vertex$key, vertex$value);
this.vertices.put(key, value);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder<K, V> vertices(java.util.Map<? extends Integer, ? extends V> vertices) {
@@ -34,10 +38,14 @@ import lombok.Singular;
this.vertices.putAll(vertices);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder<K, V> rawMap(java.lang.Object rawMap$key, java.lang.Object rawMap$value) {
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder<K, V> clearVertices() {
this.vertices = null;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder<K, V> rawMap(java.lang.Object key, java.lang.Object value) {
if ((this.rawMap == null))
this.rawMap = com.google.common.collect.ImmutableBiMap.builder();
this.rawMap.put(rawMap$key, rawMap$value);
this.rawMap.put(key, value);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder<K, V> rawMap(java.util.Map<?, ?> rawMap) {
@@ -46,6 +54,10 @@ import lombok.Singular;
this.rawMap.putAll(rawMap);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMapsBuilder<K, V> clearRawMap() {
this.rawMap = null;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaMaps<K, V> build() {
com.google.common.collect.ImmutableMap<K, V> battleaxes = ((this.battleaxes == null) ? com.google.common.collect.ImmutableMap.<K, V>of() : this.battleaxes.build());
com.google.common.collect.ImmutableSortedMap<Integer, V> vertices = ((this.vertices == null) ? com.google.common.collect.ImmutableSortedMap.<Integer, V>of() : this.vertices.build());
@@ -22,6 +22,11 @@ import lombok.Singular;
this.children.addAll(children);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularListsBuilder<T> clearChildren() {
if ((this.children != null))
this.children.clear();
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularListsBuilder<T> scarf(Number scarf) {
if ((this.scarves == null))
this.scarves = new java.util.ArrayList<Number>();
@@ -34,6 +39,11 @@ import lombok.Singular;
this.scarves.addAll(scarves);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularListsBuilder<T> clearScarves() {
if ((this.scarves != null))
this.scarves.clear();
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularListsBuilder<T> rawList(java.lang.Object rawList) {
if ((this.rawList == null))
this.rawList = new java.util.ArrayList<java.lang.Object>();
@@ -46,6 +56,11 @@ import lombok.Singular;
this.rawList.addAll(rawList);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularListsBuilder<T> clearRawList() {
if ((this.rawList != null))
this.rawList.clear();
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularLists<T> build() {
java.util.List<T> children;
switch (((this.children == null) ? 0 : this.children.size())) {
@@ -37,6 +37,14 @@ import lombok.Singular;
}
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularMapsBuilder<K, V> clearWomen() {
if ((this.women$key != null))
{
this.women$key.clear();
this.women$value.clear();
}
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularMapsBuilder<K, V> man(K manKey, Number manValue) {
if ((this.men$key == null))
{
@@ -60,6 +68,14 @@ import lombok.Singular;
}
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularMapsBuilder<K, V> clearMen() {
if ((this.men$key != null))
{
this.men$key.clear();
this.men$value.clear();
}
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularMapsBuilder<K, V> rawMap(java.lang.Object rawMapKey, java.lang.Object rawMapValue) {
if ((this.rawMap$key == null))
{
@@ -83,6 +99,14 @@ import lombok.Singular;
}
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularMapsBuilder<K, V> clearRawMap() {
if ((this.rawMap$key != null))
{
this.rawMap$key.clear();
this.rawMap$value.clear();
}
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularMapsBuilder<K, V> stringMap(String stringMapKey, V stringMapValue) {
if ((this.stringMap$key == null))
{
@@ -106,6 +130,14 @@ import lombok.Singular;
}
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularMapsBuilder<K, V> clearStringMap() {
if ((this.stringMap$key != null))
{
this.stringMap$key.clear();
this.stringMap$value.clear();
}
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularMaps<K, V> build() {
java.util.Map<K, V> women;
switch (((this.women$key == null) ? 0 : this.women$key.size())) {
@@ -20,6 +20,11 @@ import lombok.Singular;
this.things.addAll(things);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularNoAutoBuilder clearThings() {
if ((this.things != null))
this.things.clear();
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularNoAutoBuilder widget(String widget) {
if ((this.widgets == null))
this.widgets = new java.util.ArrayList<String>();
@@ -32,6 +37,11 @@ import lombok.Singular;
this.widgets.addAll(widgets);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularNoAutoBuilder clearWidgets() {
if ((this.widgets != null))
this.widgets.clear();
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularNoAutoBuilder items(String items) {
if ((this.items == null))
this.items = new java.util.ArrayList<String>();
@@ -44,6 +54,11 @@ import lombok.Singular;
this.items.addAll(items);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularNoAutoBuilder clearItems() {
if ((this.items != null))
this.items.clear();
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularNoAuto build() {
java.util.List<String> things;
switch (((this.things == null) ? 0 : this.things.size())) {
@@ -22,10 +22,14 @@ import lombok.Singular;
this.dangerMice.addAll(dangerMice);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularRedirectToGuavaBuilder thing(Integer thing$key, Number thing$value) {
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularRedirectToGuavaBuilder clearDangerMice() {
this.dangerMice = null;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularRedirectToGuavaBuilder thing(Integer key, Number value) {
if ((this.things == null))
this.things = com.google.common.collect.ImmutableSortedMap.naturalOrder();
this.things.put(thing$key, thing$value);
this.things.put(key, value);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularRedirectToGuavaBuilder things(java.util.Map<? extends Integer, ? extends Number> things) {
@@ -34,6 +38,10 @@ import lombok.Singular;
this.things.putAll(things);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularRedirectToGuavaBuilder clearThings() {
this.things = null;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularRedirectToGuavaBuilder doohickey(Class<?> doohickey) {
if ((this.doohickeys == null))
this.doohickeys = com.google.common.collect.ImmutableList.builder();
@@ -46,6 +54,10 @@ import lombok.Singular;
this.doohickeys.addAll(doohickeys);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularRedirectToGuavaBuilder clearDoohickeys() {
this.doohickeys = null;
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularRedirectToGuava build() {
java.util.Set<String> dangerMice = ((this.dangerMice == null) ? com.google.common.collect.ImmutableSet.<String>of() : this.dangerMice.build());
java.util.NavigableMap<Integer, Number> things = ((this.things == null) ? com.google.common.collect.ImmutableSortedMap.<Integer, Number>of() : this.things.build());
@@ -22,6 +22,11 @@ import lombok.Singular;
this.dangerMice.addAll(dangerMice);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularSetsBuilder<T> clearDangerMice() {
if ((this.dangerMice != null))
this.dangerMice.clear();
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularSetsBuilder<T> octopus(Number octopus) {
if ((this.octopodes == null))
this.octopodes = new java.util.ArrayList<Number>();
@@ -34,6 +39,11 @@ import lombok.Singular;
this.octopodes.addAll(octopodes);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularSetsBuilder<T> clearOctopodes() {
if ((this.octopodes != null))
this.octopodes.clear();
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularSetsBuilder<T> rawSet(java.lang.Object rawSet) {
if ((this.rawSet == null))
this.rawSet = new java.util.ArrayList<java.lang.Object>();
@@ -46,6 +56,11 @@ import lombok.Singular;
this.rawSet.addAll(rawSet);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularSetsBuilder<T> clearRawSet() {
if ((this.rawSet != null))
this.rawSet.clear();
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularSetsBuilder<T> stringSet(String stringSet) {
if ((this.stringSet == null))
this.stringSet = new java.util.ArrayList<String>();
@@ -58,6 +73,11 @@ import lombok.Singular;
this.stringSet.addAll(stringSet);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularSetsBuilder<T> clearStringSet() {
if ((this.stringSet != null))
this.stringSet.clear();
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularSets<T> build() {
java.util.Set<T> dangerMice;
switch (((this.dangerMice == null) ? 0 : this.dangerMice.size())) {
@@ -33,6 +33,11 @@ import lombok.Builder;
this.bars.addAll(bars);
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderWithToBuilderBuilder<T> clearBars() {
if ((this.bars != null))
this.bars.clear();
return this;
}
public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderWithToBuilder<T> build() {
java.util.List<T> bars;
switch (((this.bars == null) ? 0 : this.bars.size())) {
@@ -0,0 +1,8 @@
import java.util.List;
class BuilderInstanceMethod<T> {
@lombok.Builder
public String create(int show, final int yes, List<T> also, int $andMe) {
return "" + show + yes + also + $andMe;
}
}
@@ -2,6 +2,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.ImmutableTable;
import lombok.Singular;
@@ -11,4 +12,5 @@ class BuilderSingularGuavaListsSets<T> {
@Singular private ImmutableCollection<? extends Number> frogs;
@SuppressWarnings("all") @Singular("rawSet") private ImmutableSet rawSet;
@Singular private ImmutableSortedSet<String> passes;
@Singular private ImmutableTable<? extends Number, ? extends Number, String> users;
}
+8
View File
@@ -51,6 +51,14 @@ public class BuilderExample {
return this;
}
public BuilderExampleBuilder clearOccupations() {
if (this.occupations != null) {
this.occupations.clear();
}
return this;
}
public BuilderExample build() {
// complicated switch statement to produce a compact properly sized immutable set omitted.
// go to https://projectlombok.org/features/Singular-snippet.html to see it.
+14 -12
View File
@@ -18,7 +18,8 @@
<code>@Builder</code> was introduced as experimental feature in lombok v0.12.0.
</p><p>
<code>@Builder</code> gained <code>@Singular</code> support and was promoted to the main <code>lombok</code> package since lombok v1.16.0.
</p>
</p><p>
<code>@Builder</code> with <code>@Singular</code> adds a clear method since lombok v1.16.8.
</div>
<div class="overview">
<h3>Overview</h3>
@@ -28,16 +29,16 @@
<code>@Builder</code> lets you automatically produce the code required to have your class be instantiable with code such as:<br />
<code>Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build();</code>
</p><p>
<code>@Builder</code> can be placed on a class, or on a constructor, or on a static method. While the "on a class" and "on a constructor"
mode are the most common use-case, <code>@Builder</code> is most easily explained with the "static method" use-case.
<code>@Builder</code> can be placed on a class, or on a constructor, or on a method. While the "on a class" and "on a constructor"
mode are the most common use-case, <code>@Builder</code> is most easily explained with the "method" use-case.
</p><p>
A static method annotated with <code>@Builder</code> (from now on called the <em>target</em>) causes the following 7 things to be generated:<ul>
<li>An inner static class named <code><em>Foo</em>Builder</code>, with the same type arguments as the static method (called the <em>builder</em>).</li>
A method annotated with <code>@Builder</code> (from now on called the <em>target</em>) causes the following 7 things to be generated:<ul>
<li>An inner class named <code><em>Foo</em>Builder</code>, with the same type arguments as the method (called the <em>builder</em>).</li>
<li>In the <em>builder</em>: One private non-static non-final field for each parameter of the <em>target</em>.</li>
<li>In the <em>builder</em>: A package private no-args empty constructor.</li>
<li>In the <em>builder</em>: A 'setter'-like method for each parameter of the <em>target</em>: It has the same type as that parameter and the same name.
It returns the builder itself, so that the setter calls can be chained, as in the above example.</li>
<li>In the <em>builder</em>: A <code>build()</code> method which calls the static method, passing in each field. It returns the same type that the
<li>In the <em>builder</em>: A <code>build()</code> method which calls the method, passing in each field. It returns the same type that the
<em>target</em> returns.</li>
<li>In the <em>builder</em>: A sensible <code>toString()</code> implementation.</li>
<li>In the class containing the <em>target</em>: A static <code>builder()</code> method, which creates a new instance of the <em>builder</em>.</li>
@@ -51,7 +52,7 @@
element to the list. For example: <code>Person.builder().job("Mythbusters").job("Unchained Reaction").build();</code> would result in the <code>List&lt;String&gt; jobs</code>
field to have 2 strings in it. To get this behaviour, the field/parameter needs to be annotated with <code>@Singular</code>. The feature has <a href="#singular">its own documentation</a>.
</p><p>
Now that the "static method" mode is clear, putting a <code>@Builder</code> annotation on a constructor functions similarly; effectively,
Now that the "method" mode is clear, putting a <code>@Builder</code> annotation on a constructor functions similarly; effectively,
constructors are just static methods that have a special syntax to invoke them: Their 'return type' is the class they construct, and their
type parameters are the same as the type parameters of the class itself.
</p><p>
@@ -63,8 +64,8 @@
</p><p>
The name of the builder class is <code><em>Foobar</em>Builder</code>, where <em>Foobar</em> is the simplified, title-cased form of the return type of the
<em>target</em> - that is, the name of your type for <code>@Builder</code> on constructors and types, and the name of the return type for <code>@Builder</code>
on static methods. For example, if <code>@Builder</code> is applied to a class named <code>com.yoyodyne.FancyList&lt;T&gt;</code>, then the builder name will be
<code>FancyListBuilder&lt;T&gt;</code>. If <code>@Builder</code> is applied to a static method that returns <code>void</code>, the builder will be named
on methods. For example, if <code>@Builder</code> is applied to a class named <code>com.yoyodyne.FancyList&lt;T&gt;</code>, then the builder name will be
<code>FancyListBuilder&lt;T&gt;</code>. If <code>@Builder</code> is applied to a method that returns <code>void</code>, the builder will be named
<code>VoidBuilder</code>.
</p><p>
The configurable aspects of builder are:<ul>
@@ -80,13 +81,13 @@
<div class="overview">
<h3><a name="singular">@Singular</a></h3>
<p>
By annotating one of the parameters (if annotating a static method or constructor with <code>@Builder</code>) or fields (if annotating a class with <code>@Builder</code>) with the
By annotating one of the parameters (if annotating a method or constructor with <code>@Builder</code>) or fields (if annotating a class with <code>@Builder</code>) with the
<code>@Singular</code> annotation, lombok will treat that builder node as a collection, and it generates 2 'adder' methods instead of a 'setter' method. One which adds a single element to the collection, and one
which adds all elements of another collection to the collection. No setter to just set the collection (replacing whatever was already added) will be generated. These 'singular' builders
which adds all elements of another collection to the collection. No setter to just set the collection (replacing whatever was already added) will be generated. A 'clear' method is also generated. These 'singular' builders
are very complicated in order to guarantee the following properties:
<ul>
<li>When invoking <code>build()</code>, the produced collection will be immutable.</li>
<li>Calling one of the 'adder' methods after invoking <code>build()</code> does not modify any already generated objects, and, if <code>build()</code> is later called again, another collection with all the elements added since the creation of the builder is generated.</li>
<li>Calling one of the 'adder' methods, or the 'clear' method, after invoking <code>build()</code> does not modify any already generated objects, and, if <code>build()</code> is later called again, another collection with all the elements added since the creation of the builder is generated.</li>
<li>The produced collection will be compacted to the smallest feasible format while remaining efficient.</li>
</ul>
</p><p>
@@ -101,6 +102,7 @@
<li><code>ImmutableCollection</code> and <code>ImmutableList</code> (backed by the builder feature of <code>ImmutableList</code>).</li>
<li><code>ImmutableSet</code> and <code>ImmutableSortedSet</code> (backed by the builder feature of those types).</li>
<li><code>ImmutableMap</code>, <code>ImmutableBiMap</code>, and <code>ImmutableSortedMap</code> (backed by the builder feature of those types).</li>
<li><code>ImmutableTable</code> (backed by the builder feature of <code>ImmutableTable</code>).</li>
</ul></li>
</ul>
</p><p>