diff options
Diffstat (limited to 'src/main/java')
2 files changed, 62 insertions, 52 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/analysis/ArbitraryValueAnalysis.java b/src/main/java/org/zwobble/hobgoblin/compiler/analysis/ArbitraryValueAnalysis.java new file mode 100644 index 0000000..c1d7cc3 --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/analysis/ArbitraryValueAnalysis.java @@ -0,0 +1,60 @@ +package org.zwobble.hobgoblin.compiler.analysis; + +import org.zwobble.hobgoblin.compiler.typechecker.TypesInfo; +import org.zwobble.hobgoblin.compiler.types.*; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class ArbitraryValueAnalysis { + public static Type selectArbitraryVariant(SumType sumType, TypesInfo typesInfo) { + var seenTypes = new HashSet<Type>(); + seenTypes.add(sumType); + // TODO: better error + return typesInfo.sumVariants(sumType).stream() + .filter(variant -> isNonRecursivelyConstructable(variant.valueType(), seenTypes, typesInfo)) + .findFirst() + .orElseThrow() + .containerType(); + } + + private static boolean isNonRecursivelyConstructable(Type type, Set<Type> seenTypes, TypesInfo typesInfo) { + if (seenTypes.contains(type)) { + return false; + } + + return switch (type) { + case ConstructedNativeType constructedNativeType -> + // TODO: Handle Box and Shared + true; + + case EnumType enumType -> + true; + + case SimpleNativeType simpleNativeType -> + true; + + case StructType structType -> { + var newSeenTypes = new HashSet<>(seenTypes); + newSeenTypes.add(type); + var fields = typesInfo.fieldsOf(structType); + yield fields.orElse(List.of()).stream() + .allMatch(field -> isNonRecursivelyConstructable(field.type(), newSeenTypes, typesInfo)); + } + + case SumType sumType -> { + var newSeenTypes = new HashSet<>(seenTypes); + newSeenTypes.add(type); + yield typesInfo.sumVariants(sumType).stream() + .anyMatch(variant -> isNonRecursivelyConstructable(variant.valueType(), newSeenTypes, typesInfo)); + } + + case TypeLevelValueType typeLevelValueType -> + false; + + case TypeParam typeParam -> + false; + }; + } +} 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 f64370c..cd311d9 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 @@ -18,6 +18,7 @@ import java.io.IOException; import java.nio.file.Path; import java.util.*; +import static org.zwobble.hobgoblin.compiler.analysis.ArbitraryValueAnalysis.selectArbitraryVariant; import static org.zwobble.hobgoblin.compiler.util.Casing.lowerCamelCaseToUpperCamelCase; public class JavaTypesGenerator implements Generator { @@ -587,7 +588,7 @@ public class JavaTypesGenerator implements Generator { } case SumType sumType -> { - var firstVariant = selectArbitraryVariant(sumType, context); + var firstVariant = selectArbitraryVariant(sumType, context.typesInfo); yield arbitraryValue(firstVariant, context); } @@ -601,57 +602,6 @@ 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.sumVariants(sumType).stream() - .filter(variant -> isNonRecursivelyConstructable(variant.valueType(), seenTypes, context)) - .findFirst() - .orElseThrow() - .containerType(); - } - - private boolean isNonRecursivelyConstructable(Type type, Set<Type> seenTypes, Context context) { - if (seenTypes.contains(type)) { - return false; - } - - return switch (type) { - case ConstructedNativeType constructedNativeType -> - // TODO: Handle Box and Shared - true; - - case EnumType enumType -> - true; - - case SimpleNativeType simpleNativeType -> - true; - - case StructType structType -> { - var newSeenTypes = new HashSet<>(seenTypes); - newSeenTypes.add(type); - var fields = context.fieldsOf(structType); - yield fields.orElse(List.of()).stream() - .allMatch(field -> isNonRecursivelyConstructable(field.type(), newSeenTypes, context)); - } - - case SumType sumType -> { - var newSeenTypes = new HashSet<>(seenTypes); - newSeenTypes.add(type); - var result = context.sumVariants(sumType).stream() - .anyMatch(variant -> isNonRecursivelyConstructable(variant.valueType(), seenTypes, context)); - yield result; - } - - case TypeLevelValueType typeLevelValueType -> - false; - - case TypeParam typeParam -> - false; - }; - } - private JavaIdentifier generateEnumConstantName(String name) { return this.javaGenerator.generateEnumConstantName(name); } |
