aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java21
-rw-r--r--src/core/lombok/eclipse/handlers/HandleBuilder.java42
-rw-r--r--src/core/lombok/eclipse/handlers/singulars/EclipseGuavaMapSingularizer.java45
-rw-r--r--src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java45
-rw-r--r--src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java247
-rw-r--r--src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java3
-rw-r--r--src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java6
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java4
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacGuavaMapSingularizer.java119
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacGuavaSetListSingularizer.java116
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java142
11 files changed, 533 insertions, 257 deletions
diff --git a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
index 0157552b..e61e5d68 100644
--- a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
+++ b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
@@ -8,9 +8,12 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
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.IntLiteral;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
@@ -24,6 +27,8 @@ 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.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import lombok.core.LombokImmutableList;
@@ -101,14 +106,28 @@ public class EclipseSingularsRecipes {
private final List<TypeReference> typeArgs;
private final String targetFqn;
private final EclipseSingularizer singularizer;
+ private final ASTNode source;
- public SingularData(EclipseNode annotation, char[] singularName, char[] pluralName, List<TypeReference> typeArgs, String targetFqn, EclipseSingularizer singularizer) {
+ public SingularData(EclipseNode annotation, char[] singularName, char[] pluralName, List<TypeReference> typeArgs, String targetFqn, EclipseSingularizer singularizer, ASTNode source) {
this.annotation = annotation;
this.singularName = singularName;
this.pluralName = pluralName;
this.typeArgs = typeArgs;
this.targetFqn = targetFqn;
this.singularizer = singularizer;
+ this.source = source;
+ }
+
+ public void setGeneratedByRecursive(ASTNode target) {
+ SetGeneratedByVisitor visitor = new SetGeneratedByVisitor(source);
+
+ if (target instanceof AbstractMethodDeclaration) {
+ ((AbstractMethodDeclaration) target).traverse(visitor, (ClassScope) null);
+ } else if (target instanceof FieldDeclaration) {
+ ((FieldDeclaration) target).traverse(visitor, (MethodScope) null);
+ } else {
+ target.traverse(visitor, null);
+ }
}
public EclipseNode getAnnotation() {
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index 365256c7..b2ea7bbc 100644
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -62,6 +62,7 @@ import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.mangosdk.spi.ProviderFor;
@@ -71,6 +72,7 @@ import lombok.Builder;
import lombok.ConfigurationKeys;
import lombok.Singular;
import lombok.core.AST.Kind;
+import lombok.core.handlers.HandlerUtil;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
import lombok.eclipse.Eclipse;
@@ -89,6 +91,8 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
private static final boolean toBoolean(Object expr, boolean defaultValue) {
if (expr == null) return defaultValue;
+ if (expr instanceof FalseLiteral) return false;
+ if (expr instanceof TrueLiteral) return true;
return ((Boolean) expr).booleanValue();
}
@@ -153,7 +157,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
BuilderFieldData bfd = new BuilderFieldData();
bfd.name = removePrefixFromField(fieldNode);
bfd.type = fd.type;
- bfd.singularData = getSingularData(fieldNode);
+ bfd.singularData = getSingularData(fieldNode, ast);
builderFields.add(bfd);
allFields.add(fieldNode);
}
@@ -232,7 +236,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
Argument arg = (Argument) param.get();
bfd.name = arg.name;
bfd.type = arg.type;
- bfd.singularData = getSingularData(param);
+ bfd.singularData = getSingularData(param, ast);
builderFields.add(bfd);
}
}
@@ -253,12 +257,13 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
}
- generateBuilderFields(builderType, builderFields);
+ generateBuilderFields(builderType, builderFields, ast);
if (addCleaning) {
FieldDeclaration cleanDecl = new FieldDeclaration(CLEAN_FIELD_NAME, 0, -1);
cleanDecl.declarationSourceEnd = -1;
cleanDecl.modifiers = ClassFileConstants.AccPrivate;
cleanDecl.type = TypeReference.baseTypeReference(TypeIds.T_boolean, 0);
+ System.out.println("INJECTING: cleaning");
injectField(builderType, cleanDecl);
}
@@ -274,7 +279,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);
+ MethodDeclaration md = generateBuildMethod(buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, addCleaning, ast);
if (md != null) injectMethod(builderType, md);
}
@@ -287,17 +292,18 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
if (md != null) injectMethod(builderType, md);
}
- if (addCleaning) injectMethod(builderType, generateCleanMethod(builderFields, builderType));
+ if (addCleaning) {
+ MethodDeclaration cleanMethod = generateCleanMethod(builderFields, builderType, ast);
+ if (cleanMethod != null) injectMethod(builderType, cleanMethod);
+ }
if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
MethodDeclaration md = generateBuilderMethod(builderMethodName, builderClassName, tdParent, typeParams, ast);
if (md != null) injectMethod(tdParent, md);
}
-
- builderType.get().traverse(new SetGeneratedByVisitor(ast), null);
}
- private MethodDeclaration generateCleanMethod(List<BuilderFieldData> builderFields, EclipseNode builderType) {
+ private MethodDeclaration generateCleanMethod(List<BuilderFieldData> builderFields, EclipseNode builderType, ASTNode source) {
List<Statement> statements = new ArrayList<Statement>();
for (BuilderFieldData bfd : builderFields) {
@@ -309,16 +315,17 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
FieldReference thisUnclean = new FieldReference(CLEAN_FIELD_NAME, 0);
thisUnclean.receiver = new ThisReference(0, 0);
statements.add(new Assignment(thisUnclean, new FalseLiteral(0, 0), 0));
- MethodDeclaration decl =new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
+ MethodDeclaration decl = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
decl.selector = CLEAN_METHOD_NAME;
decl.modifiers = ClassFileConstants.AccPrivate;
decl.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
decl.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0);
decl.statements = statements.toArray(new Statement[0]);
+ decl.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
return decl;
}
- public MethodDeclaration generateBuildMethod(String name, char[] staticName, TypeReference returnType, List<BuilderFieldData> builderFields, EclipseNode type, TypeReference[] thrownExceptions, boolean addCleaning) {
+ public MethodDeclaration generateBuildMethod(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;
@@ -381,6 +388,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
}
out.statements = statements.isEmpty() ? null : statements.toArray(new Statement[statements.size()]);
+ out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
return out;
}
@@ -403,16 +411,14 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return out;
}
- public void generateBuilderFields(EclipseNode builderType, List<BuilderFieldData> builderFields) {
- int len = builderFields.size();
+ public void generateBuilderFields(EclipseNode builderType, List<BuilderFieldData> builderFields, ASTNode source) {
List<EclipseNode> existing = new ArrayList<EclipseNode>();
for (EclipseNode child : builderType.down()) {
if (child.getKind() == Kind.FIELD) existing.add(child);
}
top:
- for (int i = len - 1; i >= 0; i--) {
- BuilderFieldData bfd = builderFields.get(i);
+ for (BuilderFieldData bfd : builderFields) {
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
bfd.createdFields.addAll(bfd.singularData.getSingularizer().generateFields(bfd.singularData, builderType));
} else {
@@ -428,6 +434,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
fd.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
fd.modifiers = ClassFileConstants.AccPrivate;
fd.type = copyType(bfd.type);
+ fd.traverse(new SetGeneratedByVisitor(source), (MethodScope) null);
bfd.createdFields.add(injectField(builderType, fd));
}
}
@@ -457,8 +464,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
if (Arrays.equals(name, existingName)) return;
}
- boolean isBoolean = isBoolean(fd.type);
- String setterName = fluent ? fieldNode.getName() : toSetterName(builderType.getAst(), null, fieldNode.getName(), isBoolean);
+ String setterName = fluent ? fieldNode.getName() : HandlerUtil.buildAccessorName("set", fieldNode.getName());
MethodDeclaration setter = HandleSetter.createSetter(td, fieldNode, setterName, chain, ClassFileConstants.AccPublic,
sourceNode, Collections.<Annotation>emptyList(), Collections.<Annotation>emptyList());
@@ -492,7 +498,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
*
* @param node The node (field or method param) to inspect for its name and potential {@code @Singular} annotation.
*/
- private SingularData getSingularData(EclipseNode node) {
+ private SingularData getSingularData(EclipseNode node, ASTNode source) {
for (EclipseNode child : node.down()) {
if (child.getKind() == Kind.ANNOTATION && annotationTypeMatches(Singular.class, child)) {
char[] pluralName = node.getKind() == Kind.FIELD ? removePrefixFromField(node) : ((AbstractVariableDeclaration) node.get()).name;
@@ -534,7 +540,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return null;
}
- return new SingularData(child, singularName, pluralName, typeArgs == null ? Collections.<TypeReference>emptyList() : Arrays.asList(typeArgs), targetFqn, singularizer);
+ return new SingularData(child, singularName, pluralName, typeArgs == null ? Collections.<TypeReference>emptyList() : Arrays.asList(typeArgs), targetFqn, singularizer, source);
}
}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaMapSingularizer.java
new file mode 100644
index 00000000..95fd8935
--- /dev/null
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaMapSingularizer.java
@@ -0,0 +1,45 @@
+/*
+ * 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 EclipseGuavaMapSingularizer extends EclipseGuavaSingularizer {
+ // TODO cgcc.ImmutableMultimap, cgcc.ImmutableListMultimap, cgcc.ImmutableSetMultimap
+ // TODO cgcc.ImmutableClassToInstanceMap
+ // TODO cgcc.ImmutableRangeMap
+
+ @Override public LombokImmutableList<String> getSupportedTypes() {
+ return LombokImmutableList.of(
+ "com.google.common.collect.ImmutableMap",
+ "com.google.common.collect.ImmutableBiMap",
+ "com.google.common.collect.ImmutableSortedMap");
+ }
+
+ @Override protected boolean isMap() {
+ return true;
+ }
+}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java
new file mode 100644
index 00000000..bc2893bf
--- /dev/null
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSetListSingularizer.java
@@ -0,0 +1,45 @@
+/*
+ * 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 EclipseGuavaSetListSingularizer extends EclipseGuavaSingularizer {
+ // TODO com.google.common.collect.ImmutableTable
+ // TODO com.google.common.collect.ImmutableRangeSet
+ // TODO com.google.common.collect.ImmutableMultiset and com.google.common.collect.ImmutableSortedMultiset
+ @Override public LombokImmutableList<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");
+ }
+
+ @Override protected boolean isMap() {
+ return false;
+ }
+}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
new file mode 100644
index 00000000..775d4ed5
--- /dev/null
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
@@ -0,0 +1,247 @@
+/*
+ * 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 static lombok.eclipse.Eclipse.*;
+import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import lombok.core.handlers.HandlerUtil;
+import lombok.eclipse.EclipseNode;
+import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
+import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData;
+
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.Assignment;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
+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.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
+import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+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) {
+ String simpleTypeName = data.getTargetSimpleType();
+ if ("ImmutableCollection".equals(simpleTypeName)) return "ImmutableList";
+ return simpleTypeName;
+ }
+
+ protected char[] getBuilderMethodName(SingularData data) {
+ String simpleTypeName = data.getTargetSimpleType();
+ if ("ImmutableSortedSet".equals(simpleTypeName) || "ImmutableSortedMap".equals(simpleTypeName)) return "naturalOrder".toCharArray();
+ return "builder".toCharArray();
+ }
+
+ protected abstract boolean isMap();
+
+ protected char[][] makeGuavaTypeName(String simpleName, boolean addBuilder) {
+ char[][] tokenizedName = new char[addBuilder ? 6 : 5][];
+ tokenizedName[0] = new char[] {'c', 'o', 'm'};
+ tokenizedName[1] = new char[] {'g', 'o', 'o', 'g', 'l', 'e'};
+ tokenizedName[2] = new char[] {'c', 'o', 'm', 'm', 'o', 'n'};
+ tokenizedName[3] = new char[] {'c', 'o', 'l', 'l', 'e', 'c', 't'};
+ tokenizedName[4] = simpleName.toCharArray();
+ if (addBuilder) tokenizedName[5] = new char[] { 'B', 'u', 'i', 'l', 'd', 'e', 'r'};
+ return tokenizedName;
+ }
+
+ @Override public List<EclipseNode> generateFields(SingularData data, EclipseNode builderType) {
+ char[][] tokenizedName = makeGuavaTypeName(getSimpleTargetTypeName(data), true);
+ TypeReference type = new QualifiedTypeReference(tokenizedName, NULL_POSS);
+ type = addTypeArgs(isMap() ? 2 : 1, false, builderType, type, data.getTypeArgs());
+
+ FieldDeclaration buildField = new FieldDeclaration(data.getPluralName(), 0, -1);
+ buildField.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
+ buildField.modifiers = ClassFileConstants.AccPrivate;
+ buildField.declarationSourceEnd = -1;
+ buildField.type = type;
+ data.setGeneratedByRecursive(buildField);
+ return Collections.singletonList(injectField(builderType, buildField));
+ }
+
+ @Override public void generateMethods(SingularData data, EclipseNode builderType, boolean fluent, boolean chain) {
+ TypeReference returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
+ Statement returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
+ generateSingularMethod(returnType, returnStatement, data, builderType, fluent);
+
+ returnType = chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
+ returnStatement = chain ? new ReturnStatement(new ThisReference(0, 0), 0, 0) : null;
+ generatePluralMethod(returnType, returnStatement, data, builderType, fluent);
+ }
+
+ void generateSingularMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
+ boolean mapMode = isMap();
+ char[] keyName = !mapMode ? data.getSingularName() : (new String(data.getSingularName()) + "$key").toCharArray();
+ char[] valueName = !mapMode ? null : (new String(data.getSingularName()) + "$value").toCharArray();
+
+ MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
+ md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
+ md.modifiers = ClassFileConstants.AccPublic;
+
+ List<Statement> statements = new ArrayList<Statement>();
+ statements.add(createConstructBuilderVarIfNeeded(data, builderType));
+
+ 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.receiver = thisDotField;
+ thisDotFieldDotAdd.selector = (mapMode ? "put" : "add").toCharArray();
+ statements.add(thisDotFieldDotAdd);
+ if (returnStatement != null) statements.add(returnStatement);
+ md.statements = statements.toArray(new Statement[statements.size()]);
+
+ if (mapMode) {
+ TypeReference keyType = cloneParamType(0, data.getTypeArgs(), builderType);
+ Argument keyParam = new Argument(keyName, 0, keyType, 0);
+ 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.returnType = returnType;
+ md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName(mapMode ? "put" : "add", new String(data.getSingularName())).toCharArray();
+
+ data.setGeneratedByRecursive(md);
+ injectMethod(builderType, md);
+ }
+
+ void generatePluralMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
+ boolean mapMode = isMap();
+
+ MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
+ md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
+ md.modifiers = ClassFileConstants.AccPublic;
+
+ List<Statement> statements = new ArrayList<Statement>();
+ statements.add(createConstructBuilderVarIfNeeded(data, builderType));
+
+ FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
+ thisDotField.receiver = new ThisReference(0, 0);
+ MessageSend thisDotFieldDotAddAll = new MessageSend();
+ thisDotFieldDotAddAll.arguments = new Expression[] {new SingleNameReference(data.getPluralName(), 0L)};
+ thisDotFieldDotAddAll.receiver = thisDotField;
+ thisDotFieldDotAddAll.selector = (mapMode ? "putAll" : "addAll").toCharArray();
+ 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());
+ }
+ 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();
+
+ 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());
+
+ 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);
+ }
+
+ MessageSend invokeBuild; {
+ //this.pluralName.build();
+ invokeBuild = new MessageSend();
+ invokeBuild.selector = new char[] {'b', 'u', 'i', 'l', 'd'};
+ FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
+ thisDotField.receiver = new ThisReference(0, 0);
+ invokeBuild.receiver = thisDotField;
+ }
+
+ Expression isNull; {
+ //this.pluralName == null
+ FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
+ thisDotField.receiver = new ThisReference(0, 0);
+ isNull = new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.EQUAL_EQUAL);
+ }
+
+ Expression init = new ConditionalExpression(isNull, emptyInvoke, invokeBuild);
+ LocalDeclaration varDefStat = new LocalDeclaration(data.getPluralName(), 0, 0);
+ varDefStat.type = varType;
+ varDefStat.initialization = init;
+ statements.add(varDefStat);
+ }
+
+ protected Statement createConstructBuilderVarIfNeeded(SingularData data, EclipseNode builderType) {
+ FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
+ thisDotField.receiver = new ThisReference(0, 0);
+ FieldReference thisDotField2 = new FieldReference(data.getPluralName(), 0L);
+ thisDotField2.receiver = new ThisReference(0, 0);
+ Expression cond = new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.EQUAL_EQUAL);
+
+ MessageSend createBuilderInvoke = new MessageSend();
+ char[][] tokenizedName = makeGuavaTypeName(getSimpleTargetTypeName(data), false);
+ createBuilderInvoke.receiver = new QualifiedNameReference(tokenizedName, NULL_POSS, 0, 0);
+ createBuilderInvoke.selector = getBuilderMethodName(data);
+ return new IfStatement(cond, new Assignment(thisDotField2, createBuilderInvoke, 0), 0, 0);
+ }
+}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
index 64b8bd40..f64748a8 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
@@ -59,6 +59,7 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
buildField.modifiers = ClassFileConstants.AccPrivate;
buildField.declarationSourceEnd = -1;
buildField.type = type;
+ data.setGeneratedByRecursive(buildField);
return Collections.singletonList(injectField(builderType, buildField));
}
@@ -96,6 +97,7 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
md.returnType = returnType;
md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray();
+ data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
@@ -125,6 +127,7 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
md.returnType = returnType;
md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray();
+ data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
index 8e250994..6558baa5 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
@@ -85,8 +85,10 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
buildValueField.declarationSourceEnd = -1;
buildValueField.type = type;
}
- EclipseNode valueFieldNode = injectField(builderType, buildValueField);
+ data.setGeneratedByRecursive(buildKeyField);
+ data.setGeneratedByRecursive(buildValueField);
EclipseNode keyFieldNode = injectField(builderType, buildKeyField);
+ EclipseNode valueFieldNode = injectField(builderType, buildValueField);
return Arrays.asList(keyFieldNode, valueFieldNode);
}
@@ -145,6 +147,7 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
md.returnType = returnType;
md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName("put", new String(data.getSingularName())).toCharArray();
+ data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
@@ -207,6 +210,7 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
md.returnType = returnType;
md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName("putAll", new String(data.getPluralName())).toCharArray();
+ data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index 86598b3e..24e9dee4 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -54,6 +54,7 @@ import lombok.Singular;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
+import lombok.core.handlers.HandlerUtil;
import lombok.experimental.NonFinal;
import lombok.javac.Javac;
import lombok.javac.JavacAnnotationHandler;
@@ -416,8 +417,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
if (existingName.equals(fieldName)) return;
}
- boolean isBoolean = isBoolean(fieldNode);
- String setterName = fluent ? fieldNode.getName() : toSetterName(fieldNode.getAst(), null, fieldNode.getName(), isBoolean);
+ String setterName = fluent ? fieldNode.getName() : HandlerUtil.buildAccessorName("set", fieldNode.getName());
JavacTreeMaker maker = fieldNode.getTreeMaker();
JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, fieldNode, maker, setterName, chain, source, List.<JCAnnotation>nil(), List.<JCAnnotation>nil());
diff --git a/src/core/lombok/javac/handlers/singulars/JavacGuavaMapSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacGuavaMapSingularizer.java
index af39c3ba..0700e2e5 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacGuavaMapSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacGuavaMapSingularizer.java
@@ -21,34 +21,11 @@
*/
package lombok.javac.handlers.singulars;
-import static lombok.javac.Javac.*;
-import static lombok.javac.handlers.JavacHandlerUtil.*;
-
-import java.util.Collections;
-
import lombok.core.LombokImmutableList;
-import lombok.core.handlers.HandlerUtil;
-import lombok.javac.JavacNode;
-import lombok.javac.JavacTreeMaker;
-import lombok.javac.handlers.JavacHandlerUtil;
import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
-import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
import org.mangosdk.spi.ProviderFor;
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCBlock;
-import com.sun.tools.javac.tree.JCTree.JCExpression;
-import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
-import com.sun.tools.javac.tree.JCTree.JCModifiers;
-import com.sun.tools.javac.tree.JCTree.JCStatement;
-import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.util.Name;
-
@ProviderFor(JavacSingularizer.class)
public class JavacGuavaMapSingularizer extends JavacGuavaSingularizer {
// TODO cgcc.ImmutableMultimap, cgcc.ImmutableListMultimap, cgcc.ImmutableSetMultimap
@@ -62,99 +39,7 @@ public class JavacGuavaMapSingularizer extends JavacGuavaSingularizer {
"com.google.common.collect.ImmutableSortedMap");
}
- @Override public java.util.List<JavacNode> generateFields(SingularData data, JavacNode builderType, JCTree source) {
- JavacTreeMaker maker = builderType.getTreeMaker();
- JCExpression type = JavacHandlerUtil.chainDots(builderType, "com", "google", "common", "collect", getSimpleTargetTypeName(data), "Builder");
- type = addTypeArgs(2, false, builderType, type, data.getTypeArgs(), source);
-
- JCVariableDecl buildField = maker.VarDef(maker.Modifiers(Flags.PRIVATE), data.getPluralName(), type, null);
- return Collections.singletonList(injectField(builderType, buildField));
- }
-
- @Override public void generateMethods(SingularData data, JavacNode builderType, JCTree source, boolean fluent, boolean chain) {
- JavacTreeMaker maker = builderType.getTreeMaker();
- JCExpression returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
- JCStatement returnStatement = chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
- generateSingularMethod(maker, returnType, returnStatement, data, builderType, source, fluent);
-
- returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
- returnStatement = chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
- generatePluralMethod(maker, returnType, returnStatement, data, builderType, source, fluent);
- }
-
- private void generateSingularMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
- List<JCTypeParameter> typeParams = List.nil();
- List<JCExpression> thrown = List.nil();
-
- Name keyName = builderType.toName(data.getSingularName() + "$key");
- Name valueName = builderType.toName(data.getSingularName() + "$value");
-
- JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
- ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
- statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, true, source));
- JCExpression thisDotFieldDotPut = chainDots(builderType, "this", data.getPluralName().toString(), "put");
- JCExpression invokePut = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotPut, List.<JCExpression>of(maker.Ident(keyName), maker.Ident(valueName)));
- statements.append(maker.Exec(invokePut));
- if (returnStatement != null) statements.append(returnStatement);
- JCBlock body = maker.Block(0, statements.toList());
- Name name = data.getSingularName();
- long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
- if (!fluent) name = builderType.toName(HandlerUtil.buildAccessorName("put", name.toString()));
- JCExpression keyType = cloneParamType(0, maker, data.getTypeArgs(), builderType, source);
- JCExpression valueType = cloneParamType(1, maker, data.getTypeArgs(), builderType, source);
- JCVariableDecl paramKey = maker.VarDef(maker.Modifiers(paramFlags), keyName, keyType, null);
- JCVariableDecl paramValue = maker.VarDef(maker.Modifiers(paramFlags), valueName, valueType, null);
- JCMethodDecl method = maker.MethodDef(mods, name, returnType, typeParams, List.of(paramKey, paramValue), thrown, body, null);
- injectMethod(builderType, method);
- }
-
- private void generatePluralMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
- List<JCTypeParameter> typeParams = List.nil();
- List<JCExpression> thrown = List.nil();
- JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
- ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
- statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, true, source));
- JCExpression thisDotFieldDotPutAll = chainDots(builderType, "this", data.getPluralName().toString(), "putAll");
- JCExpression invokePutAll = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotPutAll, List.<JCExpression>of(maker.Ident(data.getPluralName())));
- statements.append(maker.Exec(invokePutAll));
- if (returnStatement != null) statements.append(returnStatement);
- JCBlock body = maker.Block(0, statements.toList());
- Name name = data.getPluralName();
- long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
- if (!fluent) name = builderType.toName(HandlerUtil.buildAccessorName("putAll", name.toString()));
- JCExpression paramType = chainDots(builderType, "java", "util", "Map");
- paramType = addTypeArgs(2, true, builderType, paramType, data.getTypeArgs(), source);
- JCVariableDecl param = maker.VarDef(maker.Modifiers(paramFlags), data.getPluralName(), paramType, null);
- JCMethodDecl method = maker.MethodDef(mods, name, returnType, typeParams, List.of(param), thrown, body, null);
- injectMethod(builderType, method);
- }
-
- @Override public void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName) {
- JavacTreeMaker maker = builderType.getTreeMaker();
- List<JCExpression> jceBlank = List.nil();
-
- JCExpression varType = chainDotsString(builderType, data.getTargetFqn());
- varType = addTypeArgs(2, false, builderType, varType, data.getTypeArgs(), source);
-
- JCExpression empty; {
- //ImmutableX.of()
- JCExpression emptyMethod = chainDots(builderType, "com", "google", "common", "collect", getSimpleTargetTypeName(data), "of");
- empty = maker.Apply(jceBlank, emptyMethod, jceBlank);
- }
-
- JCExpression invokeBuild; {
- //this.pluralName.build();
- invokeBuild = maker.Apply(jceBlank, chainDots(builderType, "this", data.getPluralName().toString(), "build"), jceBlank);
- }
-
- JCExpression isNull; {
- //this.pluralName == null
- isNull = maker.Binary(CTC_EQUAL, maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName()), maker.Literal(CTC_BOT, null));
- }
-
- JCExpression init = maker.Conditional(isNull, empty, invokeBuild); // this.pluralName == null ? ImmutableX.of() : this.pluralName.build()
-
- JCStatement jcs = maker.VarDef(maker.Modifiers(0), data.getPluralName(), varType, init);
- statements.append(jcs);
+ @Override protected boolean isMap() {
+ return true;
}
}
diff --git a/src/core/lombok/javac/handlers/singulars/JavacGuavaSetListSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacGuavaSetListSingularizer.java
index 54ba091b..2e404ca8 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacGuavaSetListSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacGuavaSetListSingularizer.java
@@ -21,33 +21,10 @@
*/
package lombok.javac.handlers.singulars;
-import static lombok.javac.Javac.*;
-import static lombok.javac.handlers.JavacHandlerUtil.*;
-
-import java.util.Collections;
-
-import org.mangosdk.spi.ProviderFor;
-
import lombok.core.LombokImmutableList;
-import lombok.core.handlers.HandlerUtil;
-import lombok.javac.JavacNode;
-import lombok.javac.JavacTreeMaker;
-import lombok.javac.handlers.JavacHandlerUtil;
import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
-import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCBlock;
-import com.sun.tools.javac.tree.JCTree.JCExpression;
-import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
-import com.sun.tools.javac.tree.JCTree.JCModifiers;
-import com.sun.tools.javac.tree.JCTree.JCStatement;
-import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.util.Name;
+import org.mangosdk.spi.ProviderFor;
@ProviderFor(JavacSingularizer.class)
public class JavacGuavaSetListSingularizer extends JavacGuavaSingularizer {
@@ -62,94 +39,7 @@ public class JavacGuavaSetListSingularizer extends JavacGuavaSingularizer {
"com.google.common.collect.ImmutableSortedSet");
}
- @Override public java.util.List<JavacNode> generateFields(SingularData data, JavacNode builderType, JCTree source) {
- JavacTreeMaker maker = builderType.getTreeMaker();
- JCExpression type = JavacHandlerUtil.chainDots(builderType, "com", "google", "common", "collect", getSimpleTargetTypeName(data), "Builder");
- type = addTypeArgs(1, false, builderType, type, data.getTypeArgs(), source);
-
- JCVariableDecl buildField = maker.VarDef(maker.Modifiers(Flags.PRIVATE), data.getPluralName(), type, null);
- return Collections.singletonList(injectField(builderType, buildField));
- }
-
- @Override public void generateMethods(SingularData data, JavacNode builderType, JCTree source, boolean fluent, boolean chain) {
- JavacTreeMaker maker = builderType.getTreeMaker();
- JCExpression returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
- JCStatement returnStatement = chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
- generateSingularMethod(maker, returnType, returnStatement, data, builderType, source, fluent);
-
- returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
- returnStatement = chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
- generatePluralMethod(maker, returnType, returnStatement, data, builderType, source, fluent);
- }
-
- private void generateSingularMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
- List<JCTypeParameter> typeParams = List.nil();
- List<JCExpression> thrown = List.nil();
-
- JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
- ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
- statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, false, source));
- JCExpression thisDotFieldDotAdd = chainDots(builderType, "this", data.getPluralName().toString(), "add");
- JCExpression invokeAdd = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotAdd, List.<JCExpression>of(maker.Ident(data.getSingularName())));
- statements.append(maker.Exec(invokeAdd));
- if (returnStatement != null) statements.append(returnStatement);
- JCBlock body = maker.Block(0, statements.toList());
- Name name = data.getSingularName();
- long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
- if (!fluent) name = builderType.toName(HandlerUtil.buildAccessorName("add", name.toString()));
- JCExpression paramType = cloneParamType(0, maker, data.getTypeArgs(), builderType, source);
- JCVariableDecl param = maker.VarDef(maker.Modifiers(paramFlags), data.getSingularName(), paramType, null);
- JCMethodDecl method = maker.MethodDef(mods, name, returnType, typeParams, List.of(param), thrown, body, null);
- injectMethod(builderType, method);
- }
-
- private void generatePluralMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
- List<JCTypeParameter> typeParams = List.nil();
- List<JCExpression> thrown = List.nil();
- JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
- ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
- statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, false, source));
- JCExpression thisDotFieldDotAdd = chainDots(builderType, "this", data.getPluralName().toString(), "addAll");
- JCExpression invokeAdd = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotAdd, List.<JCExpression>of(maker.Ident(data.getPluralName())));
- statements.append(maker.Exec(invokeAdd));
- if (returnStatement != null) statements.append(returnStatement);
- JCBlock body = maker.Block(0, statements.toList());
- Name name = data.getPluralName();
- long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
- if (!fluent) name = builderType.toName(HandlerUtil.buildAccessorName("addAll", name.toString()));
- JCExpression paramType = chainDots(builderType, "java", "lang", "Iterable");
- paramType = addTypeArgs(1, true, builderType, paramType, data.getTypeArgs(), source);
- JCVariableDecl param = maker.VarDef(maker.Modifiers(paramFlags), data.getPluralName(), paramType, null);
- JCMethodDecl method = maker.MethodDef(mods, name, returnType, typeParams, List.of(param), thrown, body, null);
- injectMethod(builderType, method);
- }
-
- @Override public void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName) {
- JavacTreeMaker maker = builderType.getTreeMaker();
- List<JCExpression> jceBlank = List.nil();
-
- JCExpression varType = chainDotsString(builderType, data.getTargetFqn());
- varType = addTypeArgs(1, false, builderType, varType, data.getTypeArgs(), source);
-
- JCExpression empty; {
- //ImmutableX.of()
- JCExpression emptyMethod = chainDots(builderType, "com", "google", "common", "collect", getSimpleTargetTypeName(data), "of");
- empty = maker.Apply(jceBlank, emptyMethod, jceBlank);
- }
-
- JCExpression invokeBuild; {
- //this.pluralName.build();
- invokeBuild = maker.Apply(jceBlank, chainDots(builderType, "this", data.getPluralName().toString(), "build"), jceBlank);
- }
-
- JCExpression isNull; {
- //this.pluralName == null
- isNull = maker.Binary(CTC_EQUAL, maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName()), maker.Literal(CTC_BOT, null));
- }
-
- JCExpression init = maker.Conditional(isNull, empty, invokeBuild); // this.pluralName == null ? ImmutableX.of() : this.pluralName.build()
-
- JCStatement jcs = maker.VarDef(maker.Modifiers(0), data.getPluralName(), varType, init);
- statements.append(jcs);
+ @Override protected boolean isMap() {
+ return false;
}
}
diff --git a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
index ae9f34c5..62cbc98b 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
@@ -22,18 +22,30 @@
package lombok.javac.handlers.singulars;
import static lombok.javac.Javac.*;
-import static lombok.javac.handlers.JavacHandlerUtil.chainDots;
+import static lombok.javac.handlers.JavacHandlerUtil.*;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCExpression;
-import com.sun.tools.javac.tree.JCTree.JCStatement;
-import com.sun.tools.javac.util.List;
+import java.util.Collections;
+import lombok.core.handlers.HandlerUtil;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
+import lombok.javac.handlers.JavacHandlerUtil;
import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCBlock;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCModifiers;
+import com.sun.tools.javac.tree.JCTree.JCStatement;
+import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Name;
+
abstract class JavacGuavaSingularizer extends JavacSingularizer {
protected String getSimpleTargetTypeName(SingularData data) {
String simpleTypeName = data.getTargetSimpleType();
@@ -47,6 +59,126 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
return "builder";
}
+ protected abstract boolean isMap();
+
+ @Override public java.util.List<JavacNode> generateFields(SingularData data, JavacNode builderType, JCTree source) {
+ JavacTreeMaker maker = builderType.getTreeMaker();
+ JCExpression type = JavacHandlerUtil.chainDots(builderType, "com", "google", "common", "collect", getSimpleTargetTypeName(data), "Builder");
+ type = addTypeArgs(isMap() ? 2 : 1, false, builderType, type, data.getTypeArgs(), source);
+
+ JCVariableDecl buildField = maker.VarDef(maker.Modifiers(Flags.PRIVATE), data.getPluralName(), type, null);
+ return Collections.singletonList(injectField(builderType, buildField));
+ }
+
+ @Override public void generateMethods(SingularData data, JavacNode builderType, JCTree source, boolean fluent, boolean chain) {
+ JavacTreeMaker maker = builderType.getTreeMaker();
+ JCExpression returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
+ JCStatement returnStatement = chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
+ generateSingularMethod(maker, returnType, returnStatement, data, builderType, source, fluent);
+
+ returnType = chain ? cloneSelfType(builderType) : maker.Type(createVoidType(maker, CTC_VOID));
+ returnStatement = chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
+ generatePluralMethod(maker, returnType, returnStatement, data, builderType, source, fluent);
+ }
+
+ void generateSingularMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
+ List<JCTypeParameter> typeParams = List.nil();
+ List<JCExpression> thrown = List.nil();
+ boolean mapMode = isMap();
+
+ Name keyName = !mapMode ? data.getSingularName() : builderType.toName(data.getSingularName() + "$key");
+ Name valueName = !mapMode ? null : builderType.toName(data.getSingularName() + "$value");
+
+ JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
+ ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
+ statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, mapMode, source));
+ JCExpression thisDotFieldDotAdd = chainDots(builderType, "this", data.getPluralName().toString(), mapMode ? "put" : "add");
+ List<JCExpression> invokeAddExpr;
+ if (mapMode) {
+ invokeAddExpr = List.<JCExpression>of(maker.Ident(keyName), maker.Ident(valueName));
+ } else {
+ invokeAddExpr = List.<JCExpression>of(maker.Ident(keyName));
+ }
+ JCExpression invokeAdd = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotAdd, invokeAddExpr);
+ statements.append(maker.Exec(invokeAdd));
+ if (returnStatement != null) statements.append(returnStatement);
+ JCBlock body = maker.Block(0, statements.toList());
+ Name methodName = data.getSingularName();
+ long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
+ if (!fluent) methodName = builderType.toName(HandlerUtil.buildAccessorName(mapMode ? "put" : "add", methodName.toString()));
+ List<JCVariableDecl> params;
+ if (mapMode) {
+ JCExpression keyType = cloneParamType(0, maker, data.getTypeArgs(), builderType, source);
+ JCExpression valueType = cloneParamType(1, maker, data.getTypeArgs(), builderType, source);
+ JCVariableDecl paramKey = maker.VarDef(maker.Modifiers(paramFlags), keyName, keyType, null);
+ JCVariableDecl paramValue = maker.VarDef(maker.Modifiers(paramFlags), valueName, valueType, null);
+ params = List.of(paramKey, paramValue);
+ } else {
+ JCExpression paramType = cloneParamType(0, maker, data.getTypeArgs(), builderType, source);
+ params = List.of(maker.VarDef(maker.Modifiers(paramFlags), data.getSingularName(), paramType, null));
+ }
+ JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, params, thrown, body, null);
+ injectMethod(builderType, method);
+ }
+
+ protected void generatePluralMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
+ List<JCTypeParameter> typeParams = List.nil();
+ List<JCExpression> thrown = List.nil();
+ boolean mapMode = isMap();
+
+ JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
+ ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
+ statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, mapMode, source));
+ JCExpression thisDotFieldDotAddAll = chainDots(builderType, "this", data.getPluralName().toString(), mapMode ? "putAll" : "addAll");
+ JCExpression invokeAddAll = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotAddAll, List.<JCExpression>of(maker.Ident(data.getPluralName())));
+ statements.append(maker.Exec(invokeAddAll));
+ if (returnStatement != null) statements.append(returnStatement);
+ JCBlock body = maker.Block(0, statements.toList());
+ Name methodName = data.getPluralName();
+ long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
+ if (!fluent) methodName = builderType.toName(HandlerUtil.buildAccessorName(mapMode ? "putAll" : "addAll", methodName.toString()));
+ JCExpression paramType;
+ if (mapMode) {
+ paramType = chainDots(builderType, "java", "util", "Map");
+ } else {
+ paramType = chainDots(builderType, "java", "lang", "Iterable");
+ }
+ paramType = addTypeArgs(mapMode ? 2 : 1, true, builderType, paramType, data.getTypeArgs(), source);
+ JCVariableDecl param = maker.VarDef(maker.Modifiers(paramFlags), data.getPluralName(), paramType, null);
+ JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, List.of(param), thrown, body, null);
+ injectMethod(builderType, method);
+ }
+
+ @Override public void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName) {
+ JavacTreeMaker maker = builderType.getTreeMaker();
+ List<JCExpression> jceBlank = List.nil();
+ boolean mapMode = isMap();
+
+ JCExpression varType = chainDotsString(builderType, data.getTargetFqn());
+ varType = addTypeArgs(mapMode ? 2 : 1, false, builderType, varType, data.getTypeArgs(), source);
+
+ JCExpression empty; {
+ //ImmutableX.of()
+ JCExpression emptyMethod = chainDots(builderType, "com", "google", "common", "collect", getSimpleTargetTypeName(data), "of");
+ empty = maker.Apply(jceBlank, emptyMethod, jceBlank);
+ }
+
+ JCExpression invokeBuild; {
+ //this.pluralName.build();
+ invokeBuild = maker.Apply(jceBlank, chainDots(builderType, "this", data.getPluralName().toString(), "build"), jceBlank);
+ }
+
+ JCExpression isNull; {
+ //this.pluralName == null
+ isNull = maker.Binary(CTC_EQUAL, maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName()), maker.Literal(CTC_BOT, null));
+ }
+
+ JCExpression init = maker.Conditional(isNull, empty, invokeBuild); // this.pluralName == null ? ImmutableX.of() : this.pluralName.build()
+
+ JCStatement jcs = maker.VarDef(maker.Modifiers(0), data.getPluralName(), varType, init);
+ statements.append(jcs);
+ }
+
protected JCStatement createConstructBuilderVarIfNeeded(JavacTreeMaker maker, SingularData data, JavacNode builderType, boolean mapMode, JCTree source) {
List<JCExpression> jceBlank = List.nil();