diff options
Diffstat (limited to 'src')
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 { +} |
