From aa397d67f7948d2ee0c89310147390eb0e288a73 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 3 Jul 2026 12:27:06 +0100 Subject: Add Java builder methods when field is option --- .../compiler/ast/untyped/UntypedImportNode.java | 4 ++ .../generators/javatypes/JavaTypesGenerator.java | 64 ++++++++++++++++++++++ .../lang/java/ast/JavaMethodDeclaration.java | 8 +++ .../output/lang/rust/ast/RustBlockExpression.java | 8 +++ .../output/lang/rust/ast/RustFunction.java | 8 +++ .../output/lang/rust/ast/RustTypePathSegment.java | 4 ++ .../compiler/output/lang/rust/RustWriterTests.java | 4 +- 7 files changed, 98 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedImportNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedImportNode.java index b500912..71e57db 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedImportNode.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedImportNode.java @@ -29,6 +29,10 @@ public record UntypedImportNode(java.util.List importedNames, java.util. return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder(importedNames, ancestorDepth, namespaceName, source); } + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder withAncestorDepth(int ancestorDepth) { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder(importedNames, java.util.Optional.of(ancestorDepth), namespaceName, source); + } + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder withNamespaceName(org.zwobble.hobgoblin.compiler.types.NamespaceName namespaceName) { return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder(importedNames, ancestorDepth, namespaceName, source); } 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 c01a31f..1aa88b2 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 @@ -341,6 +341,70 @@ public class JavaTypesGenerator implements Generator { } } + if ( + field.type().value() instanceof ConstructedNativeType fieldConstructedNativeType && + fieldConstructedNativeType.constructor().equals(NativeTypes.OPTION) + ) { + var elementType = fieldConstructedNativeType.args().getFirst(); + var javaElementType = generateTypeRef(elementType, context); + + methods.add(new JavaMethodDeclaration( + withMethodName, + JavaVisibility.PUBLIC, + JavaMethodKind.INSTANCE, + builderJavaTypeRef, + List.of( + new JavaParam(javaElementType, javaFieldName) + ), + new JavaBlock(List.of( + new JavaReturn(new JavaNewExpression( + builderJavaTypeRef, + components.stream().map(argComponent -> { + if (argComponent.name().equals(javaFieldName)) { + return new JavaStaticMethodCall( + JavaTypeRef.OPTIONAL, + JavaIdentifier.of("of"), + List.of(new JavaRef(javaFieldName)) + ); + } else { + return new JavaRef(argComponent.name()); + } + }).toList() + )) + )) + )); + + var elementBuilderTypeRef = generateBuilderTypeRef(elementType); + + if (elementBuilderTypeRef.isPresent()) { + methods.add(new JavaMethodDeclaration( + withMethodName, + JavaVisibility.PUBLIC, + JavaMethodKind.INSTANCE, + builderJavaTypeRef, + List.of( + new JavaParam(elementBuilderTypeRef.get(), javaFieldName) + ), + new JavaBlock(List.of( + new JavaReturn(new JavaNewExpression( + builderJavaTypeRef, + components.stream().map(argComponent -> { + if (argComponent.name().equals(javaFieldName)) { + return new JavaStaticMethodCall( + JavaTypeRef.OPTIONAL, + JavaIdentifier.of("of"), + List.of(new JavaMethodCall(new JavaRef(javaFieldName), BUILD_METHOD_NAME, List.of())) + ); + } else { + return new JavaRef(argComponent.name()); + } + }).toList() + )) + )) + )); + } + } + return methods; } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaMethodDeclaration.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaMethodDeclaration.java index 617a7e1..b3f7057 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaMethodDeclaration.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaMethodDeclaration.java @@ -55,6 +55,14 @@ public record JavaMethodDeclaration(org.zwobble.hobgoblin.compiler.output.lang.j return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaMethodDeclaration.Builder(name, visibility, kind, returnType, params, body); } + public org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaMethodDeclaration.Builder withBody(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaBlock body) { + return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaMethodDeclaration.Builder(name, visibility, kind, returnType, params, java.util.Optional.of(body)); + } + + public org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaMethodDeclaration.Builder withBody(org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaBlock.Builder body) { + return new org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaMethodDeclaration.Builder(name, visibility, kind, returnType, params, java.util.Optional.of(body.build())); + } + // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaMethodDeclaration.Builder body // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.java.ast.JavaMethodDeclaration.Builder body } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustBlockExpression.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustBlockExpression.java index 794290d..8dc7e69 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustBlockExpression.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustBlockExpression.java @@ -35,6 +35,14 @@ public record RustBlockExpression(java.util.List args) { + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder(pathIdentSegment, java.util.Optional.of(args)); + } + // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder body // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTypePathSegment.Builder body } diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java index 33c1fe4..c74f83b 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java @@ -294,7 +294,7 @@ public class RustWriterTests { @Test public void blockExpressionWithNoStatementsAndFinalOperand() throws IOException { var rust = RustBlockExpression.arbitrary() - .withFinalOperand(Optional.of(RustBoolLiteral.arbitrary().withValue(true).build())) + .withFinalOperand(RustBoolLiteral.arbitrary().withValue(true)) .build(); var string = write(writer -> writer.writeExpression(rust)); @@ -314,7 +314,7 @@ public class RustWriterTests { .addStatement(RustExpressionStatement.arbitrary() .withExpression(RustBoolLiteral.arbitrary().withValue(false)) ) - .withFinalOperand(Optional.of(RustBoolLiteral.arbitrary().withValue(true).build())) + .withFinalOperand(RustBoolLiteral.arbitrary().withValue(true)) .build(); var string = write(writer -> writer.writeExpression(rust)); -- cgit v1.2.3