Skip to content

Commit 32a7740

Browse files
committed
generate builder impl
1 parent 0e4bf00 commit 32a7740

File tree

2 files changed

+55
-12
lines changed

2 files changed

+55
-12
lines changed

compiler/src/main/java/io/jbock/simple/processor/binding/ParameterBinding.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,26 @@
1212
public final class ParameterBinding extends Binding {
1313

1414
private final Element element; // VariableElement or ExecutableElement (setter)
15+
private final String suggestedVariableName;
1516

1617
private ParameterBinding(
1718
Key key,
18-
Element element) {
19+
Element element,
20+
String suggestedVariableName) {
1921
super(key);
2022
this.element = element;
23+
this.suggestedVariableName = suggestedVariableName;
2124
}
2225

2326
public static ParameterBinding create(VariableElement parameter, KeyFactory keyFactory) {
2427
Key key = keyFactory.getKey(parameter);
25-
return new ParameterBinding(key, parameter);
28+
return new ParameterBinding(key, parameter, parameter.getSimpleName().toString());
2629
}
2730

2831
public static ParameterBinding create(ExecutableElement setter, KeyFactory keyFactory) {
29-
Key key = keyFactory.getKey(setter.getParameters().get(0));
30-
return new ParameterBinding(key, setter);
32+
VariableElement parameter = setter.getParameters().get(0);
33+
Key key = keyFactory.getKey(parameter);
34+
return new ParameterBinding(key, setter, parameter.getSimpleName().toString());
3135
}
3236

3337
@Override
@@ -52,6 +56,6 @@ public List<DependencyRequest> requests() {
5256

5357
@Override
5458
public String suggestedVariableName() {
55-
return element.getSimpleName().toString();
59+
return suggestedVariableName;
5660
}
5761
}

compiler/src/main/java/io/jbock/simple/processor/writing/ComponentImpl.java

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import io.jbock.simple.Inject;
1111
import io.jbock.simple.processor.SimpleComponentProcessor;
1212
import io.jbock.simple.processor.binding.Binding;
13+
import io.jbock.simple.processor.binding.BuilderElement;
1314
import io.jbock.simple.processor.binding.ComponentElement;
1415
import io.jbock.simple.processor.binding.DependencyRequest;
1516
import io.jbock.simple.processor.binding.FactoryElement;
@@ -18,6 +19,7 @@
1819

1920
import javax.annotation.processing.Generated;
2021
import javax.lang.model.element.ExecutableElement;
22+
import javax.lang.model.type.TypeMirror;
2123
import java.util.Collection;
2224
import java.util.Map;
2325
import java.util.function.Function;
@@ -73,20 +75,29 @@ TypeSpec generate() {
7375
.collect(Collectors.toList()));
7476
spec.addMethod(method.build());
7577
}
76-
component.factoryElement().ifPresentOrElse(factory -> {
78+
component.factoryElement().ifPresent(factory -> {
7779
spec.addMethod(MethodSpec.methodBuilder("factory")
7880
.addModifiers(STATIC)
7981
.returns(TypeName.get(factory.element().asType()))
8082
.addStatement("return new $T()", factory.generatedClass())
8183
.build());
82-
spec.addType(createFactory(factory, names));
83-
}, () -> {
84+
spec.addType(createFactoryImpl(factory));
85+
});
86+
component.builderElement().ifPresent(builder -> {
87+
spec.addMethod(MethodSpec.methodBuilder("builder")
88+
.addModifiers(STATIC)
89+
.returns(TypeName.get(builder.element().asType()))
90+
.addStatement("return new $T()", builder.generatedClass())
91+
.build());
92+
spec.addType(createBuilderImpl(builder));
93+
});
94+
if (component.factoryElement().isEmpty() && component.builderElement().isEmpty()) {
8495
spec.addMethod(MethodSpec.methodBuilder("create")
8596
.addModifiers(STATIC)
8697
.returns(TypeName.get(component.element().asType()))
8798
.addStatement("return new $T()", component.generatedClass())
8899
.build());
89-
});
100+
}
90101
spec.addAnnotation(AnnotationSpec.builder(Generated.class)
91102
.addMember("value", CodeBlock.of("$S", SimpleComponentProcessor.class.getCanonicalName()))
92103
.addMember("comments", CodeBlock.of("$S", "https://github.com/jbock-java/simple-component"))
@@ -97,9 +108,7 @@ TypeSpec generate() {
97108
return spec.build();
98109
}
99110

100-
private TypeSpec createFactory(
101-
FactoryElement factory,
102-
Function<Key, ParameterSpec> names) {
111+
private TypeSpec createFactoryImpl(FactoryElement factory) {
103112
Collection<ParameterBinding> parameterBindings = component.parameterBindings();
104113
TypeSpec.Builder spec = TypeSpec.classBuilder(factory.generatedClass());
105114
spec.addModifiers(PRIVATE, STATIC, FINAL);
@@ -120,6 +129,36 @@ private TypeSpec createFactory(
120129
return spec.build();
121130
}
122131

132+
private TypeSpec createBuilderImpl(BuilderElement builder) {
133+
Collection<ParameterBinding> parameterBindings = component.parameterBindings();
134+
TypeMirror builderType = builder.element().asType();
135+
TypeSpec.Builder spec = TypeSpec.classBuilder(builder.generatedClass());
136+
for (ParameterBinding b : parameterBindings) {
137+
spec.addField(FieldSpec.builder(b.key().typeName(), names.apply(b.key()).name).build());
138+
MethodSpec.Builder setterMethod = MethodSpec.methodBuilder(b.element().getSimpleName().toString());
139+
setterMethod.addAnnotation(Override.class);
140+
setterMethod.addParameter(names.apply(b.key()));
141+
setterMethod.addStatement("this.$N = $N", names.apply(b.key()), names.apply(b.key()));
142+
setterMethod.addStatement("return this");
143+
setterMethod.returns(TypeName.get(builderType));
144+
setterMethod.addModifiers(b.element().getModifiers().stream()
145+
.filter(m -> m == PUBLIC || m == PROTECTED).collect(Collectors.toList()));
146+
spec.addMethod(setterMethod.build());
147+
}
148+
spec.addModifiers(PRIVATE, STATIC, FINAL);
149+
spec.addSuperinterface(builderType);
150+
MethodSpec.Builder buildMethod = MethodSpec.methodBuilder(builder.buildMethod().getSimpleName().toString());
151+
buildMethod.addAnnotation(Override.class);
152+
buildMethod.addModifiers(builder.buildMethod().getModifiers().stream()
153+
.filter(m -> m == PUBLIC || m == PROTECTED).collect(Collectors.toList()));
154+
buildMethod.returns(TypeName.get(component.element().asType()));
155+
buildMethod.addStatement("return new $T($L)", component.generatedClass(), parameterBindings.stream()
156+
.map(b -> CodeBlock.of("$N", names.apply(b.key())))
157+
.collect(CodeBlock.joining(", ")));
158+
spec.addMethod(buildMethod.build());
159+
return spec.build();
160+
}
161+
123162
public static final class Factory {
124163
private final ComponentElement component;
125164

0 commit comments

Comments
 (0)