aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2015-11-17 02:15:31 +0100
committerReinier Zwitserloot <reinier@zwitserloot.com>2015-11-17 02:15:31 +0100
commit0bd688d7e624d95fef921f8b463209d70b92779a (patch)
tree19c7dc3d6e996ee96cfe4c02fbe6d651945885a7 /src/core
parent0e34eec7668ee060fe65133243009dbb27e7c251 (diff)
parent5b6829b86379321be378490b895827cd6bca13f1 (diff)
downloadlombok-0bd688d7e624d95fef921f8b463209d70b92779a.tar.gz
lombok-0bd688d7e624d95fef921f8b463209d70b92779a.tar.bz2
lombok-0bd688d7e624d95fef921f8b463209d70b92779a.zip
Merge branch 'builderUpdate'
Diffstat (limited to 'src/core')
-rw-r--r--src/core/lombok/Builder.java16
-rw-r--r--src/core/lombok/core/GuavaTypeMap.java1
-rw-r--r--src/core/lombok/eclipse/handlers/HandleBuilder.java42
-rw-r--r--src/core/lombok/eclipse/handlers/singulars/EclipseGuavaMapSingularizer.java25
-rw-r--r--src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java29
-rw-r--r--src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java101
-rw-r--r--src/core/lombok/eclipse/handlers/singulars/EclipseGuavaTableSingularizer.java51
-rw-r--r--src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java27
-rw-r--r--src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java38
-rw-r--r--src/core/lombok/experimental/Builder.java16
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java57
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacGuavaMapSingularizer.java25
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacGuavaSetListSingularizer.java37
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java111
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacGuavaTableSingularizer.java51
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java24
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java27
17 files changed, 504 insertions, 174 deletions
diff --git a/src/core/lombok/Builder.java b/src/core/lombok/Builder.java
index 0639c4cb..6a92028c 100644
--- a/src/core/lombok/Builder.java
+++ b/src/core/lombok/Builder.java
@@ -31,21 +31,21 @@ import java.lang.annotation.Target;
* The builder annotation creates a so-called 'builder' aspect to the class that is annotated or the class
* that contains a member which is annotated with {@code @Builder}.
* <p>
- * If a member is annotated, it must be either a constructor or a static method. If a class is annotated,
+ * If a member is annotated, it must be either a constructor or a method. If a class is annotated,
* then a private constructor is generated with all fields as arguments
* (as if {@code @AllArgsConstructor(AccessLevel.PRIVATE)} is present
* on the class), and it is as if this constructor has been annotated with {@code @Builder} instead.
* <p>
* The effect of {@code @Builder} is that an inner class is generated named <code><strong>T</strong>Builder</code>,
- * with a private constructor. Instances of <code><strong>T</strong>Builder</code> are made with the static
+ * with a private constructor. Instances of <code><strong>T</strong>Builder</code> are made with the
* method named {@code builder()} which is also generated for you in the class itself (not in the builder class).
* <p>
* The <code><strong>T</strong>Builder</code> class contains 1 method for each parameter of the annotated
- * constructor / static method (each field, when annotating a class), which returns the builder itself.
+ * constructor / method (each field, when annotating a class), which returns the builder itself.
* The builder also has a <code>build()</code> method which returns a completed instance of the original type,
* created by passing all parameters as set via the various other methods in the builder to the constructor
- * or static method that was annotated with {@code @Builder}. The return type of this method will be the same
- * as the relevant class, unless a static method has been annotated, in which case it'll be equal to the
+ * or method that was annotated with {@code @Builder}. The return type of this method will be the same
+ * as the relevant class, unless a method has been annotated, in which case it'll be equal to the
* return type of that method.
* <p>
* Complete documentation is found at <a href="https://projectlombok.org/features/experimental/Builder.html">the project lombok features page for &#64;Builder</a>.
@@ -107,10 +107,10 @@ import java.lang.annotation.Target;
@Target({TYPE, METHOD, CONSTRUCTOR})
@Retention(SOURCE)
public @interface Builder {
- /** Name of the static method that creates a new builder instance. Default: {@code builder}. */
+ /** Name of the method that creates a new builder instance. Default: {@code builder}. */
String builderMethodName() default "builder";
- /** Name of the instance method in the builder class that creates an instance of your {@code @Builder}-annotated class. */
+ /** Name of the method in the builder class that creates an instance of your {@code @Builder}-annotated class. */
String buildMethodName() default "build";
/**
@@ -118,7 +118,7 @@ public @interface Builder {
*
* Default for {@code @Builder} on types and constructors: {@code (TypeName)Builder}.
* <p>
- * Default for {@code @Builder} on static methods: {@code (ReturnTypeName)Builder}.
+ * Default for {@code @Builder} on methods: {@code (ReturnTypeName)Builder}.
*/
String builderClassName() default "";
diff --git a/src/core/lombok/core/GuavaTypeMap.java b/src/core/lombok/core/GuavaTypeMap.java
index 900d2b72..282d5d81 100644
--- a/src/core/lombok/core/GuavaTypeMap.java
+++ b/src/core/lombok/core/GuavaTypeMap.java
@@ -45,6 +45,7 @@ public final class GuavaTypeMap {
m.put("com.google.common.collect.ImmutableSortedMap", "ImmutableSortedMap");
m.put("com.google.common.collect.ImmutableList", "ImmutableList");
m.put("com.google.common.collect.ImmutableCollection", "ImmutableList");
+ m.put("com.google.common.collect.ImmutableTable", "ImmutableTable");
TYPE_TO_GUAVA_TYPE = Collections.unmodifiableMap(m);
}
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index ef06e249..be14653a 100644
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -49,6 +49,7 @@ import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
@@ -163,6 +164,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
EclipseNode fillParametersFrom = parent.get() instanceof AbstractMethodDeclaration ? parent : null;
boolean addCleaning = false;
+ boolean isStatic = true;
if (parent.get() instanceof TypeDeclaration) {
tdParent = parent;
@@ -212,11 +214,8 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
} else if (parent.get() instanceof MethodDeclaration) {
MethodDeclaration md = (MethodDeclaration) parent.get();
tdParent = parent.up();
- if (!md.isStatic()) {
- annotationNode.addError("@Builder is only supported on types, constructors, and static methods.");
- return;
- }
-
+ isStatic = md.isStatic();
+
if (toBuilder) {
final String TO_BUILDER_NOT_SUPPORTED = "@Builder(toBuilder=true) is only supported if you return your own type.";
char[] token;
@@ -322,7 +321,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
builderClassName = new String(token) + "Builder";
}
} else {
- annotationNode.addError("@Builder is only supported on types, constructors, and static methods.");
+ annotationNode.addError("@Builder is only supported on types, constructors, and methods.");
return;
}
@@ -342,8 +341,16 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
EclipseNode builderType = findInnerClass(tdParent, builderClassName);
if (builderType == null) {
- builderType = makeBuilderClass(tdParent, builderClassName, typeParams, ast);
+ builderType = makeBuilderClass(isStatic, tdParent, builderClassName, typeParams, ast);
} else {
+ TypeDeclaration builderTypeDeclaration = (TypeDeclaration) builderType.get();
+ if (isStatic && (builderTypeDeclaration.modifiers & ClassFileConstants.AccStatic) == 0) {
+ annotationNode.addError("Existing Builder must be a static inner class.");
+ return;
+ } else if (!isStatic && (builderTypeDeclaration.modifiers & ClassFileConstants.AccStatic) != 0) {
+ annotationNode.addError("Existing Builder must be a non-static inner class.");
+ return;
+ }
sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderType, annotationNode);
/* generate errors for @Singular BFDs that have one already defined node. */ {
for (BuilderFieldData bfd : builderFields) {
@@ -398,7 +405,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
if (methodExists(buildMethodName, builderType, -1) == MemberExistsResult.NOT_EXISTS) {
- MethodDeclaration md = generateBuildMethod(buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, addCleaning, ast);
+ MethodDeclaration md = generateBuildMethod(isStatic, buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, addCleaning, ast);
if (md != null) injectMethod(builderType, md);
}
@@ -417,7 +424,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
- MethodDeclaration md = generateBuilderMethod(builderMethodName, builderClassName, tdParent, typeParams, ast);
+ MethodDeclaration md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, tdParent, typeParams, ast);
if (md != null) injectMethod(tdParent, md);
}
@@ -507,7 +514,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return decl;
}
- public MethodDeclaration generateBuildMethod(String name, char[] staticName, TypeReference returnType, List<BuilderFieldData> builderFields, EclipseNode type, TypeReference[] thrownExceptions, boolean addCleaning, ASTNode source) {
+ public MethodDeclaration generateBuildMethod(boolean isStatic, String name, char[] staticName, TypeReference returnType, List<BuilderFieldData> builderFields, EclipseNode type, TypeReference[] thrownExceptions, boolean addCleaning, ASTNode source) {
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
List<Statement> statements = new ArrayList<Statement>();
@@ -552,7 +559,10 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
} else {
MessageSend invoke = new MessageSend();
invoke.selector = staticName;
- invoke.receiver = new SingleNameReference(type.up().getName().toCharArray(), 0);
+ if (isStatic)
+ invoke.receiver = new SingleNameReference(type.up().getName().toCharArray(), 0);
+ else
+ invoke.receiver = new QualifiedThisReference(new SingleTypeReference(type.up().getName().toCharArray(), 0) , 0, 0);
TypeParameter[] tps = ((TypeDeclaration) type.get()).typeParameters;
if (tps != null) {
TypeReference[] trs = new TypeReference[tps.length];
@@ -573,13 +583,14 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return out;
}
- public MethodDeclaration generateBuilderMethod(String builderMethodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
+ public MethodDeclaration generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
out.selector = builderMethodName.toCharArray();
- out.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic;
+ out.modifiers = ClassFileConstants.AccPublic;
+ if (isStatic) out.modifiers |= ClassFileConstants.AccStatic;
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
out.returnType = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p);
out.typeParameters = copyTypeParams(typeParams, source);
@@ -661,11 +672,12 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return null;
}
- public EclipseNode makeBuilderClass(EclipseNode tdParent, String builderClassName, TypeParameter[] typeParams, ASTNode source) {
+ public EclipseNode makeBuilderClass(boolean isStatic, EclipseNode tdParent, String builderClassName, TypeParameter[] typeParams, ASTNode source) {
TypeDeclaration parent = (TypeDeclaration) tdParent.get();
TypeDeclaration builder = new TypeDeclaration(parent.compilationResult);
builder.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
- builder.modifiers |= ClassFileConstants.AccPublic | ClassFileConstants.AccStatic;
+ builder.modifiers |= ClassFileConstants.AccPublic;
+ if (isStatic) builder.modifiers |= ClassFileConstants.AccStatic;
builder.typeParameters = copyTypeParams(typeParams, source);
builder.name = builderClassName.toCharArray();
builder.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaMapSingularizer.java
index 95fd8935..5956c01b 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaMapSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaMapSingularizer.java
@@ -32,14 +32,27 @@ public class EclipseGuavaMapSingularizer extends EclipseGuavaSingularizer {
// TODO cgcc.ImmutableClassToInstanceMap
// TODO cgcc.ImmutableRangeMap
+ private static final LombokImmutableList<String> SUFFIXES =
+ LombokImmutableList.of("key", "value");
+ private static final LombokImmutableList<String> SUPPORTED_TYPES = LombokImmutableList.of(
+ "com.google.common.collect.ImmutableMap",
+ "com.google.common.collect.ImmutableBiMap",
+ "com.google.common.collect.ImmutableSortedMap"
+ );
+
@Override public LombokImmutableList<String> getSupportedTypes() {
- return LombokImmutableList.of(
- "com.google.common.collect.ImmutableMap",
- "com.google.common.collect.ImmutableBiMap",
- "com.google.common.collect.ImmutableSortedMap");
+ return SUPPORTED_TYPES;
+ }
+
+ @Override protected LombokImmutableList<String> getArgumentSuffixes() {
+ return SUFFIXES;
+ }
+
+ @Override protected String getAddMethodName() {
+ return "put";
}
- @Override protected boolean isMap() {
- return true;
+ @Override protected String getAddAllTypeName() {
+ return "java.util.Map";
}
}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java
index bc2893bf..326a9179 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java
@@ -28,18 +28,29 @@ import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
@ProviderFor(EclipseSingularizer.class)
public class EclipseGuavaSetListSingularizer extends EclipseGuavaSingularizer {
- // TODO com.google.common.collect.ImmutableTable
// TODO com.google.common.collect.ImmutableRangeSet
// TODO com.google.common.collect.ImmutableMultiset and com.google.common.collect.ImmutableSortedMultiset
+ private static final LombokImmutableList<String> SUFFIXES = LombokImmutableList.of("");
+ private static final LombokImmutableList<String> SUPPORTED_TYPES = LombokImmutableList.of(
+ "com.google.common.collect.ImmutableCollection",
+ "com.google.common.collect.ImmutableList",
+ "com.google.common.collect.ImmutableSet",
+ "com.google.common.collect.ImmutableSortedSet"
+ );
+
@Override public LombokImmutableList<String> getSupportedTypes() {
- return LombokImmutableList.of(
- "com.google.common.collect.ImmutableCollection",
- "com.google.common.collect.ImmutableList",
- "com.google.common.collect.ImmutableSet",
- "com.google.common.collect.ImmutableSortedSet");
+ return SUPPORTED_TYPES;
}
-
- @Override protected boolean isMap() {
- return false;
+
+ @Override protected LombokImmutableList<String> getArgumentSuffixes() {
+ return SUFFIXES;
+ }
+
+ @Override protected String getAddMethodName() {
+ return "add";
+ }
+
+ @Override protected String getAddAllTypeName() {
+ return "java.lang.Iterable";
}
}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
index fa121328..242bde1f 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
@@ -29,6 +29,7 @@ import java.util.Collections;
import java.util.List;
import lombok.core.GuavaTypeMap;
+import lombok.core.LombokImmutableList;
import lombok.core.handlers.HandlerUtil;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
@@ -56,14 +57,9 @@ import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
- protected static final char[][] JAVA_UTIL_MAP = {
- {'j', 'a', 'v', 'a'}, {'u', 't', 'i', 'l'}, {'M', 'a', 'p'}
- };
-
protected String getSimpleTargetTypeName(SingularData data) {
return GuavaTypeMap.getGuavaTypeName(data.getTargetFqn());
}
@@ -74,8 +70,6 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
return "builder".toCharArray();
}
- protected abstract boolean isMap();
-
protected char[][] makeGuavaTypeName(String simpleName, boolean addBuilder) {
char[][] tokenizedName = new char[addBuilder ? 6 : 5][];
tokenizedName[0] = new char[] {'c', 'o', 'm'};
@@ -88,9 +82,10 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
}
@Override public List<EclipseNode> generateFields(SingularData data, EclipseNode builderType) {
- char[][] tokenizedName = makeGuavaTypeName(getSimpleTargetTypeName(data), true);
+ String simpleTypeName = getSimpleTargetTypeName(data);
+ char[][] tokenizedName = makeGuavaTypeName(simpleTypeName, true);
TypeReference type = new QualifiedTypeReference(tokenizedName, NULL_POSS);
- type = addTypeArgs(isMap() ? 2 : 1, false, builderType, type, data.getTypeArgs());
+ type = addTypeArgs(getTypeArgumentsCount(), false, builderType, type, data.getTypeArgs());
FieldDeclaration buildField = new FieldDeclaration(data.getPluralName(), 0, -1);
buildField.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
@@ -109,12 +104,34 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
generatePluralMethod(returnType, returnStatement, data, builderType, fluent);
+
+ returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
+ returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
+ generateClearMethod(returnType, returnStatement, data, builderType);
+ }
+
+ void generateClearMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType) {
+ MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
+ md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
+ md.modifiers = ClassFileConstants.AccPublic;
+
+ FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
+ thisDotField.receiver = new ThisReference(0, 0);
+ Assignment a = new Assignment(thisDotField, new NullLiteral(0, 0), 0);
+ md.selector = HandlerUtil.buildAccessorName("clear", new String(data.getPluralName())).toCharArray();
+ md.statements = returnStatement != null ? new Statement[] {a, returnStatement} : new Statement[] {a};
+ md.returnType = returnType;
+ injectMethod(builderType, md);
}
void generateSingularMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
- boolean mapMode = isMap();
- char[] keyName = !mapMode ? data.getSingularName() : (new String(data.getSingularName()) + "$key").toCharArray();
- char[] valueName = !mapMode ? null : (new String(data.getSingularName()) + "$value").toCharArray();
+ LombokImmutableList<String> suffixes = getArgumentSuffixes();
+ char[][] names = new char[suffixes.size()][];
+ for (int i = 0; i < suffixes.size(); i++) {
+ String s = suffixes.get(i);
+ char[] n = data.getSingularName();
+ names[i] = s.isEmpty() ? n : s.toCharArray();
+ }
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
@@ -126,40 +143,28 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
thisDotField.receiver = new ThisReference(0, 0);
MessageSend thisDotFieldDotAdd = new MessageSend();
- if (mapMode) {
- thisDotFieldDotAdd.arguments = new Expression[] {
- new SingleNameReference(keyName, 0L),
- new SingleNameReference(valueName, 0L)};
- } else {
- thisDotFieldDotAdd.arguments = new Expression[] {new SingleNameReference(keyName, 0L)};
+ thisDotFieldDotAdd.arguments = new Expression[suffixes.size()];
+ for (int i = 0; i < suffixes.size(); i++) {
+ thisDotFieldDotAdd.arguments[i] = new SingleNameReference(names[i], 0L);
}
thisDotFieldDotAdd.receiver = thisDotField;
- thisDotFieldDotAdd.selector = (mapMode ? "put" : "add").toCharArray();
+ thisDotFieldDotAdd.selector = getAddMethodName().toCharArray();
statements.add(thisDotFieldDotAdd);
if (returnStatement != null) statements.add(returnStatement);
md.statements = statements.toArray(new Statement[statements.size()]);
-
- if (mapMode) {
- TypeReference keyType = cloneParamType(0, data.getTypeArgs(), builderType);
- Argument keyParam = new Argument(keyName, 0, keyType, 0);
- TypeReference valueType = cloneParamType(1, data.getTypeArgs(), builderType);
- Argument valueParam = new Argument(valueName, 0, valueType, 0);
- md.arguments = new Argument[] {keyParam, valueParam};
- } else {
- TypeReference paramType = cloneParamType(0, data.getTypeArgs(), builderType);
- Argument param = new Argument(keyName, 0, paramType, 0);
- md.arguments = new Argument[] {param};
+ md.arguments = new Argument[suffixes.size()];
+ for (int i = 0; i < suffixes.size(); i++) {
+ TypeReference tr = cloneParamType(i, data.getTypeArgs(), builderType);
+ md.arguments[i] = new Argument(names[i], 0, tr, 0);
}
md.returnType = returnType;
- md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName(mapMode ? "put" : "add", new String(data.getSingularName())).toCharArray();
+ md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName(getAddMethodName(), new String(data.getSingularName())).toCharArray();
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
void generatePluralMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
- boolean mapMode = isMap();
-
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = ClassFileConstants.AccPublic;
@@ -172,40 +177,36 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
MessageSend thisDotFieldDotAddAll = new MessageSend();
thisDotFieldDotAddAll.arguments = new Expression[] {new SingleNameReference(data.getPluralName(), 0L)};
thisDotFieldDotAddAll.receiver = thisDotField;
- thisDotFieldDotAddAll.selector = (mapMode ? "putAll" : "addAll").toCharArray();
+ thisDotFieldDotAddAll.selector = (getAddMethodName() + "All").toCharArray();
statements.add(thisDotFieldDotAddAll);
if (returnStatement != null) statements.add(returnStatement);
md.statements = statements.toArray(new Statement[statements.size()]);
TypeReference paramType;
- if (mapMode) {
- paramType = new QualifiedTypeReference(JAVA_UTIL_MAP, NULL_POSS);
- paramType = addTypeArgs(2, true, builderType, paramType, data.getTypeArgs());
- } else {
- paramType = new QualifiedTypeReference(TypeConstants.JAVA_LANG_ITERABLE, NULL_POSS);
- paramType = addTypeArgs(1, true, builderType, paramType, data.getTypeArgs());
- }
+ paramType = new QualifiedTypeReference(fromQualifiedName(getAddAllTypeName()), NULL_POSS);
+ paramType = addTypeArgs(getTypeArgumentsCount(), true, builderType, paramType, data.getTypeArgs());
Argument param = new Argument(data.getPluralName(), 0, paramType, 0);
md.arguments = new Argument[] {param};
md.returnType = returnType;
- md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName(mapMode ? "putAll" : "addAll", new String(data.getPluralName())).toCharArray();
+ md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName(getAddMethodName() + "All", new String(data.getPluralName())).toCharArray();
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
@Override public void appendBuildCode(SingularData data, EclipseNode builderType, List<Statement> statements, char[] targetVariableName) {
- boolean mapMode = isMap();
TypeReference varType = new QualifiedTypeReference(fromQualifiedName(data.getTargetFqn()), NULL_POSS);
- varType = addTypeArgs(mapMode ? 2 : 1, false, builderType, varType, data.getTypeArgs());
+ String simpleTypeName = getSimpleTargetTypeName(data);
+ int agrumentsCount = getTypeArgumentsCount();
+ varType = addTypeArgs(agrumentsCount, false, builderType, varType, data.getTypeArgs());
MessageSend emptyInvoke; {
//ImmutableX.of()
emptyInvoke = new MessageSend();
emptyInvoke.selector = new char[] {'o', 'f'};
- emptyInvoke.receiver = new QualifiedNameReference(makeGuavaTypeName(getSimpleTargetTypeName(data), false), NULL_POSS, 0, 0);
- emptyInvoke.typeArguments = createTypeArgs(mapMode ? 2 : 1, false, builderType, data.getTypeArgs());
+ emptyInvoke.receiver = new QualifiedNameReference(makeGuavaTypeName(simpleTypeName, false), NULL_POSS, 0, 0);
+ emptyInvoke.typeArguments = createTypeArgs(agrumentsCount, false, builderType, data.getTypeArgs());
}
MessageSend invokeBuild; {
@@ -244,4 +245,12 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
createBuilderInvoke.selector = getBuilderMethodName(data);
return new IfStatement(cond, new Assignment(thisDotField2, createBuilderInvoke, 0), 0, 0);
}
+
+ protected abstract LombokImmutableList<String> getArgumentSuffixes();
+ protected abstract String getAddMethodName();
+ protected abstract String getAddAllTypeName();
+
+ protected int getTypeArgumentsCount() {
+ return getArgumentSuffixes().size();
+ }
}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaTableSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaTableSingularizer.java
new file mode 100644
index 00000000..4d25811b
--- /dev/null
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaTableSingularizer.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.handlers.singulars;
+
+import org.mangosdk.spi.ProviderFor;
+
+import lombok.core.LombokImmutableList;
+import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
+
+@ProviderFor(EclipseSingularizer.class)
+public class EclipseGuavaTableSingularizer extends EclipseGuavaSingularizer {
+ private static final LombokImmutableList<String> SUFFIXES =
+ LombokImmutableList.of("rowKey", "columnKey", "value");
+ private static final LombokImmutableList<String> SUPPORTED_TYPES =
+ LombokImmutableList.of("com.google.common.collect.ImmutableTable");
+
+ @Override public LombokImmutableList<String> getSupportedTypes() {
+ return SUPPORTED_TYPES;
+ }
+
+ @Override protected LombokImmutableList<String> getArgumentSuffixes() {
+ return SUFFIXES;
+ }
+
+ @Override protected String getAddMethodName() {
+ return "put";
+ }
+
+ @Override protected String getAddAllTypeName() {
+ return "com.google.common.collect.Table";
+ }
+}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
index 4b59f7a8..2d8083d3 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
@@ -34,11 +34,15 @@ import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
+import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
+import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
@@ -96,6 +100,29 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
generatePluralMethod(returnType, returnStatement, data, builderType, fluent);
+
+ returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
+ returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
+ generateClearMethod(returnType, returnStatement, data, builderType);
+ }
+
+ private void generateClearMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType) {
+ MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
+ md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
+ md.modifiers = ClassFileConstants.AccPublic;
+
+ FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
+ thisDotField.receiver = new ThisReference(0, 0);
+ FieldReference thisDotField2 = new FieldReference(data.getPluralName(), 0L);
+ thisDotField2.receiver = new ThisReference(0, 0);
+ md.selector = HandlerUtil.buildAccessorName("clear", new String(data.getPluralName())).toCharArray();
+ MessageSend clearMsg = new MessageSend();
+ clearMsg.receiver = thisDotField2;
+ clearMsg.selector = "clear".toCharArray();
+ Statement clearStatement = new IfStatement(new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.NOT_EQUAL), clearMsg, 0, 0);
+ md.statements = returnStatement != null ? new Statement[] {clearStatement, returnStatement} : new Statement[] {clearStatement};
+ md.returnType = returnType;
+ injectMethod(builderType, md);
}
void generateSingularMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
index 1c6b1ff3..ef9e2a76 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
@@ -32,13 +32,17 @@ import java.util.List;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
+import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
+import