From 19ad4fd57d32afad1a33f20613fbb2e7607cfee0 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot <reinier@zwitserloot.com>
Date: Wed, 13 Jun 2018 23:21:00 +0200
Subject: [SuperBuilder] code review, style update, making it JDK1.6
 compatible, documentation review, bugfix for setter auto-presuming chaining
 even when you didn’t configure it to chain.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/core/lombok/javac/handlers/HandleSetter.java   |  17 +-
 .../lombok/javac/handlers/HandleSuperBuilder.java  | 312 +++++++++------------
 .../javac/handlers/JavacSingularsRecipes.java      |  43 +--
 .../handlers/singulars/JavacGuavaSingularizer.java |  13 +-
 .../JavacJavaUtilListSetSingularizer.java          |  15 +-
 .../singulars/JavacJavaUtilMapSingularizer.java    |  15 +-
 6 files changed, 190 insertions(+), 225 deletions(-)

(limited to 'src/core/lombok/javac')

diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java
index 50967121..be3337db 100644
--- a/src/core/lombok/javac/handlers/HandleSetter.java
+++ b/src/core/lombok/javac/handlers/HandleSetter.java
@@ -210,12 +210,17 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> {
 	}
 	
 	public static JCMethodDecl createSetter(long access, boolean deprecate, JavacNode field, JavacTreeMaker treeMaker, String setterName, Name booleanFieldToSet, boolean shouldReturnThis, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) {
-		JCExpression returnType = cloneSelfType(field);
-		JCReturn returnStatement = treeMaker.Return(treeMaker.Ident(field.toName("this")));
+		JCExpression returnType = null;
+		JCReturn returnStatement = null;
+		if (shouldReturnThis) {
+			returnType = cloneSelfType(field);
+			returnStatement = treeMaker.Return(treeMaker.Ident(field.toName("this")));
+		}
+		
 		return createSetter(access, deprecate, field, treeMaker, setterName, booleanFieldToSet, returnType, returnStatement, source, onMethod, onParam);
 	}
-
-	public static JCMethodDecl createSetter(long access, boolean deprecate, JavacNode field, JavacTreeMaker treeMaker, String setterName, Name booleanFieldToSet, JCExpression methodType, JCReturn returnStatement, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) {
+	
+	public static JCMethodDecl createSetter(long access, boolean deprecate, JavacNode field, JavacTreeMaker treeMaker, String setterName, Name booleanFieldToSet, JCExpression methodType, JCStatement returnStatement, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) {
 		if (setterName == null) return null;
 		
 		JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
@@ -252,9 +257,7 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> {
 			returnStatement = null;
 		}
 		
-		if (returnStatement != null) {
-			statements.append(returnStatement);
-		}
+		if (returnStatement != null) statements.append(returnStatement);
 		
 		JCBlock methodBody = treeMaker.Block(0, statements.toList());
 		List<JCTypeParameter> methodGenericParams = List.nil();
diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
index 1835bd48..1707fb0e 100644
--- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
@@ -26,7 +26,6 @@ import static lombok.javac.Javac.*;
 import static lombok.javac.handlers.JavacHandlerUtil.*;
 
 import java.util.ArrayList;
-import java.util.function.Supplier;
 
 import org.mangosdk.spi.ProviderFor;
 
@@ -43,7 +42,6 @@ import com.sun.tools.javac.tree.JCTree.JCIf;
 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
 import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
 import com.sun.tools.javac.tree.JCTree.JCModifiers;
-import com.sun.tools.javac.tree.JCTree.JCReturn;
 import com.sun.tools.javac.tree.JCTree.JCStatement;
 import com.sun.tools.javac.tree.JCTree.JCTypeApply;
 import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
@@ -70,15 +68,16 @@ import lombok.javac.JavacNode;
 import lombok.javac.JavacTreeMaker;
 import lombok.javac.handlers.JavacHandlerUtil.FieldAccess;
 import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult;
+import lombok.javac.handlers.JavacSingularsRecipes.ExpressionMaker;
+import lombok.javac.handlers.JavacSingularsRecipes.StatementMaker;
 import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
 import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
 
 @ProviderFor(JavacAnnotationHandler.class)
 @HandlerPriority(-1024) //-2^10; to ensure we've picked up @FieldDefault's changes (-2048) but @Value hasn't removed itself yet (-512), so that we can error on presence of it on the builder classes.
 public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
-
 	private static final String SELF_METHOD = "self";
-
+	
 	private static class BuilderFieldData {
 		JCExpression type;
 		Name rawName;
@@ -88,49 +87,41 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 		ObtainVia obtainVia;
 		JavacNode obtainViaNode;
 		JavacNode originalFieldNode;
-
+		
 		java.util.List<JavacNode> createdFields = new ArrayList<JavacNode>();
 	}
-
+	
 	@Override
 	public void handle(AnnotationValues<SuperBuilder> annotation, JCAnnotation ast, JavacNode annotationNode) {
 		handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.SUPERBUILDER_FLAG_USAGE, "@SuperBuilder");
 		
 		SuperBuilder superbuilderAnnotation = annotation.getInstance();
 		deleteAnnotationIfNeccessary(annotationNode, SuperBuilder.class);
-
+		
 		String builderMethodName = superbuilderAnnotation.builderMethodName();
 		String buildMethodName = superbuilderAnnotation.buildMethodName();
-
-		if (builderMethodName == null) {
-			builderMethodName = "builder";
-		}
-		if (buildMethodName == null) {
-			buildMethodName = "build";
-		}
-
-		if (!checkName("builderMethodName", builderMethodName, annotationNode)) {
-			return;
-		}
-		if (!checkName("buildMethodName", buildMethodName, annotationNode)) {
-			return;
-		}
-
+		
+		if (builderMethodName == null) builderMethodName = "builder";
+		if (buildMethodName == null) buildMethodName = "build";
+		
+		if (!checkName("builderMethodName", builderMethodName, annotationNode)) return;
+		if (!checkName("buildMethodName", buildMethodName, annotationNode)) return;
+		
 		JavacNode tdParent = annotationNode.up();
-
+		
 		java.util.List<BuilderFieldData> builderFields = new ArrayList<BuilderFieldData>();
 		JCExpression returnType;
 		List<JCTypeParameter> typeParams = List.nil();
 		List<JCExpression> thrownExceptions = List.nil();
 		List<JCExpression> superclassTypeParams = List.nil();
-
+		
 		boolean addCleaning = false;
-
+		
 		if (!(tdParent.get() instanceof JCClassDecl)) {
 			annotationNode.addError("@SuperBuilder is only supported on types.");
 			return;
 		}
-
+		
 		// Gather all fields of the class that should be set by the builder.
 		JCClassDecl td = (JCClassDecl) tdParent.get();
 		ListBuffer<JavacNode> allFields = new ListBuffer<JavacNode>();
@@ -145,24 +136,22 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 			bfd.type = fd.vartype;
 			bfd.singularData = getSingularData(fieldNode);
 			bfd.originalFieldNode = fieldNode;
-
+			
 			if (bfd.singularData != null && isDefault != null) {
 				isDefault.addError("@Builder.Default and @Singular cannot be mixed.");
 				isDefault = null;
 			}
-
+			
 			if (fd.init == null && isDefault != null) {
 				isDefault.addWarning("@Builder.Default requires an initializing expression (' = something;').");
 				isDefault = null;
 			}
-
+			
 			if (fd.init != null && isDefault == null) {
-				if (isFinal) {
-					continue;
-				}
+				if (isFinal) continue;
 				fieldNode.addWarning("@SuperBuilder will ignore the initializing expression entirely. If you want the initializing expression to serve as default, add @Builder.Default. If it is not supposed to be settable during building, make the field final.");
 			}
-
+			
 			if (isDefault != null) {
 				bfd.nameOfSetFlag = tdParent.toName(bfd.name + "$set");
 				// The @Builder annotation removes the initializing expression on the field and moves
@@ -179,7 +168,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 			builderFields.add(bfd);
 			allFields.append(fieldNode);
 		}
-
+		
 		// Set the names of the builder classes.
 		String builderClassName = td.name.toString() + "Builder";
 		String builderImplClassName = builderClassName + "Impl";
@@ -187,14 +176,14 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 		JCExpression superclassBuilderClassExpression = null;
 		if (extendsClause instanceof JCTypeApply) {
 			// Remember the type arguments, because we need them for the extends clause of our abstract builder class.
-			superclassTypeParams = ((JCTypeApply)extendsClause).getTypeArguments();
+			superclassTypeParams = ((JCTypeApply) extendsClause).getTypeArguments();
 			// A class name with a generics type, e.g., "Superclass<A>".
-			extendsClause = ((JCTypeApply)extendsClause).getType();
+			extendsClause = ((JCTypeApply) extendsClause).getType();
 		}
 		if (extendsClause instanceof JCFieldAccess) {
 			Name superclassClassName = ((JCFieldAccess)extendsClause).getIdentifier();
 			String superclassBuilderClassName = superclassClassName + "Builder";
-			superclassBuilderClassExpression = tdParent.getTreeMaker().Select((JCFieldAccess)extendsClause,
+			superclassBuilderClassExpression = tdParent.getTreeMaker().Select((JCFieldAccess) extendsClause,
 					tdParent.toName(superclassBuilderClassName));
 		} else if (extendsClause != null) {
 			String superclassBuilderClassName = extendsClause.toString() + "Builder";
@@ -202,24 +191,22 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 		}
 		// If there is no superclass, superclassBuilderClassExpression is still == null at this point.
 		// You can use it to check whether to inherit or not.
-
+		
 		returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams);
 		typeParams = td.typarams;
-
+		
 		// <C, B> are the generics for our builder.
 		String classGenericName = "C";
 		String builderGenericName = "B";
 		// If these generics' names collide with any generics on the annotated class, modify them.
 		// For instance, if there are generics <B, B2, C> on the annotated class, use "C2" and "B3" for our builder.
 		java.util.List<String> typeParamStrings = new ArrayList<String>();
-		for (JCTypeParameter typeParam : typeParams) {
-			typeParamStrings.add(typeParam.getName().toString());
-		}
+		for (JCTypeParameter typeParam : typeParams) typeParamStrings.add(typeParam.getName().toString());
 		classGenericName = generateNonclashingNameFor(classGenericName, typeParamStrings);
 		builderGenericName = generateNonclashingNameFor(builderGenericName, typeParamStrings);
-
+		
 		thrownExceptions = List.nil();
-
+		
 		// Check validity of @ObtainVia fields, and add check if adding cleaning for @Singular is necessary.
 		for (BuilderFieldData bfd : builderFields) {
 			if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
@@ -239,7 +226,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 				}
 			}
 		}
-
+		
 		// Create the abstract builder class.
 		JavacNode builderType = findInnerClass(tdParent, builderClassName);
 		if (builderType == null) {
@@ -249,7 +236,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 			annotationNode.addError("@SuperBuilder does not support customized builders. Use @Builder instead.");
 			return;
 		}
-
+		
 		// Generate the fields in the abstract builder class that hold the values for the instance.
 		generateBuilderFields(builderType, builderFields, ast);
 		if (addCleaning) {
@@ -257,37 +244,32 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 			JCVariableDecl uncleanField = maker.VarDef(maker.Modifiers(Flags.PRIVATE), builderType.toName("$lombokUnclean"), maker.TypeIdent(CTC_BOOLEAN), null);
 			injectFieldAndMarkGenerated(builderType, uncleanField);
 		}
-
+		
 		// Generate abstract self() and build() methods in the abstract builder.
 		injectMethod(builderType, generateAbstractSelfMethod(tdParent, superclassBuilderClassExpression != null, builderGenericName));
 		injectMethod(builderType, generateAbstractBuildMethod(tdParent, buildMethodName, superclassBuilderClassExpression != null, classGenericName));
-
+		
 		// Create the setter methods in the abstract builder.
 		for (BuilderFieldData bfd : builderFields) {
 			generateSetterMethodsForBuilder(builderType, bfd, annotationNode, builderGenericName);
 		}
-
+		
 		// Create the toString() method for the abstract builder.
 		java.util.List<JavacNode> fieldNodes = new ArrayList<JavacNode>();
-		for (BuilderFieldData bfd : builderFields) {
-			fieldNodes.addAll(bfd.createdFields);
-		}
+		for (BuilderFieldData bfd : builderFields) fieldNodes.addAll(bfd.createdFields);
+		
 		// Let toString() call super.toString() if there is a superclass, so that it also shows fields from the superclass' builder.
 		JCMethodDecl toStringMethod = HandleToString.createToString(builderType, fieldNodes, true, superclassBuilderClassExpression != null, FieldAccess.ALWAYS_FIELD, ast);
-		if (toStringMethod != null) {
-			injectMethod(builderType, toStringMethod);
-		}
-
+		if (toStringMethod != null) injectMethod(builderType, toStringMethod);
+		
 		// If clean methods are requested, add them now.
-		if (addCleaning) {
-			injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
-		}
+		if (addCleaning) injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
 		
 		recursiveSetGeneratedBy(builderType.get(), ast, annotationNode.getContext());
-
+		
 		if ((td.mods.flags & Flags.ABSTRACT) == 0) {
 			// Only non-abstract classes get the Builder implementation.
-
+			
 			// Create the builder implementation class.
 			JavacNode builderImplType = findInnerClass(tdParent, builderImplClassName);
 			if (builderImplType == null) {
@@ -296,48 +278,45 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 				annotationNode.addError("@SuperBuilder does not support customized builders. Use @Builder instead.");
 				return;
 			}
-
+			
 			// Create a simple constructor for the BuilderImpl class.
 			JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PRIVATE, List.<JCAnnotation>nil(), builderImplType, List.<JavacNode>nil(), false, annotationNode);
-			if (cd != null) {
-				injectMethod(builderImplType, cd);
-			}
-
+			if (cd != null) injectMethod(builderImplType, cd);
+			
 			// Create the self() and build() methods in the BuilderImpl.
 			injectMethod(builderImplType, generateSelfMethod(builderImplType));
 			injectMethod(builderImplType, generateBuildMethod(buildMethodName, returnType, builderImplType, thrownExceptions));
-
+			
 			recursiveSetGeneratedBy(builderImplType.get(), ast, annotationNode.getContext());
 		}
-
+		
 		// Generate a constructor in the annotated class that takes a builder as argument.
 		generateBuilderBasedConstructor(tdParent, typeParams, builderFields, annotationNode, builderClassName,
 				superclassBuilderClassExpression != null);
-
+		
 		if ((td.mods.flags & Flags.ABSTRACT) == 0) {
 			// Only non-abstract classes get the Builder implementation and the builder() method.
-
+			
 			// Add the builder() method to the annotated class.
 			// Allow users to specify their own builder() methods, e.g., to provide default values.
 			if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
 				JCMethodDecl builderMethod = generateBuilderMethod(builderMethodName, builderClassName, builderImplClassName, annotationNode, tdParent, typeParams);
 				recursiveSetGeneratedBy(builderMethod, ast, annotationNode.getContext());
-				if (builderMethod != null) {
-					injectMethod(tdParent, builderMethod);
-				}
+				if (builderMethod != null) injectMethod(tdParent, builderMethod);
 			}
 		}
 	}
-
+	
 	/**
 	 * Creates and returns the abstract builder class and injects it into the annotated class.
 	 */
 	private JavacNode generateBuilderAbstractClass(JavacNode source, JavacNode tdParent, String builderClass,
 			JCExpression superclassBuilderClassExpression, List<JCTypeParameter> typeParams,
 			List<JCExpression> superclassTypeParams, JCAnnotation ast, String classGenericName, String builderGenericName) {
+		
 		JavacTreeMaker maker = tdParent.getTreeMaker();
 		JCModifiers mods = maker.Modifiers(Flags.STATIC | Flags.ABSTRACT | Flags.PUBLIC);
-
+		
 		// Keep any type params of the annotated class.
 		ListBuffer<JCTypeParameter> allTypeParams = new ListBuffer<JCTypeParameter>();
 		allTypeParams.addAll(copyTypeParams(source, typeParams));
@@ -356,7 +335,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 		typeParamsForBuilder.add(maker.Ident(tdParent.toName(builderGenericName)));
 		JCTypeApply typeApply = maker.TypeApply(maker.Ident(builderClassName), typeParamsForBuilder.toList());
 		allTypeParams.add(maker.TypeParameter(tdParent.toName(builderGenericName), List.<JCExpression>of(typeApply)));
-
+		
 		JCExpression extending = null;
 		if (superclassBuilderClassExpression != null) {
 			// If the annotated class extends another class, we want this builder to extend the builder of the superclass.
@@ -367,18 +346,18 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 			typeParamsForBuilder.add(maker.Ident(tdParent.toName(builderGenericName)));
 			extending = maker.TypeApply(superclassBuilderClassExpression, typeParamsForBuilder.toList());
 		}
-
+		
 		JCClassDecl builder = maker.ClassDef(mods, builderClassName, allTypeParams.toList(), extending, List.<JCExpression>nil(), List.<JCTree>nil());
 		return injectType(tdParent, builder);
 	}
-
+	
 	/**
 	 * Creates and returns the concrete builder implementation class and injects it into the annotated class.
 	 */
 	private JavacNode generateBuilderImplClass(JavacNode source, JavacNode tdParent, String builderImplClass, String builderAbstractClass, List<JCTypeParameter> typeParams, JCAnnotation ast) {
 		JavacTreeMaker maker = tdParent.getTreeMaker();
 		JCModifiers mods = maker.Modifiers(Flags.STATIC | Flags.PRIVATE | Flags.FINAL);
-
+		
 		// Extend the abstract builder.
 		JCExpression extending = maker.Ident(tdParent.toName(builderAbstractClass));
 		// Add any type params of the annotated class.
@@ -400,7 +379,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 		typeParamsForBuilder.add(annotatedClass);
 		typeParamsForBuilder.add(builderImplClassExpression);
 		extending = maker.TypeApply(extending, typeParamsForBuilder.toList());
-
+		
 		JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderImplClass), copyTypeParams(source, typeParams), extending, List.<JCExpression>nil(), List.<JCTree>nil());
 		return injectType(tdParent, builder);
 	}
@@ -422,22 +401,20 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 	 */
 	private void generateBuilderBasedConstructor(JavacNode typeNode, List<JCTypeParameter> typeParams, java.util.List<BuilderFieldData> builderFields, JavacNode source, String builderClassName, boolean callBuilderBasedSuperConstructor) {
 		JavacTreeMaker maker = typeNode.getTreeMaker();
-
+		
 		AccessLevel level = AccessLevel.PROTECTED;
-
+		
 		ListBuffer<JCStatement> nullChecks = new ListBuffer<JCStatement>();
 		ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
-
+		
 		Name builderVariableName = typeNode.toName("b");
 		for (BuilderFieldData bfd : builderFields) {
 			List<JCAnnotation> nonNulls = findAnnotations(bfd.originalFieldNode, NON_NULL_PATTERN);
 			if (!nonNulls.isEmpty()) {
 				JCStatement nullCheck = generateNullCheck(maker, bfd.originalFieldNode, source);
-				if (nullCheck != null) {
-					nullChecks.append(nullCheck);
-				}
+				if (nullCheck != null) nullChecks.append(nullCheck);
 			}
-
+			
 			JCExpression rhs;
 			if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
 				bfd.singularData.getSingularizer().appendBuildCode(bfd.singularData, bfd.originalFieldNode, bfd.type, statements, bfd.name, "b");
@@ -446,7 +423,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 				rhs = maker.Select(maker.Ident(builderVariableName), bfd.rawName);
 			}
 			JCFieldAccess thisX = maker.Select(maker.Ident(typeNode.toName("this")), bfd.rawName);
-
+			
 			JCStatement assign = maker.Exec(maker.Assign(thisX, rhs));
 			
 			// In case of @Builder.Default, only set the value if it really was set in the builder.
@@ -458,9 +435,9 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 				statements.append(assign);
 			}
 		}
-
+		
 		JCModifiers mods = maker.Modifiers(toJavacModifier(level), List.<JCAnnotation>nil());
-
+		
 		// Create a constructor that has just the builder as parameter.
 		ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
 		long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext());
@@ -475,7 +452,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 		JCTypeApply paramType = maker.TypeApply(maker.Ident(builderClassname), typeParamsForBuilderParameter.toList());
 		JCVariableDecl param = maker.VarDef(maker.Modifiers(flags), builderVariableName, paramType, null);
 		params.append(param);
-
+		
 		if (callBuilderBasedSuperConstructor) {
 			// The first statement must be the call to the super constructor.
 			JCMethodInvocation callToSuperConstructor = maker.Apply(List.<JCExpression>nil(),
@@ -483,29 +460,27 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 					List.<JCExpression>of(maker.Ident(builderVariableName)));
 			statements.prepend(maker.Exec(callToSuperConstructor));
 		}
-
+		
 		JCMethodDecl constr = recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("<init>"),
 			null, List.<JCTypeParameter>nil(), params.toList(), List.<JCExpression>nil(),
 			maker.Block(0L, nullChecks.appendList(statements).toList()), null), source.get(), typeNode.getContext());
-
+		
 		injectMethod(typeNode, constr, null, Javac.createVoidType(typeNode.getSymbolTable(), CTC_VOID));
 	}
-
+	
 	private JCMethodDecl generateBuilderMethod(String builderMethodName, String builderClassName, String builderImplClassName, JavacNode source, JavacNode type, List<JCTypeParameter> typeParams) {
 		JavacTreeMaker maker = type.getTreeMaker();
-
+		
 		ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
-		for (JCTypeParameter typeParam : typeParams) {
-			typeArgs.append(maker.Ident(typeParam.name));
-		}
-
+		for (JCTypeParameter typeParam : typeParams) typeArgs.append(maker.Ident(typeParam.name));
+		
 		JCExpression call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type.toName(builderImplClassName), typeParams), List.<JCExpression>nil(), null);
 		JCStatement statement = maker.Return(call);
-
+		
 		JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
 		int modifiers = Flags.PUBLIC;
 		modifiers |= Flags.STATIC;
-
+		
 		// Add any type params of the annotated class to the return type.
 		ListBuffer<JCExpression> typeParameterNames = new ListBuffer<JCExpression>();
 		typeParameterNames.addAll(typeParameterNames(maker, typeParams));
@@ -514,10 +489,10 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 		typeParameterNames.add(wildcard);
 		typeParameterNames.add(wildcard);
 		JCTypeApply returnType = maker.TypeApply(maker.Ident(type.toName(builderClassName)), typeParameterNames.toList());
-
+		
 		return maker.MethodDef(maker.Modifiers(modifiers), type.toName(builderMethodName), returnType, copyTypeParams(source, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
 	}
-
+	
 	private JCMethodDecl generateAbstractSelfMethod(JavacNode type, boolean override, String builderGenericName) {
 		JavacTreeMaker maker = type.getTreeMaker();
 		List<JCAnnotation> annotations = List.nil();
@@ -528,24 +503,24 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 		JCModifiers modifiers = maker.Modifiers(Flags.PROTECTED | Flags.ABSTRACT, annotations);
 		Name name = type.toName(SELF_METHOD);
 		JCExpression returnType = maker.Ident(type.toName(builderGenericName));
-
+		
 		return maker.MethodDef(modifiers, name, returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
 	}
-
+	
 	private JCMethodDecl generateSelfMethod(JavacNode builderImplType) {
 		JavacTreeMaker maker = builderImplType.getTreeMaker();
-
+		
 		JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(builderImplType, "Override"), List.<JCExpression>nil());
 		JCModifiers modifiers = maker.Modifiers(Flags.PROTECTED, List.of(overrideAnnotation));
 		Name name = builderImplType.toName(SELF_METHOD);
 		JCExpression returnType = maker.Ident(builderImplType.toName(builderImplType.getName()));
-
+		
 		JCStatement statement = maker.Return(maker.Ident(builderImplType.toName("this")));
 		JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
-
+		
 		return maker.MethodDef(modifiers, name, returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
 	}
-
+	
 	private JCMethodDecl generateAbstractBuildMethod(JavacNode type, String methodName, boolean override, String classGenericName) {
 		JavacTreeMaker maker = type.getTreeMaker();
 		List<JCAnnotation> annotations = List.nil();
@@ -556,53 +531,51 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 		JCModifiers modifiers = maker.Modifiers(Flags.PUBLIC | Flags.ABSTRACT, annotations);
 		Name name = type.toName(methodName);
 		JCExpression returnType = maker.Ident(type.toName(classGenericName));
-
+		
 		return maker.MethodDef(modifiers, name, returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
 	}
 
 	private JCMethodDecl generateBuildMethod(String buildName, JCExpression returnType, JavacNode type, List<JCExpression> thrownExceptions) {
 		JavacTreeMaker maker = type.getTreeMaker();
-
+		
 		JCExpression call;
 		ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
-
+		
 		// Use a constructor that only has this builder as parameter.
 		List<JCExpression> builderArg = List.<JCExpression>of(maker.Ident(type.toName("this")));
 		call = maker.NewClass(null, List.<JCExpression>nil(), returnType, builderArg, null);
 		statements.append(maker.Return(call));
-
+		
 		JCBlock body = maker.Block(0, statements.toList());
-
+		
 		JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(type, "Override"), List.<JCExpression>nil());
 		JCModifiers modifiers = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation));
-
+		
 		return maker.MethodDef(modifiers, type.toName(buildName), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null);
 	}
-
+	
 	private JCMethodDecl generateCleanMethod(java.util.List<BuilderFieldData> builderFields, JavacNode type, JCTree source) {
 		JavacTreeMaker maker = type.getTreeMaker();
 		ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
-
+		
 		for (BuilderFieldData bfd : builderFields) {
 			if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
 				bfd.singularData.getSingularizer().appendCleaningCode(bfd.singularData, type, source, statements);
 			}
 		}
-
+		
 		statements.append(maker.Exec(maker.Assign(maker.Select(maker.Ident(type.toName("this")), type.toName("$lombokUnclean")), maker.Literal(CTC_BOOLEAN, 0))));
 		JCBlock body = maker.Block(0, statements.toList());
 		return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName("$lombokClean"), maker.Type(Javac.createVoidType(type.getSymbolTable(), CTC_VOID)), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
 	}
-
+	
 	private void generateBuilderFields(JavacNode builderType, java.util.List<BuilderFieldData> builderFields, JCTree source) {
 		int len = builderFields.size();
 		java.util.List<JavacNode> existing = new ArrayList<JavacNode>();
 		for (JavacNode child : builderType.down()) {
-			if (child.getKind() == Kind.FIELD) {
-				existing.add(child);
-			}
+			if (child.getKind() == Kind.FIELD) existing.add(child);
 		}
-
+		
 		for (int i = len - 1; i >= 0; i--) {
 			BuilderFieldData bfd = builderFields.get(i);
 			if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
@@ -611,12 +584,8 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 				JavacNode field = null, setFlag = null;
 				for (JavacNode exists : existing) {
 					Name n = ((JCVariableDecl) exists.get()).name;
-					if (n.equals(bfd.name)) {
-						field = exists;
-					}
-					if (n.equals(bfd.nameOfSetFlag)) {
-						setFlag = exists;
-					}
+					if (n.equals(bfd.name)) field = exists;
+					if (n.equals(bfd.nameOfSetFlag)) setFlag = exists;
 				}
 				JavacTreeMaker maker = builderType.getTreeMaker();
 				if (field == null) {
@@ -633,52 +602,47 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 			}
 		}
 	}
-
+	
 	private void generateSetterMethodsForBuilder(final JavacNode builderType, BuilderFieldData fieldNode, JavacNode source, final String builderGenericName) {
 		boolean deprecate = isFieldDeprecated(fieldNode.originalFieldNode);
 		final JavacTreeMaker maker = builderType.getTreeMaker();
-		// TODO: Make these lambdas when switching to a source level >= 1.8.
-		Supplier<JCExpression> returnType = new Supplier<JCExpression>() { @Override public JCExpression get() {
+		ExpressionMaker returnTypeMaker = new ExpressionMaker() { @Override public JCExpression make() {
 			return maker.Ident(builderType.toName(builderGenericName));
 		}};
-		Supplier<? extends JCReturn> returnStatement = new Supplier<JCReturn>() { @Override public JCReturn get() {
+		
+		StatementMaker returnStatementMaker = new StatementMaker() { @Override public JCStatement make() {
 			return maker.Return(maker.Apply(List.<JCExpression>nil(), maker.Ident(builderType.toName(SELF_METHOD)), List.<JCExpression>nil()));
 		}};
+		
 		if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) {
-			generateSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, true, true, returnType.get(), returnStatement.get());
+			generateSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, true, true, returnTypeMaker.make(), returnStatementMaker.make());
 		} else {
-			fieldNode.singularData.getSingularizer().generateMethods(fieldNode.singularData, deprecate, builderType, source.get(), true, returnType, returnStatement);
+			fieldNode.singularData.getSingularizer().generateMethods(fieldNode.singularData, deprecate, builderType, source.get(), true, returnTypeMaker, returnStatementMaker);
 		}
 	}
-
-	private void generateSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, JCExpression returnType, JCReturn returnStatement) {
+	
+	private void generateSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, JCExpression returnType, JCStatement returnStatement) {
 		Name fieldName = ((JCVariableDecl) fieldNode.get()).name;
-
+		
 		for (JavacNode child : builderType.down()) {
-			if (child.getKind() != Kind.METHOD) {
-				continue;
-			}
+			if (child.getKind() != Kind.METHOD) continue;
 			JCMethodDecl methodDecl = (JCMethodDecl) child.get();
 			Name existingName = methodDecl.name;
-			if (existingName.equals(fieldName) && !isTolerate(fieldNode, methodDecl)) {
-				return;
-			}
+			if (existingName.equals(fieldName) && !isTolerate(fieldNode, methodDecl)) return;
 		}
-
+		
 		String setterName = fluent ? fieldNode.getName() : HandlerUtil.buildAccessorName("set", fieldNode.getName());
-
+		
 		JavacTreeMaker maker = fieldNode.getTreeMaker();
-
+		
 		JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, nameOfSetFlag, returnType, returnStatement, source, List.<JCAnnotation>nil(), List.<JCAnnotation>nil());
-
+		
 		injectMethod(builderType, newMethod);
 	}
-
+	
 	private void addObtainVia(BuilderFieldData bfd, JavacNode node) {
 		for (JavacNode child : node.down()) {
-			if (!annotationTypeMatches(ObtainVia.class, child)) {
-				continue;
-			}
+			if (!annotationTypeMatches(ObtainVia.class, child)) continue;
 			AnnotationValues<ObtainVia> ann = createAnnotation(ObtainVia.class, child);
 			bfd.obtainVia = ann.getInstance();
 			bfd.obtainViaNode = child;
@@ -686,7 +650,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 			return;
 		}
 	}
-
+	
 	/**
 	 * Returns the explicitly requested singular annotation on this node (field
 	 * or parameter), or null if there's no {@code @Singular} annotation on it.
@@ -695,9 +659,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 	 */
 	private SingularData getSingularData(JavacNode node) {
 		for (JavacNode child : node.down()) {
-			if (!annotationTypeMatches(Singular.class, child)) {
-				continue;
-			}
+			if (!annotationTypeMatches(Singular.class, child)) continue;
 			Name pluralName = node.getKind() == Kind.FIELD ? removePrefixFromField(node) : ((JCVariableDecl) node.get()).name;
 			AnnotationValues<Singular> ann = createAnnotation(Singular.class, child);
 			deleteAnnotationIfNeccessary(child, Singular.class);
@@ -715,58 +677,48 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
 				}
 			}
 			Name singularName = node.toName(explicitSingular);
-
+			
 			JCExpression type = null;
-			if (node.get() instanceof JCVariableDecl) {
-				type = ((JCVariableDecl) node.get()).vartype;
-			}
-
+			if (node.get() instanceof JCVariableDecl) type = ((JCVariableDecl) node.get()).vartype;
+			
 			String name = null;
 			List<JCExpression> typeArgs = List.nil();
 			if (type instanceof JCTypeApply) {
 				typeArgs = ((JCTypeApply) type).arguments;
 				type = ((JCTypeApply) type).clazz;
 			}
-
+			
 			name = type.toString();
-
+			
 			String targetFqn = JavacSingularsRecipes.get().toQualified(name);
 			JavacSingularizer singularizer = JavacSingularsRecipes.get().getSingularizer(targetFqn);
 			if (singularizer == null) {
 				node.addError("Lombok does not know how to create the singular-form builder methods for type '" + name + "'; they won't be generated.");
 				return null;
 			}
-
+			
 			return new SingularData(child, singularName, pluralName, typeArgs, targetFqn, singularizer);
 		}
-
+		
 		return null;
 	}
-
+	
 	private String generateNonclashingNameFor(String classGenericName, java.util.List<String> typeParamStrings) {
-		if (!typeParamStrings.contains(classGenericName)) {
-			return classGenericName;
-		}
+		if (!typeParamStrings.contains(classGenericName)) return classGenericName;
 		int counter = 2;
-		while (typeParamStrings.contains(classGenericName + counter)) {
-			counter++;
-		}
+		while (typeParamStrings.contains(classGenericName + counter)) counter++;
 		return classGenericName + counter;
 	}
-
+	
 	private JavacNode findInnerClass(JavacNode parent, String name) {
 		for (JavacNode child : parent.down()) {
-			if (child.getKind() != Kind.TYPE) {
-				continue;
-			}
+			if (child.getKind() != Kind.TYPE) continue;
 			JCClassDecl td = (JCClassDecl) child.get();
-			if (td.name.contentEquals(name)) {
-				return child;
-			}
+			if (td.name.contentEquals(name)) return child;
 		}
 		return null;
 	}
-
+	
 	private ListBuffer<JCExpression> getTypeParamExpressions(List<? extends JCTree> typeParams, JavacTreeMaker maker) {
 		ListBuffer<JCExpression> typeParamsForBuilderParameter = new ListBuffer<JCExpression>();
 		for (JCTree typeParam : typeParams) {
diff --git a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
index 67862355..ab8c3a42 100644
--- a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
+++ b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2017 The Project Lombok Authors.
+ * Copyright (C) 2015-2018 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
@@ -29,7 +29,6 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.function.Supplier;
 
 import lombok.core.LombokImmutableList;
 import lombok.core.SpiLoadUtil;
@@ -54,6 +53,14 @@ import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Name;
 
 public class JavacSingularsRecipes {
+	public interface ExpressionMaker {
+		JCExpression make();
+	}
+	
+	public interface StatementMaker {
+		JCStatement make();
+	}
+	
 	private static final JavacSingularsRecipes INSTANCE = new JavacSingularsRecipes();
 	private final Map<String, JavacSingularizer> singularizers = new HashMap<String, JavacSingularizer>();
 	private final TypeLibrary singularizableTypes = new TypeLibrary();
@@ -197,32 +204,32 @@ public class JavacSingularsRecipes {
 		public abstract java.util.List<JavacNode> generateFields(SingularData data, JavacNode builderType, JCTree source);
 		
 		/**
-		 * Generates the singular, plural, and clear methods for the given
-		 * {@link SingularData}.<br>
-		 * Uses the given <code>builderType</code> as return type if
-		 * <code>chain == true</code>, <code>void</code> otherwise. If you need more
-		 * control over the return type and value, use
-		 * {@link #generateMethods(SingularData, boolean, JavacNode, JCTree, boolean, JCExpression, JCStatement)}.
+		 * Generates the singular, plural, and clear methods for the given {@link SingularData}.
+		 * Uses the given {@code builderType} as return type if {@code chain == true}, {@code void} otherwise.
+		 * If you need more control over the return type and value, use
+		 * {@link #generateMethods(SingularData, boolean, JavacNode, JCTree, boolean, ExpressionMaker, StatementMaker)}.
 		 */
 		public void generateMethods(SingularData data, boolean deprecate, final JavacNode builderType, JCTree source, boolean fluent, final boolean chain) {
 			final JavacTreeMaker maker = builderType.getTreeMaker();
-			// TODO: Make these lambdas when switching to a source level >= 1.8.
-			Supplier<JCExpression> returnType = new Supplier<JCExpression>() { @Override public JCExpression get() {
+			
+			ExpressionMaker returnTypeMaker = new ExpressionMaker() { @Override public JCExpression make() {
 				return chain ? 
-						cloneSelfType(builderType) : 
-						maker.Type(createVoidType(builderType.getSymbolTable(), CTC_VOID));
+					cloneSelfType(builderType) : 
+					maker.Type(createVoidType(builderType.getSymbolTable(), CTC_VOID));
 			}};
-			Supplier<JCStatement> returnStatement = new Supplier<JCStatement>() { @Override public JCStatement get() {
+			
+			StatementMaker returnStatementMaker = new StatementMaker() { @Override public JCStatement make() {
 				return chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
 			}};
-			generateMethods(data, deprecate, builderType, source, fluent, returnType, returnStatement);
+			
+			generateMethods(data, deprecate, builderType, source, fluent, returnTypeMaker, returnStatementMaker);
 		}
+		
 		/**
-		 * Generates the singular, plural, and clear methods for the given
-		 * {@link SingularData}.<br>
-		 * Uses the given <code>returnType</code> and <code>returnStatement</code> for the generated methods. 
+		 * Generates the singular, plural, and clear methods for the given {@link SingularData}.
+		 * Uses the given {@code returnTypeMaker} and {@code returnStatementMaker} for the generated methods.
 		 */
-		public abstract void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, Supplier<JCExpression> returnType, Supplier<? extends JCStatement> returnStatement);
+		public abstract void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker);
 		
 		public abstract void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName, String builderVariable);
 		
diff --git a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
index ecaf5c87..ffaf6674 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2017 The Project Lombok Authors.
+ * Copyright (C) 2015-2018 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
@@ -25,7 +25,6 @@ import static lombok.javac.Javac.*;
 import static lombok.javac.handlers.JavacHandlerUtil.*;
 
 import java.util.Collections;
-import java.util.function.Supplier;
 
 import lombok.core.GuavaTypeMap;
 import lombok.core.LombokImmutableList;
@@ -33,8 +32,10 @@ import lombok.core.handlers.HandlerUtil;
 import lombok.javac.JavacNode;
 import lombok.javac.JavacTreeMaker;
 import lombok.javac.handlers.JavacHandlerUtil;
+import lombok.javac.handlers.JavacSingularsRecipes.ExpressionMaker;
 import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
 import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
+import lombok.javac.handlers.JavacSingularsRecipes.StatementMaker;
 
 import com.sun.tools.javac.code.Flags;
 import com.sun.tools.javac.tree.JCTree;
@@ -70,11 +71,11 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
 		return Collections.singletonList(injectFieldAndMarkGenerated(builderType, buildField));
 	}
 	
-	@Override public void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, Supplier<JCExpression> returnType, Supplier<? extends JCStatement> returnStatement) {
+	@Override public void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker) {
 		JavacTreeMaker maker = builderType.getTreeMaker();
-		generateSingularMethod(deprecate, maker, returnType.get(), returnStatement.get(), data, builderType, source, fluent);
-		generatePluralMethod(deprecate, maker, returnType.get(), returnStatement.get(), data, builderType, source, fluent);
-		generateClearMethod(deprecate, maker, returnType.get(), returnStatement.get(), data, builderType, source);
+		generateSingularMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, fluent);
+		generatePluralMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, fluent);
+		generateClearMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source);
 	}
 	
 	private void generateClearMethod(boolean deprecate, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source) {
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java
index bd0f740e..39e53ebb 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2017 The Project Lombok Authors.
+ * Copyright (C) 2015-2018 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
@@ -25,13 +25,14 @@ import static lombok.javac.Javac.*;
 import static lombok.javac.handlers.JavacHandlerUtil.*;
 
 import java.util.Collections;
-import java.util.function.Supplier;
 
 import lombok.core.handlers.HandlerUtil;
 import lombok.javac.JavacNode;
 import lombok.javac.JavacTreeMaker;
 import lombok.javac.handlers.JavacHandlerUtil;
+import lombok.javac.handlers.JavacSingularsRecipes.ExpressionMaker;
 import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
+import lombok.javac.handlers.JavacSingularsRecipes.StatementMaker;
 
 import com.sun.tools.javac.code.Flags;
 import com.sun.tools.javac.tree.JCTree;
@@ -76,16 +77,16 @@ abstract class JavacJavaUtilListSetSingularizer extends JavacJavaUtilSingularize
 		return Collections.singletonList(injectFieldAndMarkGenerated(builderType, buildField));
 	}
 	
-	@Override public void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, Supplier<JCExpression> returnType, Supplier<? extends JCStatement> returnStatement) {
+	@Override public void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker) {
 		if (useGuavaInstead(builderType)) {
-			guavaListSetSingularizer.generateMethods(data, deprecate, builderType, source, fluent, returnType, returnStatement);
+			guavaListSetSingularizer.generateMethods(data, deprecate, builderType, source, fluent, returnTypeMaker, returnStatementMaker);
 			return;
 		}
 		
 		JavacTreeMaker maker = builderType.getTreeMaker();
-		generateSingularMethod(deprecate, maker, returnType.get(), returnStatement.get(), data, builderType, source, fluent);
-		generatePluralMethod(deprecate, maker, returnType.get(), returnStatement.get(), data, builderType, source, fluent);
-		generateClearMethod(deprecate, maker, returnType.get(), returnStatement.get(), data, builderType, source);
+		generateSingularMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, fluent);
+		generatePluralMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, fluent);
+		generateClearMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source);
 	}
 	
 	private void generateClearMethod(boolean deprecate, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source) {
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java
index 1b4dd960..34350f40 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2017 The Project Lombok Authors.
+ * Copyright (C) 2015-2018 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
@@ -25,15 +25,16 @@ import static lombok.javac.Javac.*;
 import static lombok.javac.handlers.JavacHandlerUtil.*;
 
 import java.util.Arrays;
-import java.util.function.Supplier;
 
 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.ExpressionMaker;
 import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
 import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
+import lombok.javac.handlers.JavacSingularsRecipes.StatementMaker;
 
 import org.mangosdk.spi.ProviderFor;
 
@@ -101,16 +102,16 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
 		return Arrays.asList(keyFieldNode, valueFieldNode);
 	}
 	
-	@Override public void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, Supplier<JCExpression> returnType, Supplier<? extends JCStatement> returnStatement) {
+	@Override public void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker) {
 		if (useGuavaInstead(builderType)) {
-			guavaMapSingularizer.generateMethods(data, deprecate, builderType, source, fluent, returnType, returnStatement);
+			guavaMapSingularizer.generateMethods(data, deprecate, builderType, source, fluent, returnTypeMaker, returnStatementMaker);
 			return;
 		}
 		
 		JavacTreeMaker maker = builderType.getTreeMaker();
-		generateSingularMethod(deprecate, maker, returnType.get(), returnStatement.get(), data, builderType, source, fluent);
-		generatePluralMethod(deprecate, maker, returnType.get(), returnStatement.get(), data, builderType, source, fluent);
-		generateClearMethod(deprecate, maker, returnType.get(), returnStatement.get(), data, builderType, source);
+		generateSingularMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, fluent);
+		generatePluralMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, fluent);
+		generateClearMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source);
 	}
 	
 	private void generateClearMethod(boolean deprecate, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source) {
-- 
cgit