diff options
| -rw-r--r-- | src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java | 82 |
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; |
