aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/changelog.markdown1
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java26
-rw-r--r--test/transform/resource/after-delombok/BuilderGenericMethod.java40
-rw-r--r--test/transform/resource/after-delombok/BuilderWithExistingBuilderClass.java2
-rw-r--r--test/transform/resource/after-delombok/BuilderWithToBuilder.java2
-rw-r--r--test/transform/resource/after-ecj/BuilderGenericMethod.java35
-rw-r--r--test/transform/resource/before/BuilderGenericMethod.java11
7 files changed, 108 insertions, 9 deletions
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index fd4af685..51c1bf8d 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -10,6 +10,7 @@ Lombok Changelog
* BUGFIX: The generated hashCode would break the contract if `callSuper=true,of={}`. [Issue #1505](https://github.com/rzwitserloot/lombok/issues/1505)
* BUGFIX: `delombok` no longer prints the synthetic outer-class parameter. [Issue #1521](https://github.com/rzwitserloot/lombok/issues/1521)
* BUGFIX: @Builder.Default now also works when type parameters are present. [Issue #1527](https://github.com/rzwitserloot/lombok/issues/1527)
+* BUGFIX: @Builder now also works on method with a generified return type. [Issue #1420](https://github.com/rzwitserloot/lombok/issues/1420)
* INSTALLER: By default, the lombok installer now inserts an absolute path in `eclipse.ini` and friends, instead of a relative path. If you want the old behavior, you can use `java -jar -Dlombok.installer.fullpath=false lombok.jar`.
### v1.16.18 (July 3rd, 2017)
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index ea436422..420d4b72 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -212,7 +212,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
thrownExceptions = jmd.thrown;
nameOfBuilderMethod = jmd.name;
if (returnType instanceof JCTypeApply) {
- returnType = ((JCTypeApply) returnType).clazz;
+ returnType = cloneType(tdParent.getTreeMaker(), returnType, ast, annotationNode.getContext());
}
if (builderClassName.isEmpty()) {
if (returnType instanceof JCFieldAccess) {
@@ -232,7 +232,16 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
if (Character.isLowerCase(builderClassName.charAt(0))) {
builderClassName = Character.toTitleCase(builderClassName.charAt(0)) + builderClassName.substring(1);
}
- } else {
+ } else if (returnType instanceof JCTypeApply) {
+ JCExpression clazz = ((JCTypeApply) returnType).clazz;
+ if (clazz instanceof JCFieldAccess) {
+ builderClassName = ((JCFieldAccess) clazz).name + "Builder";
+ } else if (clazz instanceof JCIdent) {
+ builderClassName = ((JCIdent) clazz).name + "Builder";
+ }
+ }
+
+ if (builderClassName.isEmpty()) {
// This shouldn't happen.
System.err.println("Lombok bug ID#20140614-1651: javac HandleBuilder: return type to name conversion failed: " + returnType.getClass());
builderClassName = td.name.toString() + "Builder";
@@ -253,11 +262,14 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
tpOnRet = ((JCTypeApply) fullReturnType).arguments;
}
- if (returnType instanceof JCIdent) {
- simpleName = ((JCIdent) returnType).name;
+ JCExpression namingType = returnType;
+ if (returnType instanceof JCTypeApply) namingType = ((JCTypeApply) returnType).clazz;
+
+ if (namingType instanceof JCIdent) {
+ simpleName = ((JCIdent) namingType).name;
pkg = null;
- } else if (returnType instanceof JCFieldAccess) {
- JCFieldAccess jcfa = (JCFieldAccess) returnType;
+ } else if (namingType instanceof JCFieldAccess) {
+ JCFieldAccess jcfa = (JCFieldAccess) namingType;
simpleName = jcfa.name;
pkg = unpack(jcfa.selected);
if (pkg.startsWith("ERR:")) {
@@ -266,7 +278,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
return;
}
} else {
- annotationNode.addError("Expected a (parameterized) type here instead of a " + returnType.getClass().getName());
+ annotationNode.addError("Expected a (parameterized) type here instead of a " + namingType.getClass().getName());
return;
}
diff --git a/test/transform/resource/after-delombok/BuilderGenericMethod.java b/test/transform/resource/after-delombok/BuilderGenericMethod.java
new file mode 100644
index 00000000..f70ae871
--- /dev/null
+++ b/test/transform/resource/after-delombok/BuilderGenericMethod.java
@@ -0,0 +1,40 @@
+import java.util.List;
+import java.util.*;
+class BuilderGenericMethod<T> {
+ public <N extends Number> Map<N, T> foo(int a, long b) {
+ return null;
+ }
+ @java.lang.SuppressWarnings("all")
+ public class MapBuilder<N extends Number> {
+ @java.lang.SuppressWarnings("all")
+ private int a;
+ @java.lang.SuppressWarnings("all")
+ private long b;
+ @java.lang.SuppressWarnings("all")
+ MapBuilder() {
+ }
+ @java.lang.SuppressWarnings("all")
+ public MapBuilder<N> a(final int a) {
+ this.a = a;
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ public MapBuilder<N> b(final long b) {
+ this.b = b;
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ public Map<N, T> build() {
+ return BuilderGenericMethod.this.<N>foo(a, b);
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public java.lang.String toString() {
+ return "BuilderGenericMethod.MapBuilder(a=" + this.a + ", b=" + this.b + ")";
+ }
+ }
+ @java.lang.SuppressWarnings("all")
+ public <N extends Number> MapBuilder<N> builder() {
+ return new MapBuilder<N>();
+ }
+}
diff --git a/test/transform/resource/after-delombok/BuilderWithExistingBuilderClass.java b/test/transform/resource/after-delombok/BuilderWithExistingBuilderClass.java
index 15293470..0a5edacd 100644
--- a/test/transform/resource/after-delombok/BuilderWithExistingBuilderClass.java
+++ b/test/transform/resource/after-delombok/BuilderWithExistingBuilderClass.java
@@ -24,7 +24,7 @@ class BuilderWithExistingBuilderClass<T, K extends Number> {
return this;
}
@java.lang.SuppressWarnings("all")
- public BuilderWithExistingBuilderClass build() {
+ public BuilderWithExistingBuilderClass<String, Z> build() {
return BuilderWithExistingBuilderClass.<Z>staticMethod(arg1, arg2, arg3);
}
@java.lang.Override
diff --git a/test/transform/resource/after-delombok/BuilderWithToBuilder.java b/test/transform/resource/after-delombok/BuilderWithToBuilder.java
index e2ce1966..46387f0f 100644
--- a/test/transform/resource/after-delombok/BuilderWithToBuilder.java
+++ b/test/transform/resource/after-delombok/BuilderWithToBuilder.java
@@ -165,7 +165,7 @@ class StaticWithToBuilder<T, K> {
return this;
}
@java.lang.SuppressWarnings("all")
- public StaticWithToBuilder build() {
+ public StaticWithToBuilder<Z, String> build() {
return StaticWithToBuilder.<Z>test(mOne, bar);
}
@java.lang.Override
diff --git a/test/transform/resource/after-ecj/BuilderGenericMethod.java b/test/transform/resource/after-ecj/BuilderGenericMethod.java
new file mode 100644
index 00000000..1b770654
--- /dev/null
+++ b/test/transform/resource/after-ecj/BuilderGenericMethod.java
@@ -0,0 +1,35 @@
+import java.util.List;
+import lombok.Builder;
+import java.util.*;
+class BuilderGenericMethod<T> {
+ public @java.lang.SuppressWarnings("all") class MapBuilder<N extends Number> {
+ private @java.lang.SuppressWarnings("all") int a;
+ private @java.lang.SuppressWarnings("all") long b;
+ @java.lang.SuppressWarnings("all") MapBuilder() {
+ super();
+ }
+ public @java.lang.SuppressWarnings("all") MapBuilder<N> a(final int a) {
+ this.a = a;
+ return this;
+ }
+ public @java.lang.SuppressWarnings("all") MapBuilder<N> b(final long b) {
+ this.b = b;
+ return this;
+ }
+ public @java.lang.SuppressWarnings("all") Map<N, T> build() {
+ return BuilderGenericMethod.this.<N>foo(a, b);
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
+ return (((("BuilderGenericMethod.MapBuilder(a=" + this.a) + ", b=") + this.b) + ")");
+ }
+ }
+ BuilderGenericMethod() {
+ super();
+ }
+ public @Builder <N extends Number>Map<N, T> foo(int a, long b) {
+ return null;
+ }
+ public @java.lang.SuppressWarnings("all") <N extends Number>MapBuilder<N> builder() {
+ return new MapBuilder<N>();
+ }
+}
diff --git a/test/transform/resource/before/BuilderGenericMethod.java b/test/transform/resource/before/BuilderGenericMethod.java
new file mode 100644
index 00000000..63dcb4db
--- /dev/null
+++ b/test/transform/resource/before/BuilderGenericMethod.java
@@ -0,0 +1,11 @@
+import java.util.List;
+
+import lombok.Builder;
+import java.util.*;
+
+class BuilderGenericMethod<T> {
+ @Builder
+ public <N extends Number> Map<N,T> foo(int a, long b) {
+ return null;
+ }
+}