diff options
| author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2015-11-17 02:15:31 +0100 |
|---|---|---|
| committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2015-11-17 02:15:31 +0100 |
| commit | 0bd688d7e624d95fef921f8b463209d70b92779a (patch) | |
| tree | 19c7dc3d6e996ee96cfe4c02fbe6d651945885a7 | |
| parent | 0e34eec7668ee060fe65133243009dbb27e7c251 (diff) | |
| parent | 5b6829b86379321be378490b895827cd6bca13f1 (diff) | |
| download | lombok-0bd688d7e624d95fef921f8b463209d70b92779a.tar.gz lombok-0bd688d7e624d95fef921f8b463209d70b92779a.tar.bz2 lombok-0bd688d7e624d95fef921f8b463209d70b92779a.zip | |
Merge branch 'builderUpdate'
41 files changed, 1005 insertions, 208 deletions
@@ -3,6 +3,7 @@ Lombok contributors in alphabetical order: Christian Sterzl <christian.sterzl@gmail.com> DaveLaw <project.lombok@apconsult.de> Dawid Rusin <dawidrusin90@gmail.com> +Enrique da Costa Cambio <enrique.dacostacambio@gmail.com> Jappe van der Hel <jappe.vanderhel@gmail.com> Luan Nico <luannico27@gmail.com> Maarten Mulders <mthmulders@users.noreply.github.com> @@ -12,6 +13,7 @@ Reinier Zwitserloot <reinier@zwitserloot.com> Robbert Jan Grootjans <grootjans@gmail.com> Roel Spilker <r.spilker@gmail.com> Sander Koning <askoning@gmail.com> +Szymon Pacanowski <spacanowski@gmail.com> Taiki Sugawara <buzz.taiki@gmail.com> Yun Zhi Lin <yun@yunspace.com> diff --git a/doc/changelog.markdown b/doc/changelog.markdown index da1cefce..d5850457 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -2,6 +2,9 @@ Lombok Changelog ---------------- ### v1.16.7 "Edgy Guinea Pig" +* FEATURE: `@Builder` updates: It now generates `clearFieldName()` methods if `@Singular` is used. [Issue #967](https://github.com/rzwitserloot/lombok/issues/967). +* FEATURE: `@Builder` updates: The annotation can now be put on instance methods. [Issue #63](https://github.com/rzwitserloot/lombok/issues/63). +* FEATURE: `@Builder` updates: `@Singular` now supports guava's ImmutableTable [Issue #937](https://github.com/rzwitserloot/lombok/issues/937). * FEATURE: A `lombok.config` key can now be used to make your fields `final` and/or `private`... __everywhere__. We'll be monitoring the performance impact of this for a while. We'll touch every source file if you turn these on, and even if you don't, we have to call into the lombok config system for every file. * BUGFIX: `@Value` and `@FieldDefaults` no longer make uninitialized static fields final. [Issue #928](https://github.com/rzwitserloot/lombok/issues/928). * BUGFIX: When using delombok, a source file with only `@NonNull` annotations on parameters as lombok feature would not get properly delomboked. [Issue #950](https://github.com/rzwitserloot/lombok/issues/950). 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 @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(); |
