Skip to content

Commit b250645

Browse files
authored
fix nested record name collisions (#67)
1 parent dad18da commit b250645

File tree

5 files changed

+64
-34
lines changed

5 files changed

+64
-34
lines changed

avaje-record-builder-core/src/main/java/io/avaje/recordbuilder/internal/ClassBodyBuilder.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ static String createClassStart(
2121
boolean isImported,
2222
String packageName) {
2323

24-
final var components = type.getRecordComponents();
25-
final var shortName = type.getSimpleName().toString();
2624
if (type.getEnclosingElement() instanceof TypeElement) {
2725
isImported = true;
2826
}
27+
2928
var utype = UType.parse(type.asType());
29+
final var components = type.getRecordComponents();
30+
3031
var fulltypeParams =
3132
utype.componentTypes().stream()
3233
.map(
@@ -52,9 +53,15 @@ static String createClassStart(
5253
builderFrom(components).transform(s -> numberOfComponents > 5 ? "\n " + s : s);
5354
final String build =
5455
build(components).transform(s -> numberOfComponents > 6 ? "\n " + s : s);
56+
57+
final var builderName =
58+
ProcessorUtils.shortType(utype.mainType()).replace(".", "$") + "Builder";
59+
60+
final var shortName = type.getSimpleName().toString();
5561
return ClassTemplate.classTemplate(
5662
packageName,
5763
imports,
64+
builderName,
5865
shortName,
5966
fieldString,
6067
constructorParams,

avaje-record-builder-core/src/main/java/io/avaje/recordbuilder/internal/RecordProcessor.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ private void readElement(TypeElement type, BuilderPrism prism) {
107107
unnamed
108108
? ""
109109
: packageElement.getQualifiedName().toString() + (isImported ? ".builder" : "");
110-
final var shortName = type.getSimpleName().toString();
111-
110+
var builderName =
111+
ProcessorUtils.shortType(UType.parse(type.asType()).mainType()).replace(".", "$")
112+
+ "Builder";
112113
try (var writer =
113114
new Append(
114-
createSourceFile((unnamed ? "" : packageName + ".") + shortName + "Builder")
115-
.openWriter())) {
115+
createSourceFile((unnamed ? "" : packageName + ".") + builderName).openWriter())) {
116116

117117
var typeParams =
118118
type.getTypeParameters().stream()
@@ -121,7 +121,7 @@ private void readElement(TypeElement type, BuilderPrism prism) {
121121
.transform(s -> s.isEmpty() ? s : "<" + s + ">");
122122
writer.append(ClassBodyBuilder.createClassStart(type, typeParams, isImported, packageName));
123123

124-
methods(writer, typeParams, shortName, components, prism);
124+
methods(writer, typeParams, builderName, components, prism);
125125
} catch (final IOException e) {
126126
throw new UncheckedIOException(e);
127127
}
@@ -130,18 +130,20 @@ private void readElement(TypeElement type, BuilderPrism prism) {
130130
private void methods(
131131
Append writer,
132132
String typeParams,
133-
String shortName,
133+
String builderName,
134134
List<? extends RecordComponentElement> components,
135135
BuilderPrism prism) {
136136
boolean getters = prism.getters();
137137

138138
for (final var element : components) {
139+
139140
final var type = UType.parse(element.asType());
141+
140142
writer.append(
141143
MethodSetter.methodSetter(
142-
element.getSimpleName(), type.shortType(), shortName, typeParams));
144+
element.getSimpleName(), type.shortType(), builderName, typeParams));
143145
if (getters) {
144-
writer.append(MethodGetter.methodGetter(element.getSimpleName(), type, shortName));
146+
writer.append(MethodGetter.methodGetter(element.getSimpleName(), type, builderName));
145147
}
146148

147149
if (APContext.isAssignable(type.mainType(), "java.util.Collection")) {
@@ -150,7 +152,7 @@ private void methods(
150152
Name simpleName = element.getSimpleName();
151153
writer.append(
152154
MethodAdd.methodAdd(
153-
simpleName.toString(), type.shortType(), shortName, param0ShortType, typeParams));
155+
simpleName.toString(), builderName, param0ShortType, typeParams));
154156
}
155157

156158
if (APContext.isAssignable(type.mainType(), "java.util.Map")) {
@@ -160,7 +162,7 @@ private void methods(
160162
Name simpleName = element.getSimpleName();
161163
writer.append(
162164
MethodPut.methodPut(
163-
simpleName.toString(), shortName, param0ShortType, param1ShortType, typeParams));
165+
simpleName.toString(), builderName, param0ShortType, param1ShortType, typeParams));
164166
}
165167
}
166168
writer.append("}");

avaje-record-builder-core/src/main/java/io/avaje/recordbuilder/internal/Templates.java

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,23 @@ private Templates() {}
1414
1515
/** Builder class for {@link {{shortName}} } */
1616
@Generated("avaje-record-builder")
17-
public class {{shortName}}Builder{{fullTypeParams}} {
17+
public class {{builderName}}{{fullTypeParams}} {
1818
1919
{{fields}}
20-
private {{shortName}}Builder() {}
20+
private {{builderName}}() {}
2121
{{constructor}}
2222
/**
2323
* Return a new builder with all fields set to default Java values
2424
*/
25-
public static{{fullTypeParamsTransformed}}{{shortName}}Builder{{typeParams}} builder() {
26-
return new {{shortName}}Builder{{typeParams}}();
25+
public static{{fullTypeParamsTransformed}}{{builderName}}{{typeParams}} builder() {
26+
return new {{builderName}}{{typeParams}}();
2727
}
2828
2929
/**
3030
* Return a new builder with all fields set to the values taken from the given record instance
3131
*/
32-
public static{{fullTypeParamsTransformed}}{{shortName}}Builder{{typeParams}} builder({{shortName}}{{typeParams}} from) {
33-
return new {{shortName}}Builder{{typeParams}}({{builderFrom}});
32+
public static{{fullTypeParamsTransformed}}{{builderName}}{{typeParams}} builder({{shortName}}{{typeParams}} from) {
33+
return new {{builderName}}{{typeParams}}({{builderFrom}});
3434
}
3535
3636
/**
@@ -43,14 +43,15 @@ public class {{shortName}}Builder{{fullTypeParams}} {
4343
private static <T> T requireNonNull(@Nullable T obj, String fieldName) {
4444
if (obj == null) {
4545
throw new IllegalStateException(
46-
\"{{shortName}}Builder expected a value for property %s, but was null.\".formatted(fieldName));
46+
\"{{builderName}} expected a value for property %s, but was null.\".formatted(fieldName));
4747
}
4848
return obj;
4949
}
5050
""")
5151
public record ClassTemplate(
5252
String packageName,
5353
String imports,
54+
String builderName,
5455
String shortName,
5556
String fields,
5657
String constructor,
@@ -66,6 +67,7 @@ String render() {
6667
static String classTemplate(
6768
String packageName,
6869
String imports,
70+
String builderName,
6971
String shortName,
7072
String fields,
7173
String constructorArgs,
@@ -78,10 +80,11 @@ static String classTemplate(
7880
var constructor =
7981
constructorArgs.isBlank()
8082
? ""
81-
: new Constructor(shortName, constructorArgs, constructorBody).render();
83+
: new Constructor(builderName, constructorArgs, constructorBody).render();
8284
return new ClassTemplate(
8385
packageName.isBlank() ? "" : "package " + packageName + ";",
8486
imports,
87+
builderName,
8588
shortName,
8689
fields,
8790
constructor,
@@ -98,11 +101,11 @@ static String classTemplate(
98101
template =
99102
"""
100103
101-
private {{shortName}}Builder({{args}}) {
104+
private {{builderName}}({{args}}) {
102105
{{constructorBody}}
103106
}
104107
""")
105-
public record Constructor(String shortName, String args, String constructorBody) {
108+
public record Constructor(String builderName, String args, String constructorBody) {
106109

107110
String render() {
108111
return ConstructorRenderer.of().execute(this);
@@ -114,19 +117,19 @@ String render() {
114117
"""
115118
116119
/** Set a new value for {@code {{componentName}} }. */
117-
public {{shortName}}Builder{{typeParams}} {{componentName}}({{type}} {{componentName}}) {
120+
public {{builderName}}{{typeParams}} {{componentName}}({{type}} {{componentName}}) {
118121
this.{{componentName}} = {{componentName}};
119122
return this;
120123
}
121124
""")
122125
public record MethodSetter(
123-
String componentName, String type, String shortName, String typeParams) {
126+
String componentName, String type, String builderName, String typeParams) {
124127

125128
static String methodSetter(
126-
CharSequence componentName, String type, String shortName, String typeParams) {
129+
CharSequence componentName, String type, String builderName, String typeParams) {
127130

128131
return new MethodSetter(
129-
componentName.toString(), type, shortName.replace(".", "$"), typeParams)
132+
componentName.toString(), type, builderName, typeParams)
130133
.render();
131134
}
132135

@@ -175,20 +178,20 @@ String render() {
175178
"""
176179
177180
/** Add new element to the {@code {{componentName}} } collection. */
178-
public {{shortName}}Builder{{typeParams}} add{{upperCamel}}({{param0}} element) {
181+
public {{builderName}}{{typeParams}} add{{upperCamel}}({{param0}} element) {
179182
this.{{componentName}}.add(element);
180183
return this;
181184
}
182185
""")
183186
public record MethodAdd(
184-
String componentName, String shortName, String upperCamel, String param0, String typeParams) {
187+
String componentName, String builderName, String upperCamel, String param0, String typeParams) {
185188
static String methodAdd(
186-
String componentName, String type, String shortName, String param0, String typeParams) {
189+
String componentName, String builderName, String param0, String typeParams) {
187190
String upperCamel =
188191
Character.toUpperCase(componentName.charAt(0)) + componentName.substring(1);
189192

190193
return new MethodAdd(
191-
componentName, shortName.replace(".", "$"), upperCamel, param0, typeParams)
194+
componentName, builderName, upperCamel, param0, typeParams)
192195
.render();
193196
}
194197

@@ -202,26 +205,26 @@ String render() {
202205
"""
203206
204207
/** Add new key/value pair to the {@code {{componentName}} } map. */
205-
public {{shortName}}Builder{{typeParams}} put{{upperCamel}}({{param0}} key, {{param1}} value) {
208+
public {{builderName}}{{typeParams}} put{{upperCamel}}({{param0}} key, {{param1}} value) {
206209
this.{{componentName}}.put(key, value);
207210
return this;
208211
}
209212
""")
210213
public record MethodPut(
211214
String componentName,
212-
String shortName,
215+
String builderName,
213216
String upperCamel,
214217
String param0,
215218
String param1,
216219
String typeParams) {
217220

218221
static String methodPut(
219-
String componentName, String shortName, String param0, String param1, String typeParams) {
222+
String componentName, String builderName, String param0, String param1, String typeParams) {
220223
String upperCamel =
221224
Character.toUpperCase(componentName.charAt(0)) + componentName.substring(1);
222225

223226
return new MethodPut(
224-
componentName, shortName.replace(".", "$"), upperCamel, param0, param1, typeParams)
227+
componentName, builderName, upperCamel, param0, param1, typeParams)
225228
.render();
226229
}
227230

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package io.avaje.recordbuilder.nested;
2+
3+
import io.avaje.recordbuilder.RecordBuilder;
4+
5+
@RecordBuilder
6+
public record TestRecord(String s) {
7+
@RecordBuilder
8+
public record NestedTestRecord(String s) {}
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package io.avaje.recordbuilder.nested;
2+
3+
import io.avaje.recordbuilder.RecordBuilder;
4+
5+
@RecordBuilder
6+
public record TestRecord2(String s) {
7+
@RecordBuilder
8+
public record NestedTestRecord(String s) {}
9+
}

0 commit comments

Comments
 (0)