summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-05-18 23:59:45 +0100
committerMichael Williamson <mike@zwobble.org>2026-05-18 23:59:45 +0100
commit2cf8b4009dac7c076f794911b6c29741d78eb191 (patch)
treefcaffa71e17b2d24f8f41e957dfefb7afe17b200 /src/main
parent1d80b1c242ef4188deac4921e6e67bd91ba6708f (diff)
Add static arbitrary methods to create builders
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java84
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java34
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaExpression.java2
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaMethodCall.java10
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaStaticMethodCall.java10
5 files changed, 134 insertions, 6 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 0b49d87..44eb44b 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
@@ -1,10 +1,7 @@
package org.zwobble.hobgoblin.compiler.output.generators.javatypes;
import org.zwobble.hobgoblin.compiler.ast.DocComment;
-import org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceNode;
-import org.zwobble.hobgoblin.compiler.ast.typed.TypedStructDefinitionNode;
-import org.zwobble.hobgoblin.compiler.ast.typed.TypedSumDefinitionNode;
-import org.zwobble.hobgoblin.compiler.ast.typed.TypedTypeLevelExpressionNode;
+import org.zwobble.hobgoblin.compiler.ast.typed.*;
import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
import org.zwobble.hobgoblin.compiler.config.OutputConfig;
import org.zwobble.hobgoblin.compiler.output.CodeWriter;
@@ -103,6 +100,8 @@ 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()),
@@ -114,13 +113,32 @@ public class JavaTypesGenerator implements Generator {
.map(this::generateTypeRef)
.toList();
+ var builderTypeName = "Builder";
+ var builderJavaTypeRef = JavaTypeRef.inner(javaPackage, structDefinition.name(), builderTypeName);
+
+ var arbitraryComponentValues = structDefinition.fields().stream()
+ .map(field -> arbitraryValue(field.type(), context))
+ .toList();
+
return new JavaRecordDeclaration(
structDefinition.name(),
components,
implementsTypes,
List.of(
+ new JavaMethodDeclaration(
+ "arbitrary",
+ JavaMethodKind.STATIC,
+ builderJavaTypeRef,
+ List.of(),
+ new JavaBlock(List.of(
+ new JavaReturn(new JavaNewExpression(
+ builderJavaTypeRef,
+ arbitraryComponentValues
+ ))
+ ))
+ ),
new JavaRecordDeclaration(
- "Builder",
+ builderTypeName,
components,
List.of(),
List.of(
@@ -192,6 +210,58 @@ public class JavaTypesGenerator implements Generator {
};
}
+
+ private JavaExpression arbitraryValue(
+ TypedTypeLevelExpressionNode<Type> type,
+ Context context
+ ) {
+ return arbitraryValue(type.value(), context);
+ }
+
+ private JavaExpression arbitraryValue(Type type, Context context) {
+ return switch (type) {
+ case ConstructedNativeType constructedNativeType -> {
+ if (constructedNativeType.constructor().equals(NativeTypes.LIST)) {
+ yield new JavaStaticMethodCall(
+ JavaTypeRef.topLevel(List.of("java.util"), "List"),
+ "of",
+ List.of()
+ );
+ } else {
+ throw new UnsupportedOperationException("TODO");
+ }
+ }
+
+ case SimpleNativeType simpleNativeType -> {
+ if (type.equals(NativeTypes.INT_32)) {
+ yield new JavaIntegerLiteral(0);
+ } else {
+ throw new UnsupportedOperationException("TODO");
+ }
+ }
+
+ case StructType structType -> {
+ yield new JavaMethodCall(
+ new JavaStaticMethodCall(generateTypeRef(structType), "arbitrary", List.of()),
+ "build",
+ List.of()
+ );
+ }
+
+ case SumType sumType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case TypeLevelValueType typeLevelValueType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case TypeParam typeParam -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+ };
+ }
+
private static class Context {
private final TypesInfo typesInfo;
@@ -199,6 +269,10 @@ public class JavaTypesGenerator implements Generator {
this.typesInfo = typesInfo;
}
+ public List<Field> fieldsOf(StructType type) {
+ return this.typesInfo.fieldsOf(type);
+ }
+
public List<SumType> variantOf(StructType type) {
return this.typesInfo.variantOf(type);
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java
index 3711837..89c3aa0 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java
@@ -109,6 +109,10 @@ public class JavaWriter implements AutoCloseable {
writeIntegerLiteral(integerLiteral);
}
+ case JavaMethodCall methodCall -> {
+ writeMethodCall(methodCall);
+ }
+
case JavaNewExpression newExpression -> {
writeNewExpression(newExpression);
}
@@ -116,6 +120,10 @@ public class JavaWriter implements AutoCloseable {
case JavaRef ref -> {
writeRef(ref);
}
+
+ case JavaStaticMethodCall staticMethodCall -> {
+ writeStaticMethodCall(staticMethodCall);
+ }
}
}
@@ -145,6 +153,19 @@ public class JavaWriter implements AutoCloseable {
this.writer.write("}");
}
+ private void writeMethodCall(JavaMethodCall call) throws IOException {
+ this.writeExpression(call.receiver());
+ this.writer.write(".");
+ this.writer.write(call.methodName());
+ this.writer.write("(");
+ this.writeWithSeparator(
+ call.args(),
+ this::writeExpression,
+ () -> this.writer.write(", ")
+ );
+ this.writer.write(")");
+ }
+
void writeMethodDeclaration(JavaMethodDeclaration method) throws IOException {
this.writer.write("public ");
switch (method.kind()) {
@@ -250,6 +271,19 @@ public class JavaWriter implements AutoCloseable {
this.writer.write(";");
}
+ private void writeStaticMethodCall(JavaStaticMethodCall call) throws IOException {
+ this.writeTypeRef(call.type());
+ this.writer.write(".");
+ this.writer.write(call.methodName());
+ this.writer.write("(");
+ this.writeWithSeparator(
+ call.args(),
+ this::writeExpression,
+ () -> this.writer.write(", ")
+ );
+ this.writer.write(")");
+ }
+
void writeTypeRef(JavaTypeRef type) throws IOException {
for (var part : type.packageName()) {
writer.write(part);
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaExpression.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaExpression.java
index 03d54dd..63ee145 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaExpression.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaExpression.java
@@ -1,4 +1,4 @@
package org.zwobble.hobgoblin.compiler.output.lang.java.ast;
-public sealed interface JavaExpression permits JavaIntegerLiteral, JavaNewExpression, JavaRef {
+public sealed interface JavaExpression permits JavaIntegerLiteral, JavaMethodCall, JavaNewExpression, JavaRef, JavaStaticMethodCall {
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaMethodCall.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaMethodCall.java
new file mode 100644
index 0000000..6ec7caf
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaMethodCall.java
@@ -0,0 +1,10 @@
+package org.zwobble.hobgoblin.compiler.output.lang.java.ast;
+
+import java.util.List;
+
+public record JavaMethodCall(
+ JavaExpression receiver,
+ String methodName,
+ List<JavaExpression> args
+) implements JavaExpression {
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaStaticMethodCall.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaStaticMethodCall.java
new file mode 100644
index 0000000..ec12861
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaStaticMethodCall.java
@@ -0,0 +1,10 @@
+package org.zwobble.hobgoblin.compiler.output.lang.java.ast;
+
+import java.util.List;
+
+public record JavaStaticMethodCall(
+ JavaTypeRef type,
+ String methodName,
+ List<JavaExpression> args
+) implements JavaExpression {
+}