summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-05-20 22:30:16 +0100
committerMichael Williamson <mike@zwobble.org>2026-05-20 22:30:16 +0100
commit53aebac0674c8a61078cdfd13a845f23a017d076 (patch)
treec2bbbf0d745ab9eb6e024e659bad0089dc35a211
parent2cf8b4009dac7c076f794911b6c29741d78eb191 (diff)
Add with methods to Java builders
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java82
1 files changed, 58 insertions, 24 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java
index 44eb44b..abe8cf7 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java
@@ -18,9 +18,11 @@ import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
public class JavaTypesGenerator implements Generator {
public static final String NAME = "java-types";
+ private static final String BUILDER_TYPE_NAME = "Builder";
public static OutputConfig parseOutputConfig(Path projectRoot, Json5Object output) {
return () -> {
@@ -100,8 +102,6 @@ public class JavaTypesGenerator implements Generator {
TypedStructDefinitionNode structDefinition,
Context context
) {
- var javaPackage = namespaceToJavaPackageParts(structDefinition.type().namespaceName());
-
var components = structDefinition.fields().stream()
.map(field -> new JavaRecordComponent(
generateTypeRef(field.type()),
@@ -113,8 +113,7 @@ public class JavaTypesGenerator implements Generator {
.map(this::generateTypeRef)
.toList();
- var builderTypeName = "Builder";
- var builderJavaTypeRef = JavaTypeRef.inner(javaPackage, structDefinition.name(), builderTypeName);
+ var builderJavaTypeRef = generateBuilderTypeRef(structDefinition.type());
var arbitraryComponentValues = structDefinition.fields().stream()
.map(field -> arbitraryValue(field.type(), context))
@@ -137,31 +136,58 @@ public class JavaTypesGenerator implements Generator {
))
))
),
- new JavaRecordDeclaration(
- builderTypeName,
- components,
- List.of(),
- List.of(
- new JavaMethodDeclaration(
- "build",
- JavaMethodKind.INSTANCE,
- generateTypeRef(structDefinition.type()),
- List.of(),
- new JavaBlock(List.of(
- new JavaReturn(new JavaNewExpression(
- generateTypeRef(structDefinition.type()),
- components.stream().<JavaExpression>map(component -> new JavaRef(component.name())).toList()
- ))
- ))
- )
- ),
- DocComment.EMPTY
- )
+ generateStructDefinitionBuilder(structDefinition, components)
),
structDefinition.docComment()
);
}
+ private JavaRecordDeclaration generateStructDefinitionBuilder(
+ TypedStructDefinitionNode structDefinition,
+ List<JavaRecordComponent> components
+ ) {
+ var builderJavaTypeRef = generateBuilderTypeRef(structDefinition.type());
+
+ var body = new ArrayList<JavaClassBodyDeclaration>();
+ body.add(new JavaMethodDeclaration(
+ "build",
+ JavaMethodKind.INSTANCE,
+ generateTypeRef(structDefinition.type()),
+ List.of(),
+ new JavaBlock(List.of(
+ new JavaReturn(new JavaNewExpression(
+ generateTypeRef(structDefinition.type()),
+ components.stream().<JavaExpression>map(component -> new JavaRef(component.name())).toList()
+ ))
+ ))
+ ));
+
+ for (var component : components) {
+ body.add(new JavaMethodDeclaration(
+ "with" + lowerCamelCaseToUpperCamelCase(component.name()),
+ JavaMethodKind.INSTANCE,
+ builderJavaTypeRef,
+ List.of(
+ new JavaParam(component.type(), component.name())
+ ),
+ new JavaBlock(List.of(
+ new JavaReturn(new JavaNewExpression(
+ builderJavaTypeRef,
+ components.stream().<JavaExpression>map(argComponent -> new JavaRef(argComponent.name())).toList()
+ ))
+ ))
+ ));
+ }
+
+ return new JavaRecordDeclaration(
+ BUILDER_TYPE_NAME,
+ components,
+ List.of(),
+ body,
+ DocComment.EMPTY
+ );
+ }
+
private ArrayList<String> namespaceToJavaPackageParts(NamespaceName namespaceName) {
var packageParts = new ArrayList<>(this.packageName);
packageParts.addAll(namespaceName.parts());
@@ -210,6 +236,10 @@ public class JavaTypesGenerator implements Generator {
};
}
+ private JavaTypeRef generateBuilderTypeRef(StructType type) {
+ var javaPackage = namespaceToJavaPackageParts(type.namespaceName());
+ return JavaTypeRef.inner(javaPackage, type.name(), BUILDER_TYPE_NAME);
+ }
private JavaExpression arbitraryValue(
TypedTypeLevelExpressionNode<Type> type,
@@ -262,6 +292,10 @@ public class JavaTypesGenerator implements Generator {
};
}
+ private String lowerCamelCaseToUpperCamelCase(String name) {
+ return name.substring(0, 1).toUpperCase(Locale.ROOT) + name.substring(1);
+ }
+
private static class Context {
private final TypesInfo typesInfo;