diff options
-rw-r--r-- | src/core/lombok/Builder.java | 2 | ||||
-rwxr-xr-x | src/core/lombok/eclipse/handlers/HandleSuperBuilder.java | 27 | ||||
-rw-r--r-- | src/core/lombok/experimental/SuperBuilder.java | 2 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleSuperBuilder.java | 23 |
4 files changed, 43 insertions, 11 deletions
diff --git a/src/core/lombok/Builder.java b/src/core/lombok/Builder.java index ea94eb4e..c83b3670 100644 --- a/src/core/lombok/Builder.java +++ b/src/core/lombok/Builder.java @@ -120,7 +120,7 @@ public @interface Builder { @Retention(SOURCE) public @interface Default {} - /** @return Name of the method that creates a new builder instance. Default: {@code builder}. */ + /** @return Name of the method that creates a new builder instance. Default: {@code builder}. If the empty string, suppress generating the {@code builder} method. */ String builderMethodName() default "builder"; /** @return Name of the method in the builder class that creates an instance of your {@code @Builder}-annotated class. */ diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index 7b6a3c28..6f34eb30 100755 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -129,7 +129,14 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { if (builderMethodName == null) builderMethodName = "builder"; if (buildMethodName == null) buildMethodName = "build"; - if (!checkName("builderMethodName", builderMethodName, annotationNode)) return; + boolean generateBuilderMethod; + if (builderMethodName.isEmpty()) { + generateBuilderMethod = false; + } else if (!checkName("builderMethodName", builderMethodName, annotationNode)) { + return; + } else { + generateBuilderMethod = true; + } if (!checkName("buildMethodName", buildMethodName, annotationNode)) return; boolean toBuilder = superbuilderAnnotation.toBuilder(); @@ -150,6 +157,8 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { // Gather all fields of the class that should be set by the builder. List<EclipseNode> allFields = new ArrayList<EclipseNode>(); + List<EclipseNode> nonFinalNonDefaultedFields = null; + boolean valuePresent = (hasAnnotation(lombok.Value.class, tdParent) || hasAnnotation("lombok.experimental.Value", tdParent)); for (EclipseNode fieldNode : HandleConstructor.findAllFields(tdParent, true)) { FieldDeclaration fd = (FieldDeclaration) fieldNode.get(); @@ -177,10 +186,9 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { } if (fd.initialization != null && isDefault == null) { - if (isFinal) { - continue; - } - fieldNode.addWarning("@Builder 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 (isFinal) continue; + if (nonFinalNonDefaultedFields == null) nonFinalNonDefaultedFields = new ArrayList<EclipseNode>(); + nonFinalNonDefaultedFields.add(fieldNode); } if (isDefault != null) { @@ -386,10 +394,17 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { } // Add the builder() method to the annotated class. - if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) { + if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false; + if (generateBuilderMethod) { MethodDeclaration md = generateBuilderMethod(builderMethodName, builderClassName, builderImplClassName, tdParent, typeParams, ast); if (md != null) injectMethod(tdParent, md); } + + if (nonFinalNonDefaultedFields != null && generateBuilderMethod) { + for (EclipseNode fieldNode : nonFinalNonDefaultedFields) { + 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."); + } + } } private EclipseNode generateBuilderAbstractClass(EclipseNode tdParent, String builderClass, diff --git a/src/core/lombok/experimental/SuperBuilder.java b/src/core/lombok/experimental/SuperBuilder.java index be6ea304..aef76a46 100644 --- a/src/core/lombok/experimental/SuperBuilder.java +++ b/src/core/lombok/experimental/SuperBuilder.java @@ -49,7 +49,7 @@ import lombok.Singular; @Target(TYPE) @Retention(SOURCE) public @interface SuperBuilder { - /** @return Name of the method that creates a new builder instance. Default: {@code builder}. */ + /** @return Name of the method that creates a new builder instance. Default: {@code builder}. If the empty string, suppress generating the {@code builder} method. */ String builderMethodName() default "builder"; /** @return Name of the method in the builder class that creates an instance of your {@code @Builder}-annotated class. */ diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index 7ef6b658..7eb9873b 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -103,7 +103,14 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { if (builderMethodName == null) builderMethodName = "builder"; if (buildMethodName == null) buildMethodName = "build"; - if (!checkName("builderMethodName", builderMethodName, annotationNode)) return; + boolean generateBuilderMethod; + if (builderMethodName.isEmpty()) { + generateBuilderMethod = false; + } else if (!checkName("builderMethodName", builderMethodName, annotationNode)) { + return; + } else { + generateBuilderMethod = true; + } if (!checkName("buildMethodName", buildMethodName, annotationNode)) return; boolean toBuilder = superbuilderAnnotation.toBuilder(); @@ -125,6 +132,8 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { // Gather all fields of the class that should be set by the builder. JCClassDecl td = (JCClassDecl) tdParent.get(); ListBuffer<JavacNode> allFields = new ListBuffer<JavacNode>(); + ArrayList<JavacNode> nonFinalNonDefaultedFields = null; + boolean valuePresent = (hasAnnotation(lombok.Value.class, tdParent) || hasAnnotation("lombok.experimental.Value", tdParent)); for (JavacNode fieldNode : HandleConstructor.findAllFields(tdParent, true)) { JCVariableDecl fd = (JCVariableDecl) fieldNode.get(); @@ -150,7 +159,8 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { if (fd.init != null && isDefault == null) { 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 (nonFinalNonDefaultedFields == null) nonFinalNonDefaultedFields = new ArrayList<JavacNode>(); + nonFinalNonDefaultedFields.add(fieldNode); } if (isDefault != null) { @@ -347,7 +357,8 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { // 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) { + if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false; + if (generateBuilderMethod) { JCMethodDecl builderMethod = generateBuilderMethod(builderMethodName, builderClassName, builderImplClassName, annotationNode, tdParent, typeParams); recursiveSetGeneratedBy(builderMethod, ast, annotationNode.getContext()); if (builderMethod != null) injectMethod(tdParent, builderMethod); @@ -369,6 +380,12 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { // Should not happen. } } + + if (nonFinalNonDefaultedFields != null && generateBuilderMethod) { + for (JavacNode fieldNode : nonFinalNonDefaultedFields) { + 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."); + } + } } /** |