Skip to content

Commit

Permalink
Fix a bug where optional property interfaces in the Staged fixed orde…
Browse files Browse the repository at this point in the history
…r style have the wrong type parameters in the return type of the `build()` method.
  • Loading branch information
skinny85 committed Jan 21, 2024
1 parent 49731eb commit 591d10d
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,32 @@ protected final ParameterSpec setterParameterInInterface(VariableElement attribu

protected final TypeName attributeType(VariableElement attribute) {
TypeName ret = TypeName.get(attribute.asType());
return this.mangleTypeName(ret);
}

protected final String lastInterfaceName() {
String nameFromAnnotation = builderInterfaces == null
? ""
: builderInterfaces.lastInnerName();

return nameFromAnnotation.isEmpty()
? interfaceNameFromBaseName(defaultLastInterfaceName())
: nameFromAnnotation;
}

protected final void addBuildMethodToInterface(TypeSpec.Builder interfaceBuilder, boolean withMangledTypeParameters) {
TypeName targetClassTypeName = this.targetClassTypeName();
TypeName buildReturnType = withMangledTypeParameters
? this.mangleTypeName(targetClassTypeName)
: targetClassTypeName;
interfaceBuilder.addMethod(MethodSpec
.methodBuilder(this.buildMethodName())
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
.returns(buildReturnType)
.build());
}

private TypeName mangleTypeName(TypeName ret) {
if (ret instanceof TypeVariableName) {
// if this is a type variable, we need to mangle it
TypeVariableName typeVariableName = (TypeVariableName) ret;
Expand Down Expand Up @@ -100,24 +126,6 @@ private List<TypeName> mangleTypeNameParameters(List<TypeName> typeArguments) {
return ret;
}

protected final String lastInterfaceName() {
String nameFromAnnotation = builderInterfaces == null
? ""
: builderInterfaces.lastInnerName();

return nameFromAnnotation.isEmpty()
? interfaceNameFromBaseName(defaultLastInterfaceName())
: nameFromAnnotation;
}

protected final void addBuildMethodToInterface(TypeSpec.Builder interfaceBuilder) {
interfaceBuilder.addMethod(MethodSpec
.methodBuilder(buildMethodName())
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
.returns(targetClassTypeName())
.build());
}

protected final TypeName innerInterfaceNamed(String interfaceName) {
return this.innerInterfaceNamed(interfaceName, false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ protected void generateClassesNeededByBuilder() throws Exception {
}
}

addBuildMethodToInterface(optionalsInterfaceBuilder);
this.addBuildMethodToInterface(optionalsInterfaceBuilder, /* withMangledTypeParameters */ false);
outerInterfacesBuilder.addType(optionalsInterfaceBuilder.build());

JavaFile javaFile = JavaFile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ protected void generateClassesNeededByBuilder() throws Exception {
.build());

if (nextAttribute == null && isOptional(currentAttribute)) {
addBuildMethodToInterface(innerInterfaceBuilder);
this.addBuildMethodToInterface(innerInterfaceBuilder, /* withMangledTypeParameters */ true);
}
} while (nextAttribute != null
&& isOptional(currentAttribute)
Expand All @@ -62,7 +62,7 @@ && isOptional(currentAttribute)
.interfaceBuilder(lastInterfaceName())
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addTypeVariables(this.builderClassTypeParameters());
addBuildMethodToInterface(finalInterfaceBuilder);
this.addBuildMethodToInterface(finalInterfaceBuilder, /* withMangledTypeParameters */ false);
outerInterfacesBuilder.addType(finalInterfaceBuilder.build());

JavaFile javaFile = JavaFile
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/org/jilt/test/GenericTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ public void three_type_parameters_generic_class_with_staged_preserving_order_bui
public void four_type_parameters_generic_class_with_static_factory_method_and_subset_of_type_parameters_works() {
Generic4TypeParams<Boolean, ?, Boolean, Long> value = Generic4TypeParamsBuilder.<Boolean, Boolean>generic4TypeParams()
.a(true)
.c(null)
.str("str")
.c(null)
.build();

assertThat(value.a).isTrue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import java.io.Serializable;

public final class Generic4TypeParams<A, B, C, D> {
@Builder(style = BuilderStyle.STAGED)
@Builder(style = BuilderStyle.STAGED_PRESERVING_ORDER)
public static <AA, CC> Generic4TypeParams<AA, ? extends Serializable, CC, Long> make(AA a, @Opt String str, CC c, @Opt Long lng) {
return new Generic4TypeParams<AA, String, CC, Long>(a, str, c, lng);
}
Expand Down

0 comments on commit 591d10d

Please sign in to comment.