aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-12-23 20:47:17 +0000
committerMichael Williamson <mike@zwobble.org>2023-12-23 20:47:17 +0000
commit66e07897524bf6239eb154c8d548c75bd74c82d0 (patch)
tree10a3696985bbe62bbc3abfe04a961cc85a9fea55 /src/test/java
parent8a1f0a3f0ecba5a33eb8eacfb16c08461ff974dd (diff)
Use type params in struct fields
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java50
-rw-r--r--src/test/java/org/shedlang/compiler/types/TypeMatchers.java5
2 files changed, 53 insertions, 2 deletions
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<TypeParam> isStructTypeLevelParam(
+ public static Matcher<Type> 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))