aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/eclipse
diff options
context:
space:
mode:
authorJan Rieke <it@janrieke.de>2018-09-11 16:59:29 +0200
committerJan Rieke <it@janrieke.de>2018-09-11 16:59:29 +0200
commitda59d2d6375afcfcf6cb43288adba61cb99a49e8 (patch)
tree489a73df6b17b11d4bda2e7cace9b2a8d261db0a /src/core/lombok/eclipse
parent1f3688fdba92508e091eab39b6131dbca2a8ef83 (diff)
downloadlombok-da59d2d6375afcfcf6cb43288adba61cb99a49e8.tar.gz
lombok-da59d2d6375afcfcf6cb43288adba61cb99a49e8.tar.bz2
lombok-da59d2d6375afcfcf6cb43288adba61cb99a49e8.zip
SuperBuilder: generate toBuilder method (ecj)
Diffstat (limited to 'src/core/lombok/eclipse')
-rw-r--r--src/core/lombok/eclipse/handlers/HandleSuperBuilder.java47
1 files changed, 46 insertions, 1 deletions
diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
index 6c1b2cac..1bbc514e 100644
--- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
@@ -104,7 +104,8 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
private static final char[] DEFAULT_PREFIX = "$default$".toCharArray();
private static final char[] SET_PREFIX = "$set".toCharArray();
private static final char[] SELF_METHOD_NAME = "self".toCharArray();
- private static final char[] TO_BUILDER_METHOD_NAME = "toBuilder".toCharArray();
+ private static final String TO_BUILDER_METHOD_NAME_STRING = "toBuilder";
+ private static final char[] TO_BUILDER_METHOD_NAME = TO_BUILDER_METHOD_NAME_STRING.toCharArray();
private static final char[] FILL_VALUES_METHOD_NAME = "$fillValuesFrom".toCharArray();
private static final char[] EMPTY_LIST = "emptyList".toCharArray();
@@ -345,6 +346,15 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
MethodDeclaration md = generateBuilderMethod(builderMethodName, builderClassName, builderImplClassName, tdParent, typeParams, ast);
if (md != null) injectMethod(tdParent, md);
}
+
+ if (toBuilder) switch (methodExists(TO_BUILDER_METHOD_NAME_STRING, tdParent, 0)) {
+ case EXISTS_BY_USER:
+ annotationNode.addWarning("Not generating toBuilder() as it already exists.");
+ break;
+ case NOT_EXISTS:
+ MethodDeclaration md = generateToBuilderMethod(builderClassName, builderImplClassName, tdParent, typeParams, ast);
+ if (md != null) injectMethod(tdParent, md);
+ }
}
private EclipseNode generateBuilderAbstractClass(EclipseNode tdParent, String builderClass,
@@ -535,6 +545,41 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
}
/**
+ * Generates a <code>toBuilder()</code> method in the annotated class that looks like this:
+ * <pre>
+ * public ParentBuilder&lt;?, ?&gt; toBuilder() {
+ * return new <i>Foobar</i>BuilderImpl().$fillValuesFrom(this);
+ * }
+ * </pre>
+ */
+ private MethodDeclaration generateToBuilderMethod(String builderClassName, String builderImplClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
+ int pS = source.sourceStart, pE = source.sourceEnd;
+ long p = (long) pS << 32 | pE;
+
+ MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
+ out.selector = TO_BUILDER_METHOD_NAME;
+ out.modifiers = ClassFileConstants.AccPublic;
+ out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
+
+ // Add type params if there are any.
+ if (typeParams != null && typeParams.length > 0) out.typeParameters = copyTypeParams(typeParams, source);
+
+ TypeReference[] wildcards = new TypeReference[] {new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND) };
+ out.returnType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(), mergeToTypeReferences(typeParams, wildcards), 0, p);
+
+ AllocationExpression newClass = new AllocationExpression();
+ newClass.type = namePlusTypeParamsToTypeReference(builderImplClassName.toCharArray(), typeParams, p);
+ MessageSend invokeFillMethod = new MessageSend();
+ invokeFillMethod.receiver = newClass;
+ invokeFillMethod.selector = FILL_VALUES_METHOD_NAME;
+ invokeFillMethod.arguments = new Expression[] {new ThisReference(0, 0)};
+ out.statements = new Statement[] {new ReturnStatement(invokeFillMethod, pS, pE)};
+
+ out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope);
+ return out;
+ }
+
+ /**
* Generates a <code>$fillValuesFrom()</code> method in the abstract builder class that looks
* like this:
* <pre>