aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-09-28 11:38:44 +0100
committerMichael Williamson <mike@zwobble.org>2023-09-28 11:39:24 +0100
commit6d9a2f0b07204debf78f70e3d1ed5078ee4e54c0 (patch)
tree529563c9b13c39ef4e40b2e05e7495005ecd1c33 /src/test/java
parent97daf07ea93e36b5be1db2a270dcdd5d8e25cec7 (diff)
Basic type checking for field access
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java13
-rw-r--r--src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java7
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFieldAccessTests.java44
3 files changed, 64 insertions, 0 deletions
diff --git a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
index 259c3215..a21e3375 100644
--- a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
+++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
@@ -92,6 +92,19 @@ public class TypedNodeMatchers {
);
}
+ public static Matcher<TypedExpressionNode> isTypedFieldAccessNode(
+ Matcher<TypedExpressionNode> receiver,
+ String fieldName,
+ Type type
+ ) {
+ return instanceOf(
+ TypedFieldAccessNode.class,
+ has("receiver", x -> x.receiver(), receiver),
+ has("fieldName", x -> x.fieldName(), equalTo(fieldName)),
+ has("type", x -> x.type(), equalTo(type))
+ );
+ }
+
public static TypedFunctionDefinitionNodeMatcher isTypedFunctionDefinitionNode() {
return TypedFunctionDefinitionNodeMatcher.empty();
}
diff --git a/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java b/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java
index dcdb9f46..6480af7b 100644
--- a/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java
+++ b/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java
@@ -84,6 +84,13 @@ public class Untyped {
return new UntypedExpressionStatementNode(expression, Sources.NULL);
}
+ public static UntypedExpressionNode fieldAccess(
+ UntypedExpressionNode receiver,
+ String fieldName
+ ) {
+ return new UntypedFieldAccessNode(receiver, fieldName, Sources.NULL);
+ }
+
public static UntypedFunctionReturnNode functionReturn(UntypedExpressionNode expression) {
return new UntypedFunctionReturnNode(expression, Sources.NULL);
}
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFieldAccessTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFieldAccessTests.java
new file mode 100644
index 00000000..f560cfce
--- /dev/null
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFieldAccessTests.java
@@ -0,0 +1,44 @@
+package org.shedlang.compiler.typechecker;
+
+import org.junit.jupiter.api.Test;
+import org.shedlang.compiler.ast.untyped.Untyped;
+import org.shedlang.compiler.ast.untyped.UntypedCallNode;
+import org.shedlang.compiler.typechecker.errors.*;
+import org.shedlang.compiler.typechecker.typesets.TypeSets;
+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;
+import static org.shedlang.compiler.ast.typed.TypedNodeMatchers.*;
+import static org.zwobble.precisely.AssertThat.assertThat;
+import static org.zwobble.precisely.Matchers.equalTo;
+import static org.zwobble.precisely.Matchers.isSequence;
+
+public class TypeCheckerFieldAccessTests {
+ @Test
+ public void canAccessFieldOnStructType() {
+ var untyped = Untyped.fieldAccess(
+ Untyped.reference("user"),
+ "name"
+ );
+ var structType = Types.struct(NamespaceName.of("Example"), "User");
+ var structTypeInfo = new StructTypeInfo(P.orderedPMap(Map.entry("name", Types.STRING)));
+ var context = TypeCheckerContext.EMPTY
+ .enterGlobal(P.map(Map.entry("user", structType)))
+ .addStructTypeInfo(structType, structTypeInfo);
+
+ var typed = TypeChecker.typeCheckExpression(untyped, context);
+
+ assertThat(
+ typed.value(),
+ isTypedFieldAccessNode(
+ isTypedReferenceNode("user", structType),
+ "name",
+ Types.STRING
+ )
+ );
+ }
+}