summaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-08-09 22:06:17 +0100
committerMichael Williamson <mike@zwobble.org>2026-08-09 22:06:17 +0100
commit1e2d86b9d7f2f659f4c53f8543f7931ea81c5781 (patch)
tree53658f9c95fadabf8169b730c0de3d2dd54cd63c /src/test/java
parent4722db99dcc14457e505ee988c0622c65d4039cc (diff)
Type check generic struct definition
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java55
1 files changed, 44 insertions, 11 deletions
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java
index 9bdf9f8..91839f6 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java
@@ -5,13 +5,8 @@ import org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceNode;
import org.zwobble.hobgoblin.compiler.ast.typed.TypedStructDefinitionNode;
import org.zwobble.hobgoblin.compiler.ast.typed.TypedStructFieldDefinitionNode;
import org.zwobble.hobgoblin.compiler.ast.typed.TypedTypeLevelExpressionNode;
-import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedArb;
-import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNamespaceNode;
-import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStructDefinitionNode;
-import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStructFieldDefinitionNode;
-import org.zwobble.hobgoblin.compiler.types.NamespaceName;
-import org.zwobble.hobgoblin.compiler.types.SimpleNativeType;
-import org.zwobble.hobgoblin.compiler.types.SimpleStructType;
+import org.zwobble.hobgoblin.compiler.ast.untyped.*;
+import org.zwobble.hobgoblin.compiler.types.*;
import java.util.List;
import java.util.Optional;
@@ -23,7 +18,7 @@ import static org.zwobble.precisely.Matchers.*;
public class TypeCheckerStructDefinitionTests {
@Test
- public void structHasNamespaceFromContext() {
+ public void whenStructDefinitionHasNoTypeParamsThenNameIsBoundToType() {
var untyped = UntypedStructDefinitionNode.arbitrary()
.withName("X")
.build();
@@ -31,14 +26,52 @@ public class TypeCheckerStructDefinitionTests {
var typed = typeCheckNamespaceStatement(untyped, context);
+ var expectedType = new SimpleStructType(NamespaceName.of("a", "b"), "X");
assertThat(typed, instanceOf(
TypedStructDefinitionNode.class,
has(
- "type",
- TypedStructDefinitionNode::typeOrThrow,
- equalTo(new SimpleStructType(NamespaceName.of("a", "b"), "X"))
+ "typeOrConstructor",
+ TypedStructDefinitionNode::typeOrConstructor,
+ equalTo(TypeOrConstructor.type(expectedType))
)
));
+ assertThat(context.lookupType("X"), isOptionalOf(
+ equalTo(Types.metaType(expectedType))
+ ));
+ }
+
+ @Test
+ public void whenStructDefinitionHasTypeParamsThenNameIsBoundToTypeConstructor() {
+ var untyped = UntypedStructDefinitionNode.arbitrary()
+ .withName("X")
+ .withTypeParams(Optional.of(List.of(
+ UntypedTypeParamNode.arbitrary().withName("A").build(),
+ UntypedTypeParamNode.arbitrary().withName("B").build()
+ )))
+ .build();
+ var context = TypeCheckerContextArb.namespaceContext(NamespaceName.of("a", "b"));
+
+ var typed = typeCheckNamespaceStatement(untyped, context);
+
+ var expectedInnerType = new SimpleStructType(NamespaceName.of("a", "b"), "X");
+ var expectedTypeConstructor = Types.constructor(
+ List.of(
+ new TypeParam(expectedInnerType, "A"),
+ new TypeParam(expectedInnerType, "B")
+ ),
+ expectedInnerType
+ );
+ assertThat(typed, instanceOf(
+ TypedStructDefinitionNode.class,
+ has(
+ "typeOrConstructor",
+ TypedStructDefinitionNode::typeOrConstructor,
+ equalTo(TypeOrConstructor.constructor(expectedTypeConstructor))
+ )
+ ));
+ assertThat(context.lookupType("X"), isOptionalOf(
+ equalTo(Types.metaType(expectedTypeConstructor))
+ ));
}
@Test