summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-06-13 21:12:20 +0100
committerMichael Williamson <mike@zwobble.org>2026-06-13 21:12:20 +0100
commit13d7693f7d9c302f30f874109a446d9171e1f3a8 (patch)
treeceb334bc87521554537438b5e70d5f00c959b1b8 /src
parente96e21b6a5a75dfa9a801d969d3e8f91aa17fe87 (diff)
Type check fields on sum definition
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java4
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java64
2 files changed, 59 insertions, 9 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
index 00c4b8d..650cecd 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
@@ -174,12 +174,14 @@ public class TypeChecker {
variantTypes.add(variantType.value());
}
+ var typeCheckedFieldDefinitions = typeCheckFieldDefinitions(untyped.fields(), context);
+
context.defineSumType(sumType, variantTypes);
return new TypedSumDefinitionNode(
sumType,
typedVariants,
- List.of(),
+ typeCheckedFieldDefinitions.typedFieldNodes,
untyped.docComment(),
untyped.source()
);
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java
index c3e7439..c93868b 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java
@@ -1,16 +1,12 @@
package org.zwobble.hobgoblin.compiler.typechecker;
import org.junit.jupiter.api.Test;
+import org.zwobble.hobgoblin.compiler.ast.typed.TypedStructFieldDefinitionNode;
import org.zwobble.hobgoblin.compiler.ast.typed.TypedSumDefinitionNode;
import org.zwobble.hobgoblin.compiler.ast.typed.TypedSumVariantDefinitionNode;
import org.zwobble.hobgoblin.compiler.ast.typed.TypedTypeLevelExpressionNode;
-import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedArb;
-import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedSumDefinitionNode;
-import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedSumVariantDefinitionNode;
-import org.zwobble.hobgoblin.compiler.types.NamespaceName;
-import org.zwobble.hobgoblin.compiler.types.StructType;
-import org.zwobble.hobgoblin.compiler.types.SumType;
-import org.zwobble.hobgoblin.compiler.types.TypeLevelValueType;
+import org.zwobble.hobgoblin.compiler.ast.untyped.*;
+import org.zwobble.hobgoblin.compiler.types.*;
import java.util.List;
@@ -62,7 +58,7 @@ public class TypeCheckerSumDefinitionTests {
assertThat(typed, instanceOf(
TypedSumDefinitionNode.class,
has(
- "fields",
+ "variants",
TypedSumDefinitionNode::variants,
isSequence(
has("type", TypedSumVariantDefinitionNode::type, has(
@@ -84,4 +80,56 @@ public class TypeCheckerSumDefinitionTests {
assertThat(typesInfo.variantOf(triangleType), isSequence(equalTo(sumType)));
assertThat(typesInfo.variants(sumType), isSequence(equalTo(rectangleType), equalTo(triangleType)));
}
+
+ @Test
+ public void fieldsAreTypeChecked() {
+ var int32Type = SimpleNativeType.builtin("Int32");
+ var int64Type = SimpleNativeType.builtin("Int64");
+ var untyped = UntypedSumDefinitionNode.arbitrary()
+ .withName("X")
+ .withFields(List.of(
+ UntypedStructFieldDefinitionNode.arbitrary()
+ .withName("x")
+ .withType(UntypedTypeLevelReferenceNode.arbitrary().withName("Int32"))
+ .build(),
+ UntypedStructFieldDefinitionNode.arbitrary()
+ .withName("y")
+ .withType(UntypedTypeLevelReferenceNode.arbitrary().withName("Int64"))
+ .build()
+ ))
+ .build();
+ var globalContext = TypeCheckerGlobalContext.initial();
+ globalContext.addNativeType(int32Type);
+ globalContext.addNativeType(int64Type);
+ var namespaceContext = globalContext
+ .enterNamespace(NamespaceName.of("a", "b"));
+
+ var typed = typeCheckNamespaceStatement(untyped, namespaceContext);
+
+ assertThat(typed, instanceOf(
+ TypedSumDefinitionNode.class,
+ has(
+ "fields",
+ TypedSumDefinitionNode::fields,
+ isSequence(
+ allOf(
+ has("name", TypedStructFieldDefinitionNode::name, equalTo("x")),
+ has("type", TypedStructFieldDefinitionNode::type, has(
+ "value",
+ TypedTypeLevelExpressionNode::value,
+ equalTo(int32Type)
+ ))
+ ),
+ allOf(
+ has("name", TypedStructFieldDefinitionNode::name, equalTo("y")),
+ has("type", TypedStructFieldDefinitionNode::type, has(
+ "value",
+ TypedTypeLevelExpressionNode::value,
+ equalTo(int64Type)
+ ))
+ )
+ )
+ )
+ ));
+ }
}