diff options
5 files changed, 82 insertions, 7 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java index 732a533..be8d30a 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java @@ -45,13 +45,22 @@ public class JavaGenerator { } public JavaTypeRef generateTypeRef(Type type) { + return this.generateTypeRef(type, false); + } + + public JavaTypeRef generateReferenceTypeRef(Type type) { + return this.generateTypeRef(type, true); + } + + private JavaTypeRef generateTypeRef(Type type, boolean referenceType) { return switch (type) { case ConstructedNativeType constructedNativeType -> { var innerTypeRef = generateTypeRef( - constructedNativeType.constructor().genericType() + constructedNativeType.constructor().genericType(), + referenceType ); var javaArgs = constructedNativeType.args().stream() - .map(arg -> JavaTypeArg.invariant(generateTypeRef(arg))) + .map(arg -> JavaTypeArg.invariant(generateTypeRef(arg, true))) .toList(); // TODO: separate type for constructed types? yield JavaTypeRef.generic(innerTypeRef.packageName(), innerTypeRef.typeNames(), javaArgs); @@ -60,7 +69,12 @@ public class JavaGenerator { case SimpleNativeType simpleNativeType -> { var nativeTypeConfig = this.config.nativeTypeConfig(simpleNativeType); if (nativeTypeConfig.isPresent()) { - yield nativeTypeConfig.get().javaTypeRef(); + if (referenceType) { + yield nativeTypeConfig.get().javaBoxedTypeRef() + .orElse(nativeTypeConfig.get().javaTypeRef()); + } else { + yield nativeTypeConfig.get().javaTypeRef(); + } } else { throw new UnsupportedOperationException("TODO: " + type.describe()); } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGeneratorConfig.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGeneratorConfig.java index 4f2fe07..742ded7 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGeneratorConfig.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGeneratorConfig.java @@ -61,7 +61,7 @@ public record JavaGeneratorConfig( var javaTypeParts = Arrays.asList(javaTypeString.split("\\.")); var javaTypeRef = JavaTypeRef.topLevel(javaTypeParts.subList(0, javaTypeParts.size() - 1), javaTypeParts.getLast()); - nativeTypeConfigs.put(hobgoblinType, new JavaNativeTypeConfig(javaTypeRef, Optional.empty())); + nativeTypeConfigs.put(hobgoblinType, new JavaNativeTypeConfig(javaTypeRef, Optional.empty(), Optional.empty())); } }); @@ -69,7 +69,7 @@ public record JavaGeneratorConfig( } private static final Map<SimpleNativeType, JavaNativeTypeConfig> DEFAULT_NATIVE_TYPE_CONFIGS = Map.ofEntries( - Map.entry(NativeTypes.INT_32, JavaNativeTypeConfig.of(JavaTypeRef.INT, new JavaIntegerLiteral(0))), + Map.entry(NativeTypes.INT_32, JavaNativeTypeConfig.primitive(JavaTypeRef.INT, JavaTypeRef.INT_BOXED, new JavaIntegerLiteral(0))), Map.entry(NativeTypes.STRING, JavaNativeTypeConfig.of(JavaTypeRef.STRING, new JavaStringLiteral(""))), Map.entry(NativeTypes.LIST_INNER, JavaNativeTypeConfig.of(JavaTypeRef.LIST, new JavaStaticMethodCall(JavaTypeRef.LIST, "of", List.of()))) ); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaNativeTypeConfig.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaNativeTypeConfig.java index 54e99b2..768dcbd 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaNativeTypeConfig.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaNativeTypeConfig.java @@ -7,9 +7,14 @@ import java.util.Optional; public record JavaNativeTypeConfig( JavaTypeRef javaTypeRef, + Optional<JavaTypeRef> javaBoxedTypeRef, Optional<JavaExpression> arbitraryValue ) { public static JavaNativeTypeConfig of(JavaTypeRef javaTypeRef, JavaExpression arbitraryValue) { - return new JavaNativeTypeConfig(javaTypeRef, Optional.of(arbitraryValue)); + return new JavaNativeTypeConfig(javaTypeRef, Optional.empty(), Optional.of(arbitraryValue)); + } + + public static JavaNativeTypeConfig primitive(JavaTypeRef javaTypeRef, JavaTypeRef javaBoxedTypeRef, JavaExpression arbitraryValue) { + return new JavaNativeTypeConfig(javaTypeRef, Optional.of(javaBoxedTypeRef), Optional.of(arbitraryValue)); } } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java index ab15e64..f592aa7 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java @@ -177,7 +177,7 @@ public class JavaPreciselyMatchersGenerator implements Generator { List.of(), new JavaBlock(List.of( new JavaReturn(new JavaStaticMethodCall( - JavaTypeRef.topLevel(PRECISELY_PACKAGE_NAME, "Matchers"), + MATCHERS_REF, "instanceOf", List.of( new JavaStaticFieldAccess(javaStructTypeRef, "class"), @@ -188,6 +188,58 @@ public class JavaPreciselyMatchersGenerator implements Generator { ) )); + for (var field : structDefinition.fields()) { + var fieldType = field.type().value(); + var javaFieldTypeRef = this.javaGenerator.generateReferenceTypeRef(fieldType); + methods.add(new JavaMethodDeclaration( + "with" + lowerCamelCaseToUpperCamelCase(field.name()), + JavaVisibility.PUBLIC, + JavaMethodKind.INSTANCE, + javaMatcherTypeRef, + List.of( + new JavaParam(matcherRef(JavaTypeArg.superType(javaFieldTypeRef)), field.name()) + ), + new JavaBlock(List.of( + // TODO: avoid using Java streams here + new JavaReturn(new JavaNewExpression( + javaMatcherTypeRef, + List.of( + new JavaMethodCall( + new JavaStaticMethodCall( + JavaTypeRef.STREAM, + "concat", + List.of( + new JavaMethodCall( + new JavaFieldAccess(new JavaRef("this"), "submatchers"), + "stream", + List.of() + ), + new JavaStaticMethodCall( + JavaTypeRef.STREAM, + "of", + List.of( + new JavaStaticMethodCall( + MATCHERS_REF, + "has", + List.of( + new JavaStringLiteral(field.name()), + new JavaMethodRef(javaStructTypeRef, field.name()), + new JavaRef(field.name()) + ) + ) + ) + ) + ) + ), + "toList", + List.of() + ) + ) + )) + )) + )); + } + return new JavaClassDeclaration( matcherTypeName, List.of( @@ -230,6 +282,7 @@ public class JavaPreciselyMatchersGenerator implements Generator { private static final List<String> PRECISELY_PACKAGE_NAME = List.of("org", "zwobble", "precisely"); private static final JavaTypeRef MATCH_RESULT_REF = JavaTypeRef.topLevel(PRECISELY_PACKAGE_NAME, "MatchResult"); + private static final JavaTypeRef MATCHERS_REF = JavaTypeRef.topLevel(PRECISELY_PACKAGE_NAME, "Matchers"); private static JavaTypeRef matcherRef(JavaTypeRef arg) { return matcherRef(JavaTypeArg.invariant(arg)); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java index 9986768..8f4ea1b 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java @@ -33,6 +33,7 @@ public record JavaTypeRef(List<String> packageName, List<String> typeNames, List } public static final JavaTypeRef INT = primitive("int"); + public static final JavaTypeRef INT_BOXED = topLevel(List.of("java", "lang"), "Integer"); public static final JavaTypeRef LONG = primitive("long"); public static final JavaTypeRef STRING = primitive("String"); public static final JavaTypeRef VOID = primitive("void"); @@ -48,4 +49,6 @@ public record JavaTypeRef(List<String> packageName, List<String> typeNames, List } public static final JavaTypeRef OBJECT = topLevel(List.of("java", "lang"), "Object"); + + public static final JavaTypeRef STREAM = topLevel(List.of("java", "util", "stream"), "Stream"); } |
