added the ‘always use guava’ lombok.config option for @Singular @Builder.

This commit is contained in:
Reinier Zwitserloot committed 2015-01-20 15:01:30 +01:00
1 parent 857da88e3e
commit 5b4ab9dae8
22 files changed
+400 -42

No files matched your search

+2 -1
View File
@@ -7,7 +7,8 @@ Lombok Changelog
* Builder __TODO TODO TODO TODO DO NOT SHIP YET__:
* features web page
* The 'I use guava' switch in l.config
* Check if the shadowed localvar names are properly typed; if compatible subtypes, we should cast these to avoid accidentally calling an overload.
* Add support for guava sortedset.
* Disable auto-singular in l.config
* Review if there are nay potentially breaking changes in the pipeline for builder BEFORE moving it out of experimental.
* Make sure you cover the fact that builder has moved on from experimental in this issue, and on the features page /doc!
+20 -12
View File
@@ -133,9 +133,9 @@ public class ConfigurationKeys {
/**
* lombok configuration: {@code lombok.equalsAndHashCode.doNotUseGetters} = {@code true} | {@code false}.
*
* For any class without an {@code @EqualsAndHashCode} that explicitly defines the {@code doNotUseGetters} option, this value is used.
* For any class without an {@code @EqualsAndHashCode} that explicitly defines the {@code doNotUseGetters} option, this value is used (default = false).
*/
public static final ConfigurationKey<Boolean> EQUALS_AND_HASH_CODE_DO_NOT_USE_GETTERS = new ConfigurationKey<Boolean>("lombok.equalsAndHashCode.doNotUseGetters", "Don't call the getters but use the fields directly in the generated equalsAndHashCode method.") {};
public static final ConfigurationKey<Boolean> EQUALS_AND_HASH_CODE_DO_NOT_USE_GETTERS = new ConfigurationKey<Boolean>("lombok.equalsAndHashCode.doNotUseGetters", "Don't call the getters but use the fields directly in the generated equalsAndHashCode method (default = false).") {};
/**
* lombok configuration: {@code lombok.equalsAndHashCode.flagUsage} = {@code WARNING} | {@code ERROR}.
@@ -149,9 +149,9 @@ public class ConfigurationKeys {
/**
* lombok configuration: {@code lombok.toString.doNotUseGetters} = {@code true} | {@code false}.
*
* For any class without an {@code @ToString} that explicitly defines the {@code doNotUseGetters} option, this value is used.
* For any class without an {@code @ToString} that explicitly defines the {@code doNotUseGetters} option, this value is used (default = false).
*/
public static final ConfigurationKey<Boolean> TO_STRING_DO_NOT_USE_GETTERS = new ConfigurationKey<Boolean>("lombok.toString.doNotUseGetters", "Don't call the getters but use the fields directly in the generated toString method.") {};
public static final ConfigurationKey<Boolean> TO_STRING_DO_NOT_USE_GETTERS = new ConfigurationKey<Boolean>("lombok.toString.doNotUseGetters", "Don't call the getters but use the fields directly in the generated toString method (default = false).") {};
/**
* lombok configuration: {@code lombok.toString.flagUsage} = {@code WARNING} | {@code ERROR}.
@@ -163,9 +163,9 @@ public class ConfigurationKeys {
/**
* lombok configuration: {@code lombok.toString.includeFieldNames} = {@code true} | {@code false}.
*
* For any class without an {@code @ToString} that explicitly defines the {@code includeFieldNames} option, this value is used.
* For any class without an {@code @ToString} that explicitly defines the {@code includeFieldNames} option, this value is used (default = true).
*/
public static final ConfigurationKey<Boolean> TO_STRING_INCLUDE_FIELD_NAMES = new ConfigurationKey<Boolean>("lombok.toString.includeFieldNames", "Include the field names in the generated toString method.") {};
public static final ConfigurationKey<Boolean> TO_STRING_INCLUDE_FIELD_NAMES = new ConfigurationKey<Boolean>("lombok.toString.includeFieldNames", "Include the field names in the generated toString method (default = true).") {};
// ##### Standalones #####
@@ -194,7 +194,7 @@ public class ConfigurationKeys {
*
* Sets the exception to throw if {@code @NonNull} is applied to a method parameter, and a caller passes in {@code null}.
*/
public static final ConfigurationKey<NullCheckExceptionType> NON_NULL_EXCEPTION_TYPE = new ConfigurationKey<NullCheckExceptionType>("lombok.nonNull.exceptionType", "The type of the exception to throw if a passed-in argument is null. Default: NullPointerException.") {};
public static final ConfigurationKey<NullCheckExceptionType> NON_NULL_EXCEPTION_TYPE = new ConfigurationKey<NullCheckExceptionType>("lombok.nonNull.exceptionType", "The type of the exception to throw if a passed-in argument is null (Default: NullPointerException).") {};
/**
* lombok configuration: {@code lombok.nonNull.flagUsage} = {@code WARNING} | {@code ERROR}.
@@ -289,7 +289,7 @@ public class ConfigurationKeys {
*
* If set the various log annotations (which make a log field) will use the stated identifier instead of {@code log} as a name.
*/
public static final ConfigurationKey<String> LOG_ANY_FIELD_NAME = new ConfigurationKey<String>("lombok.log.fieldName", "Use this name for the generated logger fields (default: 'log')") {};
public static final ConfigurationKey<String> LOG_ANY_FIELD_NAME = new ConfigurationKey<String>("lombok.log.fieldName", "Use this name for the generated logger fields (default: 'log').") {};
/**
* lombok configuration: {@code lombok.log.fieldIsStatic} = {@code true} | {@code false}.
@@ -329,16 +329,16 @@ public class ConfigurationKeys {
/**
* lombok configuration: {@code lombok.accessors.chain} = {@code true} | {@code false}.
*
* For any class without an {@code @Accessors} that explicitly defines the {@code chain} option, this value is used.
* For any class without an {@code @Accessors} that explicitly defines the {@code chain} option, this value is used (default = false).
*/
public static final ConfigurationKey<Boolean> ACCESSORS_CHAIN = new ConfigurationKey<Boolean>("lombok.accessors.chain", "Generate setters that return 'this' instead of 'void'.") {};
public static final ConfigurationKey<Boolean> ACCESSORS_CHAIN = new ConfigurationKey<Boolean>("lombok.accessors.chain", "Generate setters that return 'this' instead of 'void' (default: false).") {};
/**
* lombok configuration: {@code lombok.accessors.fluent} = {@code true} | {@code false}.
*
* For any class without an {@code @Accessors} that explicitly defines the {@code fluent} option, this value is used.
* For any class without an {@code @Accessors} that explicitly defines the {@code fluent} option, this value is used (default = false).
*/
public static final ConfigurationKey<Boolean> ACCESSORS_FLUENT = new ConfigurationKey<Boolean>("lombok.accessors.fluent", "Generate getters and setters using only the field name (no get/set prefix).") {};
public static final ConfigurationKey<Boolean> ACCESSORS_FLUENT = new ConfigurationKey<Boolean>("lombok.accessors.fluent", "Generate getters and setters using only the field name (no get/set prefix) (default: false).") {};
// ----- Builder -----
@@ -349,6 +349,14 @@ public class ConfigurationKeys {
*/
public static final ConfigurationKey<FlagUsageType> BUILDER_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.builder.flagUsage", "Emit a warning or error if @Builder is used.") {};
/**
* lombok configuration: {@code lombok.builder.useGuava} = {@code true} | {@code false}.
*
* If explicitly set to {@code true}, guava's {@code ImmutableList} etc are used to implement the immutable collection datatypes generated by @Singular @Builder for fields/parameters of type {@code java.util.List} and such.
* By default, unmodifiable-wrapped versions of {@code java.util} types are used.
*/
public static final ConfigurationKey<Boolean> BUILDER_USE_GUAVA = new ConfigurationKey<Boolean>("lombok.builder.useGuava", "Generate backing immutable implementations for @Singular on java.util.* types by using guava's ImmutableList, etc. Normally java.util's mutable types are used and wrapped to make them immutable.") {};
// ----- ExtensionMethod -----
/**
+58
View File
@@ -0,0 +1,58 @@
/*
* 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.core;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public final class GuavaTypeMap {
private static final Map<String, String> TYPE_TO_GUAVA_TYPE; static {
Map<String, String> m = new HashMap<String, String>();
m.put("java.util.NavigableSet", "ImmutableSortedSet");
m.put("java.util.NavigableMap", "ImmutableSortedMap");
m.put("java.util.SortedSet", "ImmutableSortedSet");
m.put("java.util.SortedMap", "ImmutableSortedMap");
m.put("java.util.Set", "ImmutableSet");
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");
m.put("com.google.common.collect.ImmutableBiMap", "ImmutableBiMap");
m.put("com.google.common.collect.ImmutableSortedMap", "ImmutableSortedMap");
m.put("com.google.common.collect.ImmutableList", "ImmutableList");
m.put("com.google.common.collect.ImmutableCollection", "ImmutableList");
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() {}
}
@@ -175,7 +175,7 @@ public class EclipseSingularsRecipes {
char[] name = fd.name;
if (name == null) continue;
if (getGeneratedBy(fd) != null) continue;
for (char[] fieldToBeGenerated : listFieldsToBeGenerated(data)) {
for (char[] fieldToBeGenerated : listFieldsToBeGenerated(data, builderType)) {
if (!Arrays.equals(name, fieldToBeGenerated)) continue;
child.addError("Manually adding a field that @Singular @Builder would generate is not supported. If you want to manually manage the builder aspect for this field/parameter, don't use @Singular.");
return true;
@@ -187,7 +187,7 @@ public class EclipseSingularsRecipes {
char[] name = method.selector;
if (name == null) continue;
if (getGeneratedBy(method) != null) continue;
for (char[] methodToBeGenerated : listMethodsToBeGenerated(data)) {
for (char[] methodToBeGenerated : listMethodsToBeGenerated(data, builderType)) {
if (!Arrays.equals(name, methodToBeGenerated)) continue;
child.addError("Manually adding a method that @Singular @Builder would generate is not supported. If you want to manually manage the builder aspect for this field/parameter, don't use @Singular.");
return true;
@@ -199,11 +199,11 @@ public class EclipseSingularsRecipes {
return false;
}
public List<char[]> listFieldsToBeGenerated(SingularData data) {
public List<char[]> listFieldsToBeGenerated(SingularData data, EclipseNode builderType) {
return Collections.singletonList(data.pluralName);
}
public List<char[]> listMethodsToBeGenerated(SingularData data) {
public List<char[]> listMethodsToBeGenerated(SingularData data, EclipseNode builderType) {
char[] p = data.pluralName;
char[] s = data.singularName;
if (Arrays.equals(p, s)) return Collections.singletonList(p);
@@ -28,6 +28,7 @@ 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;
@@ -64,13 +65,11 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
};
protected String getSimpleTargetTypeName(SingularData data) {
String simpleTypeName = data.getTargetSimpleType();
if ("ImmutableCollection".equals(simpleTypeName)) return "ImmutableList";
return simpleTypeName;
return GuavaTypeMap.getGuavaTypeName(data.getTargetFqn());
}
protected char[] getBuilderMethodName(SingularData data) {
String simpleTypeName = data.getTargetSimpleType();
String simpleTypeName = getSimpleTargetTypeName(data);
if ("ImmutableSortedSet".equals(simpleTypeName) || "ImmutableSortedMap".equals(simpleTypeName)) return "naturalOrder".toCharArray();
return "builder".toCharArray();
}
@@ -50,7 +50,27 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingularizer {
@Override public List<char[]> listFieldsToBeGenerated(SingularData data, EclipseNode builderType) {
if (useGuavaInstead(builderType)) {
return guavaListSetSingularizer.listFieldsToBeGenerated(data, builderType);
}
return super.listFieldsToBeGenerated(data, builderType);
}
@Override public List<char[]> listMethodsToBeGenerated(SingularData data, EclipseNode builderType) {
if (useGuavaInstead(builderType)) {
return guavaListSetSingularizer.listMethodsToBeGenerated(data, builderType);
}
return super.listMethodsToBeGenerated(data, builderType);
}
@Override public List<EclipseNode> generateFields(SingularData data, EclipseNode builderType) {
if (useGuavaInstead(builderType)) {
return guavaListSetSingularizer.generateFields(data, builderType);
}
TypeReference type = new QualifiedTypeReference(JAVA_UTIL_ARRAYLIST, NULL_POSS);
type = addTypeArgs(1, false, builderType, type, data.getTypeArgs());
@@ -64,6 +84,11 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
}
@Override public void generateMethods(SingularData data, EclipseNode builderType, boolean fluent, boolean chain) {
if (useGuavaInstead(builderType)) {
guavaListSetSingularizer.generateMethods(data, builderType, fluent, chain);
return;
}
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);
@@ -56,6 +56,11 @@ public class EclipseJavaUtilListSingularizer extends EclipseJavaUtilListSetSingu
}
@Override public void appendBuildCode(SingularData data, EclipseNode builderType, List<Statement> statements, char[] targetVariableName) {
if (useGuavaInstead(builderType)) {
guavaListSetSingularizer.appendBuildCode(data, builderType, statements, targetVariableName);
return;
}
List<Statement> switchContents = new ArrayList<Statement>();
/* case 0: (empty) break; */ {
@@ -61,7 +61,11 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
return LombokImmutableList.of("java.util.Map", "java.util.SortedMap", "java.util.NavigableMap");
}
@Override public List<char[]> listFieldsToBeGenerated(SingularData data) {
@Override public List<char[]> listFieldsToBeGenerated(SingularData data, EclipseNode builderType) {
if (useGuavaInstead(builderType)) {
return guavaMapSingularizer.listFieldsToBeGenerated(data, builderType);
}
char[] p = data.getPluralName();
int len = p.length;
char[] k = new char[len + 4];
@@ -81,7 +85,19 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
return Arrays.asList(k, v);
}
@Override public java.util.List<EclipseNode> generateFields(SingularData data, EclipseNode builderType) {
@Override public List<char[]> listMethodsToBeGenerated(SingularData data, EclipseNode builderType) {
if (useGuavaInstead(builderType)) {
return guavaMapSingularizer.listFieldsToBeGenerated(data, builderType);
} else {
return super.listMethodsToBeGenerated(data, builderType);
}
}
@Override public List<EclipseNode> generateFields(SingularData data, EclipseNode builderType) {
if (useGuavaInstead(builderType)) {
return guavaMapSingularizer.generateFields(data, builderType);
}
char[] keyName = (new String(data.getPluralName()) + "$key").toCharArray();
char[] valueName = (new String(data.getPluralName()) + "$value").toCharArray();
FieldDeclaration buildKeyField; {
@@ -113,6 +129,11 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
}
@Override public void generateMethods(SingularData data, EclipseNode builderType, boolean fluent, boolean chain) {
if (useGuavaInstead(builderType)) {
guavaMapSingularizer.generateMethods(data, builderType, fluent, chain);
return;
}
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);
@@ -235,6 +256,11 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
}
@Override public void appendBuildCode(SingularData data, EclipseNode builderType, List<Statement> statements, char[] targetVariableName) {
if (useGuavaInstead(builderType)) {
guavaMapSingularizer.appendBuildCode(data, builderType, statements, targetVariableName);
return;
}
if (data.getTargetFqn().equals("java.util.Map")) {
statements.addAll(createJavaUtilSetMapInitialCapacitySwitchStatements(data, builderType, true, "emptyMap", "singletonMap", "LinkedHashMap"));
} else {
@@ -38,6 +38,11 @@ public class EclipseJavaUtilSetSingularizer extends EclipseJavaUtilListSetSingul
}
@Override public void appendBuildCode(SingularData data, EclipseNode builderType, List<Statement> statements, char[] targetVariableName) {
if (useGuavaInstead(builderType)) {
guavaListSetSingularizer.appendBuildCode(data, builderType, statements, targetVariableName);
return;
}
if (data.getTargetFqn().equals("java.util.Set")) {
statements.addAll(createJavaUtilSetMapInitialCapacitySwitchStatements(data, builderType, false, "emptySet", "singleton", "LinkedHashSet"));
} else {
@@ -57,6 +57,7 @@ import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import lombok.ConfigurationKeys;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData;
@@ -82,6 +83,13 @@ abstract class EclipseJavaUtilSingularizer extends EclipseSingularizer {
{'j', 'a', 'v', 'a'}, {'u', 't', 'i', 'l'}, {'C', 'o', 'l', 'l', 'e', 'c', 't', 'i', 'o', 'n', 's'}
};
protected final EclipseSingularizer guavaListSetSingularizer = new EclipseGuavaSetListSingularizer();
protected final EclipseSingularizer guavaMapSingularizer = new EclipseGuavaMapSingularizer();
protected boolean useGuavaInstead(EclipseNode node) {
return Boolean.TRUE.equals(node.getAst().readConfiguration(ConfigurationKeys.BUILDER_USE_GUAVA));
}
protected List<Statement> createJavaUtilSetMapInitialCapacitySwitchStatements(SingularData data, EclipseNode builderType, boolean mapMode, String emptyCollectionMethod, String singletonCollectionMethod, String targetType) {
List<Statement> switchContents = new ArrayList<Statement>();
char[] keyName = mapMode ? (new String(data.getPluralName()) + "$key").toCharArray() : data.getPluralName();
@@ -150,7 +150,7 @@ public class JavacSingularsRecipes {
Name name = field.name;
if (name == null) break;
if (getGeneratedBy(field) != null) continue;
for (Name fieldToBeGenerated : listFieldsToBeGenerated(builderType, data)) {
for (Name fieldToBeGenerated : listFieldsToBeGenerated(data, builderType)) {
if (!fieldToBeGenerated.equals(name)) continue;
child.addError("Manually adding a field that @Singular @Builder would generate is not supported. If you want to manually manage the builder aspect for this field/parameter, don't use @Singular.");
return true;
@@ -162,7 +162,7 @@ public class JavacSingularsRecipes {
Name name = method.name;
if (name == null) break;
if (getGeneratedBy(method) != null) continue;
for (Name methodToBeGenerated : listMethodsToBeGenerated(builderType, data)) {
for (Name methodToBeGenerated : listMethodsToBeGenerated(data, builderType)) {
if (!methodToBeGenerated.equals(name)) continue;
child.addError("Manually adding a method that @Singular @Builder would generate is not supported. If you want to manually manage the builder aspect for this field/parameter, don't use @Singular.");
return true;
@@ -174,11 +174,11 @@ public class JavacSingularsRecipes {
return false;
}
public java.util.List<Name> listFieldsToBeGenerated(JavacNode builderType, SingularData data) {
public java.util.List<Name> listFieldsToBeGenerated(SingularData data, JavacNode builderType) {
return Collections.singletonList(data.pluralName);
}
public java.util.List<Name> listMethodsToBeGenerated(JavacNode builderType, SingularData data) {
public java.util.List<Name> listMethodsToBeGenerated(SingularData data, JavacNode builderType) {
Name p = data.pluralName;
Name s = data.singularName;
if (p.equals(s)) return Collections.singletonList(p);
@@ -26,6 +26,7 @@ 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;
@@ -48,13 +49,11 @@ import com.sun.tools.javac.util.Name;
abstract class JavacGuavaSingularizer extends JavacSingularizer {
protected String getSimpleTargetTypeName(SingularData data) {
String simpleTypeName = data.getTargetSimpleType();
if ("ImmutableCollection".equals(simpleTypeName)) return "ImmutableList";
return simpleTypeName;
return GuavaTypeMap.getGuavaTypeName(data.getTargetFqn());
}
protected String getBuilderMethodName(SingularData data) {
String simpleTypeName = data.getTargetSimpleType();
String simpleTypeName = getSimpleTargetTypeName(data);
if ("ImmutableSortedSet".equals(simpleTypeName) || "ImmutableSortedMap".equals(simpleTypeName)) return "naturalOrder";
return "builder";
}
@@ -46,7 +46,27 @@ import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
abstract class JavacJavaUtilListSetSingularizer extends JavacJavaUtilSingularizer {
@Override public java.util.List<Name> listFieldsToBeGenerated(SingularData data, JavacNode builderType) {
if (useGuavaInstead(builderType)) {
return guavaListSetSingularizer.listFieldsToBeGenerated(data, builderType);
}
return super.listFieldsToBeGenerated(data, builderType);
}
@Override public java.util.List<Name> listMethodsToBeGenerated(SingularData data, JavacNode builderType) {
if (useGuavaInstead(builderType)) {
return guavaListSetSingularizer.listMethodsToBeGenerated(data, builderType);
}
return super.listMethodsToBeGenerated(data, builderType);
}
@Override public java.util.List<JavacNode> generateFields(SingularData data, JavacNode builderType, JCTree source) {
if (useGuavaInstead(builderType)) {
return guavaListSetSingularizer.generateFields(data, builderType, source);
}
JavacTreeMaker maker = builderType.getTreeMaker();
JCExpression type = JavacHandlerUtil.chainDots(builderType, "java", "util", "ArrayList");
type = addTypeArgs(1, false, builderType, type, data.getTypeArgs(), source);
@@ -56,6 +76,11 @@ abstract class JavacJavaUtilListSetSingularizer extends JavacJavaUtilSingularize
}
@Override public void generateMethods(SingularData data, JavacNode builderType, JCTree source, boolean fluent, boolean chain) {
if (useGuavaInstead(builderType)) {
guavaListSetSingularizer.generateMethods(data, builderType, source, fluent, chain);
return;
}
JavacTreeMaker maker = builderType.getTreeMaker();
Name thisName = builderType.toName("this");
@@ -47,6 +47,11 @@ public class JavacJavaUtilListSingularizer extends JavacJavaUtilListSetSingulari
}
@Override public void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName) {
if (useGuavaInstead(builderType)) {
guavaListSetSingularizer.appendBuildCode(data, builderType, source, statements, targetVariableName);
return;
}
JavacTreeMaker maker = builderType.getTreeMaker();
List<JCExpression> jceBlank = List.nil();
ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
@@ -55,12 +55,28 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
return LombokImmutableList.of("java.util.Map", "java.util.SortedMap", "java.util.NavigableMap");
}
@Override public java.util.List<Name> listFieldsToBeGenerated(JavacNode builderType, SingularData data) {
@Override public java.util.List<Name> listFieldsToBeGenerated(SingularData data, JavacNode builderType) {
if (useGuavaInstead(builderType)) {
return guavaMapSingularizer.listFieldsToBeGenerated(data, builderType);
}
String p = data.getPluralName().toString();
return Arrays.asList(builderType.toName(p + "$key"), builderType.toName(p + "$value"));
}
@Override public java.util.List<Name> listMethodsToBeGenerated(SingularData data, JavacNode builderType) {
if (useGuavaInstead(builderType)) {
return guavaMapSingularizer.listMethodsToBeGenerated(data, builderType);
}
return super.listMethodsToBeGenerated(data, builderType);
}
@Override public java.util.List<JavacNode> generateFields(SingularData data, JavacNode builderType, JCTree source) {
if (useGuavaInstead(builderType)) {
return guavaMapSingularizer.generateFields(data, builderType, source);
}
JavacTreeMaker maker = builderType.getTreeMaker();
JCVariableDecl buildKeyField; {
@@ -85,6 +101,11 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
}
@Override public void generateMethods(SingularData data, JavacNode builderType, JCTree source, boolean fluent, boolean chain) {
if (useGuavaInstead(builderType)) {
guavaMapSingularizer.generateMethods(data, builderType, source, fluent, chain);
return;
}
JavacTreeMaker maker = builderType.getTreeMaker();
JCExpression returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
@@ -161,6 +182,11 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
}
@Override public void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName) {
if (useGuavaInstead(builderType)) {
guavaMapSingularizer.appendBuildCode(data, builderType, source, statements, targetVariableName);
return;
}
JavacTreeMaker maker = builderType.getTreeMaker();
if (data.getTargetFqn().equals("java.util.Map")) {
@@ -41,6 +41,11 @@ public class JavacJavaUtilSetSingularizer extends JavacJavaUtilListSetSingulariz
}
@Override public void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName) {
if (useGuavaInstead(builderType)) {
guavaListSetSingularizer.appendBuildCode(data, builderType, source, statements, targetVariableName);
return;
}
JavacTreeMaker maker = builderType.getTreeMaker();
if (data.getTargetFqn().equals("java.util.Set")) {
@@ -32,12 +32,20 @@ import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
import lombok.ConfigurationKeys;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
abstract class JavacJavaUtilSingularizer extends JavacSingularizer {
protected final JavacSingularizer guavaListSetSingularizer = new JavacGuavaSetListSingularizer();
protected final JavacSingularizer guavaMapSingularizer = new JavacGuavaMapSingularizer();
protected boolean useGuavaInstead(JavacNode node) {
return Boolean.TRUE.equals(node.getAst().readConfiguration(ConfigurationKeys.BUILDER_USE_GUAVA));
}
protected List<JCStatement> createJavaUtilSetMapInitialCapacitySwitchStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType, boolean mapMode, String emptyCollectionMethod, String singletonCollectionMethod, String targetType, JCTree source) {
List<JCExpression> jceBlank = List.nil();
ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
@@ -8,7 +8,7 @@ lombok.accessors.flagUsage = ERROR
# BASE/d1/d11/lombok.config:
# 3: lombok.accessors.flagUsage = ERROR
# Generate setters that return 'this' instead of 'void'.
# Generate setters that return 'this' instead of 'void' (default: false).
lombok.accessors.chain = false
# BASE/d1/lombok.config:
# <'lombok.accessors.chain' not mentioned>
@@ -24,7 +24,7 @@ lombok.accessors.prefix += f
# BASE/d1/d11/lombok.config:
# 4: lombok.accessors.prefix += f
# Use this name for the generated logger fields (default: 'log')
# Use this name for the generated logger fields (default: 'log').
clear lombok.log.fieldName
@@ -43,7 +43,7 @@ lombok.accessors.flagUsage = ERROR
# BASE/d1/d11/d111/lombok.config:
# <'lombok.accessors.flagUsage' not mentioned>
# Generate setters that return 'this' instead of 'void'.
# Generate setters that return 'this' instead of 'void' (default: false).
clear lombok.accessors.chain
# BASE/d1/lombok.config:
# <'lombok.accessors.chain' not mentioned>
@@ -66,7 +66,7 @@ lombok.accessors.prefix += m_
# BASE/d1/d11/d111/lombok.config:
# 2: lombok.accessors.prefix += m_
# Use this name for the generated logger fields (default: 'log')
# Use this name for the generated logger fields (default: 'log').
clear lombok.log.fieldName
@@ -75,7 +75,7 @@ Configuration for 'BASE/d1/d12'.
# Emit a warning or error if @Accessors is used.
clear lombok.accessors.flagUsage
# Generate setters that return 'this' instead of 'void'.
# Generate setters that return 'this' instead of 'void' (default: false).
lombok.accessors.chain = true
# BASE/d1/lombok.config:
# <'lombok.accessors.chain' not mentioned>
@@ -86,5 +86,5 @@ lombok.accessors.chain = true
# Strip this field prefix, like 'f' or 'm_', from the names of generated getters and setters.
clear lombok.accessors.prefix
# Use this name for the generated logger fields (default: 'log')
# Use this name for the generated logger fields (default: 'log').
clear lombok.log.fieldName
@@ -0,0 +1,75 @@
import java.util.Set;
import java.util.NavigableMap;
import java.util.Collection;
class BuilderSingletonRedirectToGuava {
private Set<String> dangerMice;
private NavigableMap<Integer, Number> things;
private Collection<Class<?>> doohickeys;
@java.lang.SuppressWarnings("all")
BuilderSingletonRedirectToGuava(final Set<String> dangerMice, final NavigableMap<Integer, Number> things, final Collection<Class<?>> doohickeys) {
this.dangerMice = dangerMice;
this.things = things;
this.doohickeys = doohickeys;
}
@java.lang.SuppressWarnings("all")
public static class BuilderSingletonRedirectToGuavaBuilder {
private com.google.common.collect.ImmutableSet.Builder<String> dangerMice;
private com.google.common.collect.ImmutableSortedMap.Builder<Integer, Number> things;
private com.google.common.collect.ImmutableList.Builder<Class<?>> doohickeys;
@java.lang.SuppressWarnings("all")
BuilderSingletonRedirectToGuavaBuilder() {
}
@java.lang.SuppressWarnings("all")
public BuilderSingletonRedirectToGuavaBuilder dangerMouse(final String dangerMouse) {
if (this.dangerMice == null) this.dangerMice = com.google.common.collect.ImmutableSet.builder();
this.dangerMice.add(dangerMouse);
return this;
}
@java.lang.SuppressWarnings("all")
public BuilderSingletonRedirectToGuavaBuilder dangerMice(final java.lang.Iterable<? extends String> dangerMice) {
if (this.dangerMice == null) this.dangerMice = com.google.common.collect.ImmutableSet.builder();
this.dangerMice.addAll(dangerMice);
return this;
}
@java.lang.SuppressWarnings("all")
public BuilderSingletonRedirectToGuavaBuilder thing(final Integer thing$key, final Number thing$value) {
if (this.things == null) this.things = com.google.common.collect.ImmutableSortedMap.naturalOrder();
this.things.put(thing$key, thing$value);
return this;
}
@java.lang.SuppressWarnings("all")
public BuilderSingletonRedirectToGuavaBuilder things(final java.util.Map<? extends Integer, ? extends Number> things) {
if (this.things == null) this.things = com.google.common.collect.ImmutableSortedMap.naturalOrder();
this.things.putAll(things);
return this;
}
@java.lang.SuppressWarnings("all")
public BuilderSingletonRedirectToGuavaBuilder doohickey(final Class<?> doohickey) {
if (this.doohickeys == null) this.doohickeys = com.google.common.collect.ImmutableList.builder();
this.doohickeys.add(doohickey);
return this;
}
@java.lang.SuppressWarnings("all")
public BuilderSingletonRedirectToGuavaBuilder doohickeys(final java.lang.Iterable<? extends Class<?>> doohickeys) {
if (this.doohickeys == null) this.doohickeys = com.google.common.collect.ImmutableList.builder();
this.doohickeys.addAll(doohickeys);
return this;
}
@java.lang.SuppressWarnings("all")
public BuilderSingletonRedirectToGuava build() {
java.util.Set<String> dangerMice = this.dangerMice == null ? com.google.common.collect.ImmutableSet.of() : this.dangerMice.build();
java.util.NavigableMap<Integer, Number> things = this.things == null ? com.google.common.collect.ImmutableSortedMap.of() : this.things.build();
java.util.Collection<Class<?>> doohickeys = this.doohickeys == null ? com.google.common.collect.ImmutableList.of() : this.doohickeys.build();
return new BuilderSingletonRedirectToGuava(dangerMice, things, doohickeys);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public java.lang.String toString() {
return "BuilderSingletonRedirectToGuava.BuilderSingletonRedirectToGuavaBuilder(dangerMice=" + this.dangerMice + ", things=" + this.things + ", doohickeys=" + this.doohickeys + ")";
}
}
@java.lang.SuppressWarnings("all")
public static BuilderSingletonRedirectToGuavaBuilder builder() {
return new BuilderSingletonRedirectToGuavaBuilder();
}
}
@@ -0,0 +1,71 @@
import java.util.Set;
import java.util.NavigableMap;
import java.util.Collection;
import lombok.Singular;
@lombok.Builder class BuilderSingletonRedirectToGuava {
public static @java.lang.SuppressWarnings("all") class BuilderSingletonRedirectToGuavaBuilder {
private com.google.common.collect.ImmutableSet.Builder<String> dangerMice;
private com.google.common.collect.ImmutableSortedMap.Builder<Integer, Number> things;
private com.google.common.collect.ImmutableList.Builder<Class<?>> doohickeys;
@java.lang.SuppressWarnings("all") BuilderSingletonRedirectToGuavaBuilder() {
super();
}
public @java.lang.SuppressWarnings("all") BuilderSingletonRedirectToGuavaBuilder dangerMouse(String dangerMouse) {
if ((this.dangerMice == null))
this.dangerMice = com.google.common.collect.ImmutableSet.builder();
this.dangerMice.add(dangerMouse);
return this;
}
public @java.lang.SuppressWarnings("all") BuilderSingletonRedirectToGuavaBuilder dangerMice(java.lang.Iterable<? extends String> dangerMice) {
if ((this.dangerMice == null))
this.dangerMice = com.google.common.collect.ImmutableSet.builder();
this.dangerMice.addAll(dangerMice);
return this;
}
public @java.lang.SuppressWarnings("all") BuilderSingletonRedirectToGuavaBuilder thing(Integer thing$key, Number thing$value) {
if ((this.things == null))
this.things = com.google.common.collect.ImmutableSortedMap.naturalOrder();
this.things.put(thing$key, thing$value);
return this;
}
public @java.lang.SuppressWarnings("all") BuilderSingletonRedirectToGuavaBuilder things(java.util.Map<? extends Integer, ? extends Number> things) {
if ((this.things == null))
this.things = com.google.common.collect.ImmutableSortedMap.naturalOrder();
this.things.putAll(things);
return this;
}
public @java.lang.SuppressWarnings("all") BuilderSingletonRedirectToGuavaBuilder doohickey(Class<?> doohickey) {
if ((this.doohickeys == null))
this.doohickeys = com.google.common.collect.ImmutableList.builder();
this.doohickeys.add(doohickey);
return this;
}
public @java.lang.SuppressWarnings("all") BuilderSingletonRedirectToGuavaBuilder doohickeys(java.lang.Iterable<? extends Class<?>> doohickeys) {
if ((this.doohickeys == null))
this.doohickeys = com.google.common.collect.ImmutableList.builder();
this.doohickeys.addAll(doohickeys);
return this;
}
public @java.lang.SuppressWarnings("all") BuilderSingletonRedirectToGuava build() {
java.util.Set<String> dangerMice = ((this.dangerMice == null) ? com.google.common.collect.ImmutableSet.of() : this.dangerMice.build());
java.util.NavigableMap<Integer, Number> things = ((this.things == null) ? com.google.common.collect.ImmutableSortedMap.of() : this.things.build());
java.util.Collection<Class<?>> doohickeys = ((this.doohickeys == null) ? com.google.common.collect.ImmutableList.of() : this.doohickeys.build());
return new BuilderSingletonRedirectToGuava(dangerMice, things, doohickeys);
}
public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
return (((((("BuilderSingletonRedirectToGuava.BuilderSingletonRedirectToGuavaBuilder(dangerMice=" + this.dangerMice) + ", things=") + this.things) + ", doohickeys=") + this.doohickeys) + ")");
}
}
private @Singular Set<String> dangerMice;
private @Singular NavigableMap<Integer, Number> things;
private @Singular Collection<Class<?>> doohickeys;
@java.lang.SuppressWarnings("all") BuilderSingletonRedirectToGuava(final Set<String> dangerMice, final NavigableMap<Integer, Number> things, final Collection<Class<?>> doohickeys) {
super();
this.dangerMice = dangerMice;
this.things = things;
this.doohickeys = doohickeys;
}
public static @java.lang.SuppressWarnings("all") BuilderSingletonRedirectToGuavaBuilder builder() {
return new BuilderSingletonRedirectToGuavaBuilder();
}
}
@@ -0,0 +1,13 @@
//CONF: lombok.builder.useGuava = true
import java.util.Set;
import java.util.NavigableMap;
import java.util.Collection;
import lombok.Singular;
@lombok.Builder
class BuilderSingletonRedirectToGuava {
@Singular private Set<String> dangerMice;
@Singular private NavigableMap<Integer, Number> things;
@Singular private Collection<Class<?>> doohickeys;
}
@@ -57,8 +57,4 @@ public class TestWithEcj extends DirectoryRunner.TestParams {
public File getMessagesDirectory() {
return new File("test/transform/resource/messages-ecj");
}
@Override public boolean accept(File file) {
return file.getName().startsWith("BuilderSingleton");
}
}