From 66e07897524bf6239eb154c8d548c75bd74c82d0 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 23 Dec 2023 20:47:17 +0000 Subject: Use type params in struct fields --- .../TypeCheckerStructDefinitionTests.java | 50 ++++++++++++++++++++++ .../org/shedlang/compiler/types/TypeMatchers.java | 5 ++- 2 files changed, 53 insertions(+), 2 deletions(-) (limited to 'src/test/java') diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java index 497a3869..76d399db 100644 --- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java +++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java @@ -196,4 +196,54 @@ public class TypeCheckerStructDefinitionTests { )) ); } + + @Test + public void typeParamsCanBeUsedInFieldTypes() { + var untyped = UntypedStructDefinitionNode.builder() + .withName("ExampleStruct") + .withTypeLevelParams(List.of( + Untyped.typeLevelParam("T1"), + Untyped.typeLevelParam("T2") + )) + .addField(Untyped.structFieldDefinition("x1", Untyped.typeLevelReference("T1"))) + .addField(Untyped.structFieldDefinition("x2", Untyped.typeLevelReference("T2"))) + .build(); + var context = TypeCheckerContext.EMPTY + .enterGlobal(P.map()); + + var typed = typeCheckNamespaceStatement(untyped, context); + + var structTypeInfo = typed.context().toTypeInfos() + .structTypeInfo(Types.struct(NAMESPACE_NAME, "ExampleStruct")) + .orElseThrow(); + assertThat( + structTypeInfo, + has("fields", x -> x.fields(), isSequence( + allOf( + has("name", x -> x.name(), equalTo("x1")), + has("type", x -> x.type(), isStructTypeLevelParam(NAMESPACE_NAME, "ExampleStruct", "T1")) + ), + allOf( + has("name", x -> x.name(), equalTo("x2")), + has("type", x -> x.type(), isStructTypeLevelParam(NAMESPACE_NAME, "ExampleStruct", "T2")) + ) + )) + ); + } + + @Test + public void typeParamsCannotBeUsedAfterStructDefinition() { + var untyped = UntypedStructDefinitionNode.builder() + .withName("ExampleStruct") + .withTypeLevelParams(List.of( + Untyped.typeLevelParam("T1") + )) + .build(); + var context = TypeCheckerContext.EMPTY + .enterGlobal(P.map()); + + var typed = typeCheckNamespaceStatement(untyped, context); + + assertThat(typed.context().compileTimeLookup("T1"), isOptionalEmpty()); + } } diff --git a/src/test/java/org/shedlang/compiler/types/TypeMatchers.java b/src/test/java/org/shedlang/compiler/types/TypeMatchers.java index 7f0e9faa..b52bbdff 100644 --- a/src/test/java/org/shedlang/compiler/types/TypeMatchers.java +++ b/src/test/java/org/shedlang/compiler/types/TypeMatchers.java @@ -29,12 +29,13 @@ public class TypeMatchers { ); } - public static Matcher isStructTypeLevelParam( + public static Matcher isStructTypeLevelParam( NamespaceName namespaceName, String structName, String paramName ) { - return allOf( + return instanceOf( + TypeParam.class, has("scope", x -> x.scope(), instanceOf( Scope.Struct.class, has("type", x -> x.type(), isStructType(namespaceName, structName)) -- cgit v1.2.3