aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-12-25 12:05:46 +0000
committerMichael Williamson <mike@zwobble.org>2023-12-25 12:07:37 +0000
commit854545383ef1145223c181127a40a9a2cc2be638 (patch)
treef5265b11a9620681523602393ba75acc6fbdaf59 /src/test/java
parent1c0b88e256de6b4ea1b0c34ad525dfdad471f5ee (diff)
Support field accesses on constructed types
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFieldAccessTests.java73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFieldAccessTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFieldAccessTests.java
index 427db10f..e555181b 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFieldAccessTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFieldAccessTests.java
@@ -7,6 +7,7 @@ import org.shedlang.compiler.typechecker.errors.NoSuchFieldError;
import org.shedlang.compiler.types.*;
import org.shedlang.compiler.util.P;
+import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -44,6 +45,78 @@ public class TypeCheckerFieldAccessTests {
}
@Test
+ public void canAccessFieldWithFixedTypeOnConstructedStructType() {
+ var untyped = Untyped.fieldAccess(
+ Untyped.reference("x"),
+ "size"
+ );
+ var genericType = Types.struct(NamespaceName.of("Example"), "List");
+ var typeConstructor = Types.typeConstructor(
+ List.of(TypeParam.forStructType(genericType, "T")),
+ genericType
+ );
+ var constructedType = Types.constructedType(
+ typeConstructor,
+ List.of(Types.STRING)
+ );
+ var structTypeInfo = StructTypeInfo.builder()
+ .addField("size", Types.INT)
+ .build();
+ var context = TypeCheckerContext.EMPTY
+ .enterGlobal(P.map(Map.entry("x", constructedType)))
+ .addStructTypeInfo(genericType, structTypeInfo);
+
+ var typed = typeCheckExpression(untyped, context);
+
+ assertThat(
+ typed.value(),
+ isTypedFieldAccessNode(
+ isTypedReferenceNode("x", constructedType),
+ "size",
+ Types.INT
+ )
+ );
+ }
+
+ @Test
+ public void canAccessFieldWithGenericTypeOnConstructedStructType() {
+ var untyped = Untyped.fieldAccess(
+ Untyped.reference("x"),
+ "value"
+ );
+ var genericType = Types.struct(NamespaceName.of("Example"), "Box");
+ var typeConstructor = Types.typeConstructor(
+ List.of(
+ TypeParam.forStructType(genericType, "T1"),
+ TypeParam.forStructType(genericType, "T2"),
+ TypeParam.forStructType(genericType, "T3")
+ ),
+ genericType
+ );
+ var constructedType = Types.constructedType(
+ typeConstructor,
+ List.of(Types.INT, Types.STRING, Types.BOOL)
+ );
+ var structTypeInfo = StructTypeInfo.builder()
+ .addField("value", TypeParam.forStructType(genericType, "T2"))
+ .build();
+ var context = TypeCheckerContext.EMPTY
+ .enterGlobal(P.map(Map.entry("x", constructedType)))
+ .addStructTypeInfo(genericType, structTypeInfo);
+
+ var typed = typeCheckExpression(untyped, context);
+
+ assertThat(
+ typed.value(),
+ isTypedFieldAccessNode(
+ isTypedReferenceNode("x", constructedType),
+ "value",
+ Types.STRING
+ )
+ );
+ }
+
+ @Test
public void canAccessFieldOnNamespaceType() {
var untyped = Untyped.fieldAccess(
Untyped.reference("Example"),