diff options
Diffstat (limited to 'src/main/java/org')
2 files changed, 52 insertions, 2 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTypeLevelExpressionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTypeLevelExpressionNode.java index c2e484c..67f56e6 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTypeLevelExpressionNode.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTypeLevelExpressionNode.java @@ -1,6 +1,6 @@ package org.zwobble.hobgoblin.compiler.ast.untyped; -public sealed interface UntypedTypeLevelExpressionNode permits org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedConstructedTypeNode { +public sealed interface UntypedTypeLevelExpressionNode permits org.zwobble.hobgoblin.compiler.ast.untyped.UntypedConstructedTypeNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode { public interface Builder { public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelExpressionNode build(); 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 6e09b7d..653da8d 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 @@ -408,7 +408,7 @@ public class JavaTypesGenerator implements Generator { } case SumType sumType -> { - var firstVariant = context.variants(sumType).getFirst(); + var firstVariant = selectArbitraryVariant(sumType, context); yield arbitraryValue(firstVariant, context); } @@ -422,6 +422,52 @@ public class JavaTypesGenerator implements Generator { }; } + private Type selectArbitraryVariant(SumType sumType, Context context) { + var seenTypes = new HashSet<Type>(); + seenTypes.add(sumType); + // TODO: better error + return context.variants(sumType).stream() + .filter(variant -> isNonRecursivelyConstructable(variant, seenTypes, context)) + .findFirst() + .orElseThrow(); + } + + private boolean isNonRecursivelyConstructable(Type type, Set<Type> seenTypes, Context context) { + if (seenTypes.contains(type)) { + return false; + } + + return switch (type) { + case ConstructedNativeType constructedNativeType -> + true; + + case SimpleNativeType simpleNativeType -> + true; + + case StructType structType -> { + var newSeenTypes = new HashSet<>(seenTypes); + newSeenTypes.add(type); + var result = context.fieldsOf(structType).stream() + .allMatch(field -> isNonRecursivelyConstructable(field.type(), newSeenTypes, context)); + yield result; + } + + case SumType sumType -> { + var newSeenTypes = new HashSet<>(seenTypes); + newSeenTypes.add(type); + var result = context.variants(sumType).stream() + .anyMatch(variant -> isNonRecursivelyConstructable(variant, seenTypes, context)); + yield result; + } + + case TypeLevelValueType typeLevelValueType -> + false; + + case TypeParam typeParam -> + false; + }; + } + private String lowerCamelCaseToUpperCamelCase(String name) { return name.substring(0, 1).toUpperCase(Locale.ROOT) + name.substring(1); } @@ -437,6 +483,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); } |
