summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/analysis/ArbitraryValueAnalysis.java60
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java54
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);
}