support for @Builder on methods with a generified return type. Fixes #1420

This commit is contained in:
Roel Spilker committed 2017-12-12 02:42:14 +01:00
1 parent f2530ab37e
commit d9031506b5
7 files changed
+108 -9

No files matched your search

+1
View File
@@ -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)
@@ -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;
}
@@ -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>();
}
}
@@ -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
@@ -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
@@ -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>();
}
}
@@ -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;
}
}