From 854545383ef1145223c181127a40a9a2cc2be638 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Mon, 25 Dec 2023 12:05:46 +0000 Subject: Support field accesses on constructed types --- .../typechecker/TypeCheckerFieldAccessTests.java | 73 ++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'src/test/java') 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; @@ -43,6 +44,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( -- cgit v1.2.3