aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Rieke <it@janrieke.de>2018-04-10 20:25:19 +0200
committerJan Rieke <it@janrieke.de>2018-04-10 20:31:39 +0200
commit8acc37011f5c13d6547ca2e76fa15d89e1472dae (patch)
tree1aa2aacc6f88fb353acf0f68056a16959d558b93
parente9929b100cc88246b13a9c3e76795db6fe446d38 (diff)
downloadlombok-8acc37011f5c13d6547ca2e76fa15d89e1472dae.tar.gz
lombok-8acc37011f5c13d6547ca2e76fa15d89e1472dae.tar.bz2
lombok-8acc37011f5c13d6547ca2e76fa15d89e1472dae.zip
apply generics on builder extends clause; fixed builder name generation
-rw-r--r--src/core/lombok/javac/handlers/HandleSuperBuilder.java62
1 files changed, 36 insertions, 26 deletions
diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
index c271a262..8bf5b7a2 100644
--- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
@@ -163,7 +163,14 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
String builderClassName = td.name.toString() + "Builder";
String builderImplClassName = builderClassName + "Impl";
JCTree extendsClause = Javac.getExtendsClause(td);
- String superclassBuilderClassName= extendsClause + "Builder";
+ String superclassBuilderClassName = null;
+ if (extendsClause instanceof JCFieldAccess) {
+ // The extends clause consists of a fully-qualified name.
+ superclassBuilderClassName = ((JCFieldAccess)extendsClause).getIdentifier() + "Builder";
+ } else {
+ // A simple class name is used in the extends clause.
+ superclassBuilderClassName = extendsClause + "Builder";
+ }
boolean useInheritanceOnBuilder = extendsClause != null;
generateBuilderBasedConstructor(tdParent, builderFields, annotationNode, builderClassName, useInheritanceOnBuilder);
@@ -181,15 +188,6 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
return;
}
- // Create the builder implementation class.
- JavacNode builderImplType = findInnerClass(tdParent, builderImplClassName);
- if (builderImplType == null) {
- builderImplType = makeBuilderImplClass(annotationNode, tdParent, builderImplClassName, builderClassName, typeParams, ast);
- } else {
- annotationNode.addError("@SuperBuilder does not support customized builders. Use @Builder instead.");
- return;
- }
-
// Check that all builder fields for @Singular and @ObtainVia.
for (BuilderFieldData bfd : builderFields) {
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
@@ -210,7 +208,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
}
}
- // Generate the fields in the builder class that hold the values for the instance.
+ // Generate the fields in the abstract builder class that hold the values for the instance.
generateBuilderFields(builderType, builderFields, ast);
if (addCleaning) {
JavacTreeMaker maker = builderType.getTreeMaker();
@@ -218,11 +216,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
injectFieldAndMarkGenerated(builderType, uncleanField);
}
- // Create a simple constructor for the builder class.
- JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PRIVATE, List.<JCAnnotation>nil(), builderImplType, List.<JavacNode>nil(), false, annotationNode);
- if (cd != null) injectMethod(builderImplType, cd);
-
- // Generate abstract self() and build() methods.
+ // Generate abstract self() and build() methods in the abstract builder.
injectMethod(builderType, generateAbstractSelfMethod(tdParent));
injectMethod(builderType, generateAbstractBuildMethod(tdParent, buildMethodName));
@@ -231,10 +225,6 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
makeSetterMethodsForBuilder(builderType, bfd, annotationNode);
}
- // Create the self() and build() methods in the BuilderImpl.
- injectMethod(builderImplType, generateSelfMethod(builderImplType));
- injectMethod(builderImplType, generateBuildMethod(tdParent, buildMethodName, returnType, builderImplType, thrownExceptions, ast));
-
// Create the toString() method for the abstract builder.
if (methodExists("toString", builderType, 0) == MemberExistsResult.NOT_EXISTS) {
java.util.List<JavacNode> fieldNodes = new ArrayList<JavacNode>();
@@ -247,6 +237,23 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
if (addCleaning) injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
+ // Create the builder implementation class.
+ JavacNode builderImplType = findInnerClass(tdParent, builderImplClassName);
+ if (builderImplType == null) {
+ builderImplType = makeBuilderImplClass(annotationNode, tdParent, builderImplClassName, builderClassName, typeParams, ast);
+ } else {
+ 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);
+
+ // Create the self() and build() methods in the BuilderImpl.
+ injectMethod(builderImplType, generateSelfMethod(builderImplType));
+ injectMethod(builderImplType, generateBuildMethod(tdParent, buildMethodName, returnType, builderImplType, thrownExceptions, ast));
+
// Add the builder() method to the annotated class.
if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
JCMethodDecl md = generateBuilderMethod(builderMethodName, builderClassName, builderImplClassName, annotationNode, tdParent, typeParams);
@@ -516,12 +523,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
public JavacNode makeBuilderClass(JavacNode source, JavacNode tdParent, String builderClass, String parentBuilderClass, List<JCTypeParameter> typeParams, JCAnnotation ast) {
JavacTreeMaker maker = tdParent.getTreeMaker();
JCModifiers mods = maker.Modifiers(Flags.STATIC | Flags.ABSTRACT | Flags.PUBLIC);
-
- JCExpression extending = null;
- if (parentBuilderClass != null) {
- extending = maker.Ident(tdParent.toName(parentBuilderClass));
- }
-
+
// Keep any type params of the annotated class.
// TODO: Prevent name clashes with type params from annotated class.
ListBuffer<JCTypeParameter> allTypeParams = new ListBuffer<JCTypeParameter>();
@@ -535,6 +537,14 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
JCTypeApply typeApply = maker.TypeApply(maker.Ident(builderClassName),
List.<JCExpression>of(maker.Ident(tdParent.toName("C")), maker.Ident(tdParent.toName("B"))));
allTypeParams.add(maker.TypeParameter(tdParent.toName("B"), List.<JCExpression>of(typeApply)));
+
+ JCExpression extending = null;
+ if (parentBuilderClass != null) {
+ // If the annotated class extends another class, we want this builder to extend the builder of the superclass.
+ extending = maker.TypeApply(maker.Ident(tdParent.toName(parentBuilderClass)),
+ List.<JCExpression>of(maker.Ident(tdParent.toName("C")), maker.Ident(tdParent.toName("B"))));
+ // TODO: type params from annotated class
+ }
JCClassDecl builder = maker.ClassDef(mods, builderClassName, allTypeParams.toList(), extending, List.<JCExpression>nil(), List.<JCTree>nil());
return injectType(tdParent, builder);