diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-06-13 21:12:20 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-06-13 21:12:20 +0100 |
| commit | 13d7693f7d9c302f30f874109a446d9171e1f3a8 (patch) | |
| tree | ceb334bc87521554537438b5e70d5f00c959b1b8 | |
| parent | e96e21b6a5a75dfa9a801d969d3e8f91aa17fe87 (diff) | |
Type check fields on sum definition
| -rw-r--r-- | src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java | 4 | ||||
| -rw-r--r-- | src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java | 64 |
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) + )) + ) + ) + ) + )); + } } |
