From 14af3bec3b601d52c6a34710a63e22fceebf8dde Mon Sep 17 00:00:00 2001
From: Enrique da Costa Cambio
Date: Tue, 17 Mar 2015 18:13:27 -0700
Subject: Allow @Builder on instance methods
---
website/features/Builder.html | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
(limited to 'website/features')
diff --git a/website/features/Builder.html b/website/features/Builder.html
index b4731b07..033e49e4 100644
--- a/website/features/Builder.html
+++ b/website/features/Builder.html
@@ -28,16 +28,16 @@
@Builder lets you automatically produce the code required to have your class be instantiable with code such as: Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build();
- @Builder 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, @Builder is most easily explained with the "static method" use-case.
+ @Builder 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, @Builder is most easily explained with the "method" use-case.
- A static method annotated with @Builder (from now on called the target) causes the following 7 things to be generated:
-
An inner static class named FooBuilder, with the same type arguments as the static method (called the builder).
+ A method annotated with @Builder (from now on called the target) causes the following 7 things to be generated:
+
An inner class named FooBuilder, with the same type arguments as the method (called the builder).
In the builder: One private non-static non-final field for each parameter of the target.
In the builder: A package private no-args empty constructor.
In the builder: A 'setter'-like method for each parameter of the target: 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.
-
In the builder: A build() method which calls the static method, passing in each field. It returns the same type that the
+
In the builder: A build() method which calls the method, passing in each field. It returns the same type that the
target returns.
In the builder: A sensible toString() implementation.
In the class containing the target: A builder() method, which creates a new instance of the builder.
@@ -51,7 +51,7 @@
element to the list. For example: Person.builder().job("Mythbusters").job("Unchained Reaction").build(); would result in the List<String> jobs
field to have 2 strings in it. To get this behaviour, the field/parameter needs to be annotated with @Singular. The feature has its own documentation.
- Now that the "static method" mode is clear, putting a @Builder annotation on a constructor functions similarly; effectively,
+ Now that the "method" mode is clear, putting a @Builder 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.
@@ -61,8 +61,8 @@
The name of the builder class is FoobarBuilder, where Foobar is the simplified, title-cased form of the return type of the
target - that is, the name of your type for @Builder on constructors and types, and the name of the return type for @Builder
- on static methods. For example, if @Builder is applied to a class named com.yoyodyne.FancyList<T>, then the builder name will be
- FancyListBuilder<T>. If @Builder is applied to a static method that returns void, the builder will be named
+ on methods. For example, if @Builder is applied to a class named com.yoyodyne.FancyList<T>, then the builder name will be
+ FancyListBuilder<T>. If @Builder is applied to a method that returns void, the builder will be named
VoidBuilder.
- By annotating one of the parameters (if annotating a static method or constructor with @Builder) or fields (if annotating a class with @Builder) with the
+ By annotating one of the parameters (if annotating a method or constructor with @Builder) or fields (if annotating a class with @Builder) with the
@Singular 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
are very complicated in order to guarantee the following properties:
--
cgit
From db8281f7f5c027c24cf9a1a8208a2aa92d06a73d Mon Sep 17 00:00:00 2001
From: spc
Date: Sun, 4 Oct 2015 09:23:28 +0200
Subject: Added support for builder singular for Guavas ImmutableTable
---
src/core/lombok/core/GuavaTypeMap.java | 17 +--
.../singulars/EclipseGuavaSetListSingularizer.java | 16 +--
.../singulars/EclipseGuavaSingularizer.java | 139 +++++++++++++--------
.../singulars/JavacGuavaSetListSingularizer.java | 22 ++--
.../handlers/singulars/JavacGuavaSingularizer.java | 119 +++++++++++-------
.../BuilderSingularGuavaListsSets.java | 27 +++-
.../after-ecj/BuilderSingularGuavaListsSets.java | 23 +++-
.../before/BuilderSingularGuavaListsSets.java | 2 +
website/features/Builder.html | 1 +
9 files changed, 239 insertions(+), 127 deletions(-)
(limited to 'website/features')
diff --git a/src/core/lombok/core/GuavaTypeMap.java b/src/core/lombok/core/GuavaTypeMap.java
index 900d2b72..e84a32be 100644
--- a/src/core/lombok/core/GuavaTypeMap.java
+++ b/src/core/lombok/core/GuavaTypeMap.java
@@ -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
@@ -28,7 +28,7 @@ import java.util.Map;
public final class GuavaTypeMap {
private static final Map TYPE_TO_GUAVA_TYPE; static {
Map m = new HashMap();
-
+
m.put("java.util.NavigableSet", "ImmutableSortedSet");
m.put("java.util.NavigableMap", "ImmutableSortedMap");
m.put("java.util.SortedSet", "ImmutableSortedSet");
@@ -37,7 +37,7 @@ public final class GuavaTypeMap {
m.put("java.util.Map", "ImmutableMap");
m.put("java.util.Collection", "ImmutableList");
m.put("java.util.List", "ImmutableList");
-
+
m.put("com.google.common.collect.ImmutableSet", "ImmutableSet");
m.put("com.google.common.collect.ImmutableSortedSet", "ImmutableSortedSet");
m.put("com.google.common.collect.ImmutableMap", "ImmutableMap");
@@ -45,14 +45,15 @@ 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);
}
-
+
public static String getGuavaTypeName(String fqn) {
String target = TYPE_TO_GUAVA_TYPE.get(fqn);
return target != null ? target : "ImmutableList";
}
-
+
private GuavaTypeMap() {}
}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java
index bc2893bf..e2ca1270 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java
@@ -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
@@ -28,15 +28,15 @@ 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
@Override public LombokImmutableList getSupportedTypes() {
return LombokImmutableList.of(
- "com.google.common.collect.ImmutableCollection",
- "com.google.common.collect.ImmutableList",
- "com.google.common.collect.ImmutableSet",
- "com.google.common.collect.ImmutableSortedSet");
+ "com.google.common.collect.ImmutableCollection",
+ "com.google.common.collect.ImmutableList",
+ "com.google.common.collect.ImmutableSet",
+ "com.google.common.collect.ImmutableSortedSet",
+ "com.google.common.collect.ImmutableTable");
}
@Override protected boolean isMap() {
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
index fa121328..c3a4c314 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
@@ -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
@@ -28,12 +28,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import lombok.core.GuavaTypeMap;
-import lombok.core.handlers.HandlerUtil;
-import lombok.eclipse.EclipseNode;
-import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
-import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData;
-
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.Assignment;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
@@ -59,23 +53,32 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import lombok.core.GuavaTypeMap;
+import lombok.core.handlers.HandlerUtil;
+import lombok.eclipse.EclipseNode;
+import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
+import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData;
+
abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
protected static final char[][] JAVA_UTIL_MAP = {
{'j', 'a', 'v', 'a'}, {'u', 't', 'i', 'l'}, {'M', 'a', 'p'}
};
-
+ protected static final char[][] GUAVA_COLLECT_TABLE = {
+ {'c', 'o', 'm'}, {'g', 'o', 'o', 'g', 'l', 'e'}, {'c', 'o', 'm', 'm', 'o', 'n'}, {'c', 'o', 'l', 'l', 'e', 'c', 't'}, {'T', 'a', 'b', 'l', 'e'}
+ };
+
protected String getSimpleTargetTypeName(SingularData data) {
return GuavaTypeMap.getGuavaTypeName(data.getTargetFqn());
}
-
+
protected char[] getBuilderMethodName(SingularData data) {
String simpleTypeName = getSimpleTargetTypeName(data);
if ("ImmutableSortedSet".equals(simpleTypeName) || "ImmutableSortedMap".equals(simpleTypeName)) return "naturalOrder".toCharArray();
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'};
@@ -86,12 +89,13 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
if (addBuilder) tokenizedName[5] = new char[] { 'B', 'u', 'i', 'l', 'd', 'e', 'r'};
return tokenizedName;
}
-
+
@Override public List 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(getTypeAgrumentsCount(isMap(), simpleTypeName), false, builderType, type, data.getTypeArgs());
+
FieldDeclaration buildField = new FieldDeclaration(data.getPluralName(), 0, -1);
buildField.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
buildField.modifiers = ClassFileConstants.AccPrivate;
@@ -100,29 +104,29 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
data.setGeneratedByRecursive(buildField);
return Collections.singletonList(injectFieldAndMarkGenerated(builderType, buildField));
}
-
+
@Override public void generateMethods(SingularData data, EclipseNode builderType, boolean fluent, boolean chain) {
TypeReference returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
Statement returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
generateSingularMethod(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;
generatePluralMethod(returnType, returnStatement, data, builderType, fluent);
}
-
+
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();
-
+
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = ClassFileConstants.AccPublic;
-
+
List statements = new ArrayList();
statements.add(createConstructBuilderVarIfNeeded(data, builderType));
-
+
FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
thisDotField.receiver = new ThisReference(0, 0);
MessageSend thisDotFieldDotAdd = new MessageSend();
@@ -134,11 +138,11 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
thisDotFieldDotAdd.arguments = new Expression[] {new SingleNameReference(keyName, 0L)};
}
thisDotFieldDotAdd.receiver = thisDotField;
- thisDotFieldDotAdd.selector = (mapMode ? "put" : "add").toCharArray();
+ thisDotFieldDotAdd.selector = (shouldUsePut(data, mapMode) ? "put" : "add").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);
@@ -146,68 +150,87 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
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);
+ final Argument param;
+
+ if (isSpecialTypeOfListSet(data)) {
+ char[][] cellTypeName = makeGuavaTypeName("Table", true);
+ cellTypeName[5] = new char[] { 'C', 'e', 'l', 'l' };
+ TypeReference type = new QualifiedTypeReference(cellTypeName, NULL_POSS);
+ type = addTypeArgs(3, false, builderType, type, data.getTypeArgs());
+
+ param = new Argument(keyName, 0, type, 0);
+ } else {
+ TypeReference paramType = cloneParamType(0, data.getTypeArgs(), builderType);
+ param = new Argument(keyName, 0, paramType, 0);
+ }
+
md.arguments = new Argument[] {param};
}
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(shouldUsePut(data, mapMode) ? "put" : "add", 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;
-
+
List statements = new ArrayList();
statements.add(createConstructBuilderVarIfNeeded(data, builderType));
-
+
FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
thisDotField.receiver = new ThisReference(0, 0);
MessageSend thisDotFieldDotAddAll = new MessageSend();
thisDotFieldDotAddAll.arguments = new Expression[] {new SingleNameReference(data.getPluralName(), 0L)};
thisDotFieldDotAddAll.receiver = thisDotField;
- thisDotFieldDotAddAll.selector = (mapMode ? "putAll" : "addAll").toCharArray();
+ thisDotFieldDotAddAll.selector = (shouldUsePut(data, mapMode) ? "putAll" : "addAll").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());
+ if (isSpecialTypeOfListSet(data)) {
+ paramType = new QualifiedTypeReference(GUAVA_COLLECT_TABLE, NULL_POSS);
+ } else {
+ paramType = new QualifiedTypeReference(TypeConstants.JAVA_LANG_ITERABLE, NULL_POSS);
+ }
+
+ paramType = addTypeArgs(getListSetTypeArgumentsCount(getSimpleTargetTypeName(data)), 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(shouldUsePut(data, mapMode) ? "putAll" : "addAll", new String(data.getPluralName())).toCharArray();
+
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
-
+
@Override public void appendBuildCode(SingularData data, EclipseNode builderType, List 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 = getTypeAgrumentsCount(mapMode, simpleTypeName);
+ 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; {
//this.pluralName.build();
invokeBuild = new MessageSend();
@@ -216,32 +239,48 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
thisDotField.receiver = new ThisReference(0, 0);
invokeBuild.receiver = thisDotField;
}
-
+
Expression isNull; {
//this.pluralName == null
FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
thisDotField.receiver = new ThisReference(0, 0);
isNull = new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.EQUAL_EQUAL);
}
-
+
Expression init = new ConditionalExpression(isNull, emptyInvoke, invokeBuild);
LocalDeclaration varDefStat = new LocalDeclaration(data.getPluralName(), 0, 0);
varDefStat.type = varType;
varDefStat.initialization = init;
statements.add(varDefStat);
}
-
+
protected Statement createConstructBuilderVarIfNeeded(SingularData data, EclipseNode builderType) {
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);
Expression cond = new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.EQUAL_EQUAL);
-
+
MessageSend createBuilderInvoke = new MessageSend();
char[][] tokenizedName = makeGuavaTypeName(getSimpleTargetTypeName(data), false);
createBuilderInvoke.receiver = new QualifiedNameReference(tokenizedName, NULL_POSS, 0, 0);
createBuilderInvoke.selector = getBuilderMethodName(data);
return new IfStatement(cond, new Assignment(thisDotField2, createBuilderInvoke, 0), 0, 0);
}
+
+ private int getTypeAgrumentsCount(boolean isMap, String simpleTypeName) {
+ return isMap ? 2 : getListSetTypeArgumentsCount(simpleTypeName);
+ }
+
+ private int getListSetTypeArgumentsCount(String simpleTypeName) {
+ return "ImmutableTable".equals(simpleTypeName) ? 3 : 1;
+ }
+
+ private boolean shouldUsePut(SingularData data, boolean mapMode) {
+ return mapMode || isSpecialTypeOfListSet(data);
+ }
+
+ private boolean isSpecialTypeOfListSet(SingularData data) {
+ return "ImmutableTable".equals(getSimpleTargetTypeName(data));
+ }
}
diff --git a/src/core/lombok/javac/handlers/singulars/JavacGuavaSetListSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacGuavaSetListSingularizer.java
index 2e404ca8..fe8e8dc0 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacGuavaSetListSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacGuavaSetListSingularizer.java
@@ -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,24 +21,24 @@
*/
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
@Override public LombokImmutableList getSupportedTypes() {
return LombokImmutableList.of(
- "com.google.common.collect.ImmutableCollection",
- "com.google.common.collect.ImmutableList",
- "com.google.common.collect.ImmutableSet",
- "com.google.common.collect.ImmutableSortedSet");
+ "com.google.common.collect.ImmutableCollection",
+ "com.google.common.collect.ImmutableList",
+ "com.google.common.collect.ImmutableSet",
+ "com.google.common.collect.ImmutableSortedSet",
+ "com.google.common.collect.ImmutableTable");
}
-
+
@Override protected boolean isMap() {
return false;
}
diff --git a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
index 41e379f6..399f2239 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
@@ -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
@@ -26,14 +26,6 @@ import static lombok.javac.handlers.JavacHandlerUtil.*;
import java.util.Collections;
-import lombok.core.GuavaTypeMap;
-import lombok.core.handlers.HandlerUtil;
-import lombok.javac.JavacNode;
-import lombok.javac.JavacTreeMaker;
-import lombok.javac.handlers.JavacHandlerUtil;
-import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
-import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
-
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCBlock;
@@ -47,51 +39,60 @@ import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
+import lombok.core.GuavaTypeMap;
+import lombok.core.handlers.HandlerUtil;
+import lombok.javac.JavacNode;
+import lombok.javac.JavacTreeMaker;
+import lombok.javac.handlers.JavacHandlerUtil;
+import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
+import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
+
abstract class JavacGuavaSingularizer extends JavacSingularizer {
protected String getSimpleTargetTypeName(SingularData data) {
return GuavaTypeMap.getGuavaTypeName(data.getTargetFqn());
}
-
+
protected String getBuilderMethodName(SingularData data) {
String simpleTypeName = getSimpleTargetTypeName(data);
if ("ImmutableSortedSet".equals(simpleTypeName) || "ImmutableSortedMap".equals(simpleTypeName)) return "naturalOrder";
return "builder";
}
-
+
protected abstract boolean isMap();
-
+
@Override public java.util.List 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(getTypeAgrumentsCount(isMap(), simpleTypeName), false, builderType, type, data.getTypeArgs(), source);
+
JCVariableDecl buildField = maker.VarDef(maker.Modifiers(Flags.PRIVATE), data.getPluralName(), type, null);
return Collections.singletonList(injectFieldAndMarkGenerated(builderType, buildField));
}
-
+
@Override public void generateMethods(SingularData data, JavacNode builderType, JCTree source, boolean fluent, boolean chain) {
JavacTreeMaker maker = builderType.getTreeMaker();
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);
}
-
+
void generateSingularMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
List typeParams = List.nil();
List 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");
-
+
JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
ListBuffer statements = new ListBuffer();
statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, mapMode, source));
- JCExpression thisDotFieldDotAdd = chainDots(builderType, "this", data.getPluralName().toString(), mapMode ? "put" : "add");
+ JCExpression thisDotFieldDotAdd = chainDots(builderType, "this", data.getPluralName().toString(), shouldUsePut(data, mapMode) ? "put" : "add");
List invokeAddExpr;
if (mapMode) {
invokeAddExpr = List.of(maker.Ident(keyName), maker.Ident(valueName));
@@ -104,7 +105,7 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
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()));
+ if (!fluent) methodName = builderType.toName(HandlerUtil.buildAccessorName(shouldUsePut(data, mapMode) ? "put" : "add", methodName.toString()));
List params;
if (mapMode) {
JCExpression keyType = cloneParamType(0, maker, data.getTypeArgs(), builderType, source);
@@ -113,82 +114,112 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
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);
+ final JCExpression paramType;
+
+ if (isSpecialTypeOfListSet(data)) {
+ JCExpression cellType = JavacHandlerUtil.chainDots(builderType, "com", "google", "common", "collect", "Table", "Cell");
+ paramType = addTypeArgs(3, false, builderType, cellType, data.getTypeArgs(), source);
+ } else {
+ paramType = cloneParamType(0, maker, data.getTypeArgs(), builderType, source);
+ }
params = List.of(maker.VarDef(maker.Modifiers(paramFlags), data.getSingularName(), paramType, null));
}
JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, params, thrown, body, null);
injectMethod(builderType, method);
}
-
+
protected void generatePluralMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
List typeParams = List.nil();
List thrown = List.nil();
boolean mapMode = isMap();
-
+
JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
ListBuffer statements = new ListBuffer();
statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, mapMode, source));
- JCExpression thisDotFieldDotAddAll = chainDots(builderType, "this", data.getPluralName().toString(), mapMode ? "putAll" : "addAll");
+ JCExpression thisDotFieldDotAddAll = chainDots(builderType, "this", data.getPluralName().toString(), shouldUsePut(data, mapMode) ? "putAll" : "addAll");
JCExpression invokeAddAll = maker.Apply(List.nil(), thisDotFieldDotAddAll, List.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(shouldUsePut(data, mapMode) ? "putAll" : "addAll", methodName.toString()));
JCExpression paramType;
if (mapMode) {
paramType = chainDots(builderType, "java", "util", "Map");
} else {
- paramType = genJavaLangTypeRef(builderType, "Iterable");
+ if (isSpecialTypeOfListSet(data)) {
+ paramType = chainDots(builderType, "com", "google", "common", "collect", "Table");
+ } else {
+ paramType = genJavaLangTypeRef(builderType, "Iterable");
+ }
}
- paramType = addTypeArgs(mapMode ? 2 : 1, true, builderType, paramType, data.getTypeArgs(), source);
+ String simpleTypeName = getSimpleTargetTypeName(data);
+ paramType = addTypeArgs(getTypeAgrumentsCount(mapMode, simpleTypeName), 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);
}
-
+
@Override public void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer statements, Name targetVariableName) {
JavacTreeMaker maker = builderType.getTreeMaker();
List jceBlank = List.nil();
boolean mapMode = isMap();
-
+
+ String simpleTypeName = getSimpleTargetTypeName(data);
JCExpression varType = chainDotsString(builderType, data.getTargetFqn());
- varType = addTypeArgs(mapMode ? 2 : 1, false, builderType, varType, data.getTypeArgs(), source);
-
+ int agrumentsCount = getTypeAgrumentsCount(mapMode, simpleTypeName);
+ 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 invokeTypeArgs = createTypeArgs(mapMode ? 2 : 1, false, builderType, data.getTypeArgs(), source);
+ List invokeTypeArgs = createTypeArgs(agrumentsCount, false, builderType, data.getTypeArgs(), source);
empty = maker.Apply(invokeTypeArgs, emptyMethod, jceBlank);
}
-
+
JCExpression invokeBuild; {
//this.pluralName.build();
invokeBuild = maker.Apply(jceBlank, chainDots(builderType, "this", data.getPluralName().toString(), "build"), jceBlank);
}
-
+
JCExpression isNull; {
//this.pluralName == null
isNull = maker.Binary(CTC_EQUAL, maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName()), maker.Literal(CTC_BOT, null));
}
-
+
JCExpression init = maker.Conditional(isNull, empty, invokeBuild); // this.pluralName == null ? ImmutableX.of() : this.pluralName.build()
-
+
JCStatement jcs = maker.VarDef(maker.Modifiers(0), data.getPluralName(), varType, init);
statements.append(jcs);
}
-
+
protected JCStatement createConstructBuilderVarIfNeeded(JavacTreeMaker maker, SingularData data, JavacNode builderType, boolean mapMode, JCTree source) {
List jceBlank = List.nil();
-
+
JCExpression thisDotField = maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName());
JCExpression thisDotField2 = maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName());
JCExpression cond = maker.Binary(CTC_EQUAL, thisDotField, maker.Literal(CTC_BOT, null));
-
+
JCExpression create = maker.Apply(jceBlank, chainDots(builderType, "com", "google", "common", "collect", getSimpleTargetTypeName(data), getBuilderMethodName(data)), jceBlank);
JCStatement thenPart = maker.Exec(maker.Assign(thisDotField2, create));
-
+
return maker.If(cond, thenPart, null);
}
+
+ private int getTypeAgrumentsCount(boolean isMap, String simpleTypeName) {
+ return isMap ? 2 : getListSetTypeArgumentsCount(simpleTypeName);
+ }
+
+ private int getListSetTypeArgumentsCount(String simpleTypeName) {
+ return "ImmutableTable".equals(simpleTypeName) ? 3 : 1;
+ }
+
+ private boolean shouldUsePut(SingularData data, boolean mapMode) {
+ return mapMode || isSpecialTypeOfListSet(data);
+ }
+
+ private boolean isSpecialTypeOfListSet(SingularData data) {
+ return "ImmutableTable".equals(getSimpleTargetTypeName(data));
+ }
}
diff --git a/test/transform/resource/after-delombok/BuilderSingularGuavaListsSets.java b/test/transform/resource/after-delombok/BuilderSingularGuavaListsSets.java
index f8e0579d..f676166d 100644
--- a/test/transform/resource/after-delombok/BuilderSingularGuavaListsSets.java
+++ b/test/transform/resource/after-delombok/BuilderSingularGuavaListsSets.java
@@ -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 {
private ImmutableList cards;
private ImmutableCollection extends Number> frogs;
@SuppressWarnings("all")
private ImmutableSet rawSet;
private ImmutableSortedSet passes;
+ private ImmutableTable extends Number, ? extends Number, String> users;
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
- BuilderSingularGuavaListsSets(final ImmutableList cards, final ImmutableCollection extends Number> frogs, final ImmutableSet rawSet, final ImmutableSortedSet passes) {
+ BuilderSingularGuavaListsSets(final ImmutableList cards, final ImmutableCollection extends Number> frogs, final ImmutableSet rawSet, final ImmutableSortedSet 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 {
private com.google.common.collect.ImmutableSortedSet.Builder passes;
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
+ private com.google.common.collect.ImmutableTable.Builder users;
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
BuilderSingularGuavaListsSetsBuilder() {
}
@java.lang.SuppressWarnings("all")
@@ -93,18 +99,33 @@ class BuilderSingularGuavaListsSets {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
+ public BuilderSingularGuavaListsSetsBuilder user(final com.google.common.collect.Table.Cell user) {
+ if (this.users == null) this.users = com.google.common.collect.ImmutableTable.builder();
+ this.users.put(user);
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
+ public BuilderSingularGuavaListsSetsBuilder 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 BuilderSingularGuavaListsSets build() {
com.google.common.collect.ImmutableList cards = this.cards == null ? com.google.common.collect.ImmutableList.of() : this.cards.build();
com.google.common.collect.ImmutableCollection frogs = this.frogs == null ? com.google.common.collect.ImmutableList.of() : this.frogs.build();
com.google.common.collect.ImmutableSet rawSet = this.rawSet == null ? com.google.common.collect.ImmutableSet.of() : this.rawSet.build();
com.google.common.collect.ImmutableSortedSet passes = this.passes == null ? com.google.common.collect.ImmutableSortedSet.of() : this.passes.build();
- return new BuilderSingularGuavaListsSets(cards, frogs, rawSet, passes);
+ com.google.common.collect.ImmutableTable users = this.users == null ? com.google.common.collect.ImmutableTable.of() : this.users.build();
+ return new BuilderSingularGuavaListsSets(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")
diff --git a/test/transform/resource/after-ecj/BuilderSingularGuavaListsSets.java b/test/transform/resource/after-ecj/BuilderSingularGuavaListsSets.java
index e7aa7835..dc53b8fb 100644
--- a/test/transform/resource/after-ecj/BuilderSingularGuavaListsSets.java
+++ b/test/transform/resource/after-ecj/BuilderSingularGuavaListsSets.java
@@ -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 {
public static @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") class BuilderSingularGuavaListsSetsBuilder {
@@ -9,6 +10,7 @@ import lombok.Singular;
private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") com.google.common.collect.ImmutableList.Builder frogs;
private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") com.google.common.collect.ImmutableSet.Builder rawSet;
private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") com.google.common.collect.ImmutableSortedSet.Builder passes;
+ private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") com.google.common.collect.ImmutableTable.Builder users;
@java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder() {
super();
}
@@ -60,27 +62,42 @@ import lombok.Singular;
this.passes.addAll(passes);
return this;
}
+ public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder user(com.google.common.collect.Table.Cell user) {
+ if ((this.users == null))
+ this.users = com.google.common.collect.ImmutableTable.builder();
+ this.users.put(user);
+ return this;
+ }
+ public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSetsBuilder 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") BuilderSingularGuavaListsSets build() {
com.google.common.collect.ImmutableList cards = ((this.cards == null) ? com.google.common.collect.ImmutableList.of() : this.cards.build());
com.google.common.collect.ImmutableCollection frogs = ((this.frogs == null) ? com.google.common.collect.ImmutableList.of() : this.frogs.build());
com.google.common.collect.ImmutableSet rawSet = ((this.rawSet == null) ? com.google.common.collect.ImmutableSet.of() : this.rawSet.build());
com.google.common.collect.ImmutableSortedSet passes = ((this.passes == null) ? com.google.common.collect.ImmutableSortedSet.of() : this.passes.build());
- return new BuilderSingularGuavaListsSets(cards, frogs, rawSet, passes);
+ com.google.common.collect.ImmutableTable users = ((this.users == null) ? com.google.common.collect.ImmutableTable.of() : this.users.build());
+ return new BuilderSingularGuavaListsSets(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 cards;
private @Singular ImmutableCollection extends Number> frogs;
private @SuppressWarnings("all") @Singular("rawSet") ImmutableSet rawSet;
private @Singular ImmutableSortedSet passes;
- @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSets(final ImmutableList cards, final ImmutableCollection extends Number> frogs, final ImmutableSet rawSet, final ImmutableSortedSet passes) {
+ private @Singular ImmutableTable extends Number, ? extends Number, String> users;
+ @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") BuilderSingularGuavaListsSets(final ImmutableList cards, final ImmutableCollection extends Number> frogs, final ImmutableSet rawSet, final ImmutableSortedSet 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") BuilderSingularGuavaListsSetsBuilder builder() {
return new BuilderSingularGuavaListsSetsBuilder();
diff --git a/test/transform/resource/before/BuilderSingularGuavaListsSets.java b/test/transform/resource/before/BuilderSingularGuavaListsSets.java
index 995c00e8..73e8018c 100644
--- a/test/transform/resource/before/BuilderSingularGuavaListsSets.java
+++ b/test/transform/resource/before/BuilderSingularGuavaListsSets.java
@@ -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 {
@Singular private ImmutableCollection extends Number> frogs;
@SuppressWarnings("all") @Singular("rawSet") private ImmutableSet rawSet;
@Singular private ImmutableSortedSet passes;
+ @Singular private ImmutableTable extends Number, ? extends Number, String> users;
}
diff --git a/website/features/Builder.html b/website/features/Builder.html
index 6cf46600..c6f51ff1 100644
--- a/website/features/Builder.html
+++ b/website/features/Builder.html
@@ -101,6 +101,7 @@
ImmutableCollection and ImmutableList (backed by the builder feature of ImmutableList).
ImmutableSet and ImmutableSortedSet (backed by the builder feature of those types).
ImmutableMap, ImmutableBiMap, and ImmutableSortedMap (backed by the builder feature of those types).
+
ImmutableTable (backed by the builder feature of ImmutableTable).
--
cgit
From bd78d0841775b1a1c91ed4eef1defc62b33e9ed5 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Mon, 16 Nov 2015 23:46:12 +0100
Subject: [builder] Added clearX() functionality for `@Singular` annotations
for javac. Also docs and changelog.
---
doc/changelog.markdown | 1 +
.../singulars/EclipseGuavaSingularizer.java | 2 +-
.../EclipseJavaUtilListSetSingularizer.java | 2 +-
.../singulars/EclipseJavaUtilMapSingularizer.java | 2 +-
.../handlers/singulars/JavacGuavaSingularizer.java | 20 ++++++++++++++
.../JavacJavaUtilListSetSingularizer.java | 24 ++++++++++++++++
.../singulars/JavacJavaUtilMapSingularizer.java | 27 ++++++++++++++++++
.../BuilderSingularGuavaListsSets.java | 24 ++++++++++++++++
.../after-delombok/BuilderSingularGuavaMaps.java | 18 ++++++++++++
.../after-delombok/BuilderSingularLists.java | 18 ++++++++++++
.../after-delombok/BuilderSingularMaps.java | 32 ++++++++++++++++++++++
.../after-delombok/BuilderSingularNoAuto.java | 18 ++++++++++++
.../BuilderSingularRedirectToGuava.java | 18 ++++++++++++
.../after-delombok/BuilderSingularSets.java | 24 ++++++++++++++++
.../after-delombok/BuilderWithToBuilder.java | 6 ++++
usage_examples/BuilderExample_post.jpage | 8 ++++++
website/features/Builder.html | 7 +++--
17 files changed, 245 insertions(+), 6 deletions(-)
(limited to 'website/features')
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index da1cefce..52ed1182 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -2,6 +2,7 @@ Lombok Changelog
----------------
### v1.16.7 "Edgy Guinea Pig"
+* FEATURE: The `@Builder` annotation has received many updates: It now generates `clearFieldName()` methods if `@Singular` is used, ..... [Issue #967](https://github.com/rzwitserloot/lombok/issues/967).
* 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).
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
index 622451ee..d1c4d53c 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
@@ -124,7 +124,7 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
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 = new Statement[] {a, returnStatement};
+ md.statements = returnStatement != null ? new Statement[] {a, returnStatement} : new Statement[] {a};
md.returnType = returnType;
injectMethod(builderType, md);
}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
index 5efb610f..2d8083d3 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
@@ -120,7 +120,7 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
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 = new Statement[] {clearStatement, returnStatement};
+ md.statements = returnStatement != null ? new Statement[] {clearStatement, returnStatement} : new Statement[] {clearStatement};
md.returnType = returnType;
injectMethod(builderType, md);
}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
index 3aaa9165..ef9e2a76 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
@@ -176,7 +176,7 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
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 = new Statement[] {clearStatement, returnStatement};
+ md.statements = returnStatement != null ? new Statement[] {clearStatement, returnStatement} : new Statement[] {clearStatement};
md.returnType = returnType;
injectMethod(builderType, md);
}
diff --git a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
index 41e379f6..97e5f9be 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
@@ -78,6 +78,26 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
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 typeParams = List.nil();
+ List thrown = List.nil();
+ List 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 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) {
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java
index 8574ddbf..e167c7e2 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java
@@ -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 typeParams = List.nil();
+ List thrown = List.nil();
+ List params = List.nil();
+ List 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 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) {
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java
index 0830c9c9..1acae7e3 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java
@@ -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 typeParams = List.nil();
+ List thrown = List.nil();
+ List params = List.nil();
+ List 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 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) {
diff --git a/test/transform/resource/after-delombok/BuilderSingularGuavaListsSets.java b/test/transform/resource/after-delombok/BuilderSingularGuavaListsSets.java
index f8e0579d..3339d809 100644
--- a/test/transform/resource/after-delombok/BuilderSingularGuavaListsSets.java
+++ b/test/transform/resource/after-delombok/BuilderSingularGuavaListsSets.java
@@ -51,6 +51,12 @@ class BuilderSingularGuavaListsSets {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
+ public BuilderSingularGuavaListsSetsBuilder clearCards() {
+ this.cards = null;
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder frog(final Number frog) {
if (this.frogs == null) this.frogs = com.google.common.collect.ImmutableList.builder();
this.frogs.add(frog);
@@ -65,6 +71,12 @@ class BuilderSingularGuavaListsSets {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
+ public BuilderSingularGuavaListsSetsBuilder clearFrogs() {
+ this.frogs = null;
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder rawSet(final java.lang.Object rawSet) {
if (this.rawSet == null) this.rawSet = com.google.common.collect.ImmutableSet.builder();
this.rawSet.add(rawSet);
@@ -79,6 +91,12 @@ class BuilderSingularGuavaListsSets {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
+ public BuilderSingularGuavaListsSetsBuilder clearRawSet() {
+ this.rawSet = null;
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSetsBuilder pass(final String pass) {
if (this.passes == null) this.passes = com.google.common.collect.ImmutableSortedSet.naturalOrder();
this.passes.add(pass);
@@ -93,6 +111,12 @@ class BuilderSingularGuavaListsSets {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
+ public BuilderSingularGuavaListsSetsBuilder clearPasses() {
+ this.passes = null;
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
public BuilderSingularGuavaListsSets build() {
com.google.common.collect.ImmutableList cards = this.cards == null ? com.google.common.collect.ImmutableList.of() : this.cards.build();
com.google.common.collect.ImmutableCollection frogs = this.frogs == null ? com.google.common.collect.ImmutableList.of() : this.frogs.build();
diff --git a/test/transform/resource/after-delombok/BuilderSingularGuavaMaps.java b/test/transform/resource/after-delombok/BuilderSingularGuavaMaps.java
index 0cb0001b..10545a8f 100644
--- a/test/transform/resource/after-delombok/BuilderSingularGuavaMaps.java
+++ b/test/transform/resource/after-delombok/BuilderSingularGuavaMaps.java
@@ -45,6 +45,12 @@ class BuilderSingularGuavaMaps {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
+ public BuilderSingularGuavaMapsBuilder clearBattleaxes() {
+ this.battleaxes = null;
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
public BuilderSingularGuavaMapsBuilder vertex(final Integer vertex$key, final V vertex$value) {
if (this.vertices == null) this.vertices = com.google.common.collect.ImmutableSortedMap.naturalOrder();
this.vertices.put(vertex$key, vertex$value);
@@ -59,6 +65,12 @@ class BuilderSingularGuavaMaps {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
+ public BuilderSingularGuavaMapsBuilder clearVertices() {
+ this.vertices = null;
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
public BuilderSingularGuavaMapsBuilder rawMap(final java.lang.Object rawMap$key, final java.lang.Object rawMap$value) {
if (this.rawMap == null) this.rawMap = com.google.common.collect.ImmutableBiMap.builder();
this.rawMap.put(rawMap$key, rawMap$value);
@@ -73,6 +85,12 @@ class BuilderSingularGuavaMaps {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
+ public BuilderSingularGuavaMapsBuilder clearRawMap() {
+ this.rawMap = null;
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
public BuilderSingularGuavaMaps build() {
com.google.common.collect.ImmutableMap battleaxes = this.battleaxes == null ? com.google.common.collect.ImmutableMap.of() : this.battleaxes.build();
com.google.common.collect.ImmutableSortedMap vertices = this.vertices == null ? com.google.common.collect.ImmutableSortedMap.of() : this.vertices.build();
diff --git a/test/transform/resource/after-delombok/BuilderSingularLists.java b/test/transform/resource/after-delombok/BuilderSingularLists.java
index f58934d4..9b409404 100644
--- a/test/transform/resource/after-delombok/BuilderSingularLists.java
+++ b/test/transform/resource/after-delombok/BuilderSingularLists.java
@@ -44,6 +44,12 @@ class BuilderSingularLists {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
+ public BuilderSingularListsBuilder clearChildren() {
+ if (this.children != null) this.children.clear();
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
public BuilderSingularListsBuilder scarf(final Number scarf) {
if (this.scarves == null) this.scarves = new java.util.ArrayList();
this.scarves.add(scarf);
@@ -58,6 +64,12 @@ class BuilderSingularLists {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
+ public BuilderSingularListsBuilder clearScarves() {
+ if (this.scarves != null) this.scarves.clear();
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
public BuilderSingularListsBuilder rawList(final java.lang.Object rawList) {
if (this.rawList == null) this.rawList = new java.util.ArrayList();
this.rawList.add(rawList);
@@ -72,6 +84,12 @@ class BuilderSingularLists {
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
+ public BuilderSingularListsBuilder clearRawList() {
+ if (this.rawList != null) this.rawList.clear();
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
public BuilderSingularLists build() {
java.util.List children;
switch (this.children == null ? 0 : this.children.size()) {
diff --git a/test/transform/resource/after-delombok/BuilderSingularMaps.java b/test/transform/resource/after-delombok/BuilderSingularMaps.java
index 212ece26..257a2ec2 100644
--- a/test/transform/resource/after-delombok/BuilderSingularMaps.java
+++ b/test/transform/resource/after-delombok/BuilderSingularMaps.java
@@ -57,6 +57,14 @@ class BuilderSingularMaps {
return this;
}
@SuppressWarnings("all")
+ public BuilderSingularMapsBuilder clearWomen() {
+ if (this.women$key != null) {
+ this.women$key.clear();
+ this.women$value.clear();
+ }
+ return this;
+ }
+ @SuppressWarnings("all")
public BuilderSingularMapsBuilder man(K manKey, Number manValue) {
if (this.men$key == null) {
this.men$key = new java.util.ArrayList();
@@ -79,6 +87,14 @@ class BuilderSingularMaps {
return this;
}
@SuppressWarnings("all")
+ public BuilderSingularMapsBuilder clearMen() {
+ if (this.men$key != null) {
+ this.men$key.clear();
+ this.men$value.clear();
+ }
+ return this;
+ }
+ @SuppressWarnings("all")
public BuilderSingularMapsBuilder rawMap(Object rawMapKey, Object rawMapValue) {
if (this.rawMap$key == null) {
this.rawMap$key = new java.util.ArrayList
@Builder gained @Singular support and was promoted to the main lombok package since lombok v1.16.0.
-
+
+ @Builder with @Singular adds a clear method since lombok v1.16.8.
Overview
@@ -82,11 +83,11 @@
By annotating one of the parameters (if annotating a static method or constructor with @Builder) or fields (if annotating a class with @Builder) with the
@Singular 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:
When invoking build(), the produced collection will be immutable.
-
Calling one of the 'adder' methods after invoking build() does not modify any already generated objects, and, if build() is later called again, another collection with all the elements added since the creation of the builder is generated.
+
Calling one of the 'adder' methods, or the 'clear' method, after invoking build() does not modify any already generated objects, and, if build() is later called again, another collection with all the elements added since the creation of the builder is generated.
The produced collection will be compacted to the smallest feasible format while remaining efficient.