aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lombok/javac')
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java57
1 files changed, 36 insertions, 21 deletions
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index 30fec45b..ab833195 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -24,6 +24,8 @@ package lombok.javac.handlers;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
+import javax.lang.model.element.Modifier;
+
import org.mangosdk.spi.ProviderFor;
import com.sun.tools.javac.code.Flags;
@@ -116,11 +118,12 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCExpression returnType;
List<JCTypeParameter> typeParams = List.nil();
List<JCExpression> thrownExceptions = List.nil();
- Name nameOfStaticBuilderMethod;
+ Name nameOfBuilderMethod;
JavacNode tdParent;
JavacNode fillParametersFrom = parent.get() instanceof JCMethodDecl ? parent : null;
boolean addCleaning = false;
+ boolean isStatic = true;
if (parent.get() instanceof JCClassDecl) {
tdParent = parent;
@@ -147,7 +150,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams);
typeParams = td.typarams;
thrownExceptions = List.nil();
- nameOfStaticBuilderMethod = null;
+ nameOfBuilderMethod = null;
if (builderClassName.isEmpty()) builderClassName = td.name.toString() + "Builder";
} else if (fillParametersFrom != null && fillParametersFrom.getName().toString().equals("<init>")) {
JCMethodDecl jmd = (JCMethodDecl) fillParametersFrom.get();
@@ -161,20 +164,17 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams);
typeParams = td.typarams;
thrownExceptions = jmd.thrown;
- nameOfStaticBuilderMethod = null;
+ nameOfBuilderMethod = null;
if (builderClassName.isEmpty()) builderClassName = td.name.toString() + "Builder";
} else if (fillParametersFrom != null) {
tdParent = parent.up();
JCClassDecl td = (JCClassDecl) tdParent.get();
JCMethodDecl jmd = (JCMethodDecl) fillParametersFrom.get();
- if ((jmd.mods.flags & Flags.STATIC) == 0) {
- annotationNode.addError("@Builder is only supported on types, constructors, and static methods.");
- return;
- }
+ isStatic = (jmd.mods.flags & Flags.STATIC) != 0;
returnType = jmd.restype;
typeParams = jmd.typarams;
thrownExceptions = jmd.thrown;
- nameOfStaticBuilderMethod = jmd.name;
+ nameOfBuilderMethod = jmd.name;
if (builderClassName.isEmpty()) {
if (returnType instanceof JCTypeApply) {
returnType = ((JCTypeApply) returnType).clazz;
@@ -204,7 +204,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
}
} else {
- annotationNode.addError("@Builder is only supported on types, constructors, and static methods.");
+ annotationNode.addError("@Builder is only supported on types, constructors, and methods.");
return;
}
@@ -222,8 +222,16 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JavacNode builderType = findInnerClass(tdParent, builderClassName);
if (builderType == null) {
- builderType = makeBuilderClass(tdParent, builderClassName, typeParams, ast);
+ builderType = makeBuilderClass(isStatic, tdParent, builderClassName, typeParams, ast);
} else {
+ JCClassDecl builderTypeDeclaration = (JCClassDecl) builderType.get();
+ if (isStatic && !builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) {
+ annotationNode.addError("Existing Builder must be a static inner class.");
+ return;
+ } else if (!isStatic && builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) {
+ annotationNode.addError("Existing Builder must be a non-static inner class.");
+ return;
+ }
sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderType, annotationNode);
/* generate errors for @Singular BFDs that have one already defined node. */ {
for (BuilderFieldData bfd : builderFields) {
@@ -265,7 +273,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
if (methodExists(buildMethodName, builderType, -1) == MemberExistsResult.NOT_EXISTS) {
- JCMethodDecl md = generateBuildMethod(buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, ast, addCleaning);
+ JCMethodDecl md = generateBuildMethod(isStatic, buildMethodName, nameOfBuilderMethod, returnType, builderFields, builderType, thrownExceptions, ast, addCleaning);
if (md != null) injectMethod(builderType, md);
}
@@ -281,7 +289,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
if (addCleaning) injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
- JCMethodDecl md = generateBuilderMethod(builderMethodName, builderClassName, tdParent, typeParams);
+ JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, tdParent, typeParams);
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
if (md != null) injectMethod(tdParent, md);
}
@@ -316,7 +324,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
*/
}
- private JCMethodDecl generateBuildMethod(String name, Name staticName, JCExpression returnType, java.util.List<BuilderFieldData> builderFields, JavacNode type, List<JCExpression> thrownExceptions, JCTree source, boolean addCleaning) {
+ private JCMethodDecl generateBuildMethod(boolean isStatic, String buildName, Name builderName, JCExpression returnType, java.util.List<BuilderFieldData> builderFields, JavacNode type, List<JCExpression> thrownExceptions, JCTree source, boolean addCleaning) {
JavacTreeMaker maker = type.getTreeMaker();
JCExpression call;
@@ -344,16 +352,19 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
statements.append(maker.Exec(maker.Assign(maker.Select(maker.Ident(type.toName("this")), type.toName("$lombokUnclean")), maker.Literal(CTC_BOOLEAN, true))));
}
- if (staticName == null) {
+ if (builderName == null) {
call = maker.NewClass(null, List.<JCExpression>nil(), returnType, args.toList(), null);
statements.append(maker.Return(call));
} else {
+
ListBuffer<JCExpression> typeParams = new ListBuffer<JCExpression>();
for (JCTypeParameter tp : ((JCClassDecl) type.get()).typarams) {
typeParams.append(maker.Ident(tp.name));
}
-
- JCExpression fn = maker.Select(maker.Ident(((JCClassDecl) type.up().get()).name), staticName);
+ JCExpression callee = maker.Ident(((JCClassDecl) type.up().get()).name);
+ if (!isStatic)
+ callee = maker.Select(callee, type.up().toName("this"));
+ JCExpression fn = maker.Select(callee, builderName);
call = maker.Apply(typeParams.toList(), fn, args.toList());
if (returnType instanceof JCPrimitiveTypeTree && CTC_VOID.equals(typeTag(returnType))) {
statements.append(maker.Exec(call));
@@ -364,10 +375,10 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCBlock body = maker.Block(0, statements.toList());
- return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName(name), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null);
+ return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName(buildName), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null);
}
- public JCMethodDecl generateBuilderMethod(String builderMethodName, String builderClassName, JavacNode type, List<JCTypeParameter> typeParams) {
+ public JCMethodDecl generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, JavacNode type, List<JCTypeParameter> typeParams) {
JavacTreeMaker maker = type.getTreeMaker();
ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
@@ -379,7 +390,9 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCStatement statement = maker.Return(call);
JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
- return maker.MethodDef(maker.Modifiers(Flags.STATIC | Flags.PUBLIC), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(maker, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
+ int modifiers = Flags.PUBLIC;
+ if (isStatic) modifiers |= Flags.STATIC;
+ return maker.MethodDef(maker.Modifiers(modifiers), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(maker, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
}
public void generateBuilderFields(JavacNode builderType, java.util.List<BuilderFieldData> builderFields, JCTree source) {
@@ -443,9 +456,11 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
return null;
}
- public JavacNode makeBuilderClass(JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast) {
+ public JavacNode makeBuilderClass(boolean isStatic, JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast) {
JavacTreeMaker maker = tdParent.getTreeMaker();
- JCModifiers mods = maker.Modifiers(Flags.PUBLIC | Flags.STATIC);
+ int modifiers = Flags.PUBLIC;
+ if (isStatic) modifiers |= Flags.STATIC;
+ JCModifiers mods = maker.Modifiers(modifiers);
JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(maker, typeParams), null, List.<JCExpression>nil(), List.<JCTree>nil());
return injectType(tdParent, builder);
}