aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-09-28 11:57:36 +0100
committerMichael Williamson <mike@zwobble.org>2023-09-28 11:57:36 +0100
commitb1ca0653b7bd80302a287faef3a7c7647f92d23a (patch)
tree4c5d219f68d8b3d9f4e9e4d6a575d8e4fd1f121f /src/test/java
parenta409b4f6576980f876ec880ddf24dadc5d418c58 (diff)
Define struct type info earlier
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java9
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java35
2 files changed, 43 insertions, 1 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 a21e3375..7bd1402d 100644
--- a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
+++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
@@ -83,6 +83,15 @@ public class TypedNodeMatchers {
);
}
+ public static Matcher<TypedExpressionNode> isTypedExpressionNode(
+ Type type
+ ) {
+ return instanceOf(
+ TypedExpressionNode.class,
+ has("type", x -> x.type(), equalTo(type))
+ );
+ }
+
public static Matcher<TypedFunctionStatementNode> isTypedExpressionStatementNode(
Matcher<TypedExpressionNode> expression
) {
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java
index 5a081076..226769bf 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java
@@ -324,7 +324,7 @@ public class TypeCheckerNamespaceTests {
}
@Test
- public void functionCanUseTypeDefinedLater() {
+ public void functionSignatureCanUseTypeDefinedLater() {
var untyped = Untyped.namespace(NamespaceName.of("Example", "Project"), List.of(
UntypedFunctionDefinitionNode.builder()
.withName("printUser")
@@ -362,6 +362,39 @@ public class TypeCheckerNamespaceTests {
}
@Test
+ public void functionBodyCanAccessFieldOnTypeDefinedLater() {
+ var untyped = Untyped.namespace(NamespaceName.of("Example", "Project"), List.of(
+ UntypedFunctionDefinitionNode.builder()
+ .withName("printUser")
+ .addPositionalParam("user", Untyped.typeLevelReference("User"))
+ .withReturnType(Untyped.typeLevelReference("Unit"))
+ .addStatement(Untyped.expressionStatement(Untyped.fieldAccess(Untyped.reference("user"), "name")))
+ .build(),
+ UntypedStructDefinitionNode.builder()
+ .withName("User")
+ .addField(Untyped.structFieldDefinition("name", Untyped.typeLevelReference("String")))
+ .build()
+ ));
+ var context = TypeCheckerContext.EMPTY
+ .enterGlobal(P.map(Map.entry("String", Types.metaType(Types.STRING))))
+ .enterGlobal(P.map(Map.entry("Unit", Types.metaType(Types.UNIT))));
+
+ var result = TypeChecker.typeCheckNamespace(untyped, context);
+
+ assertThat(
+ result.value(),
+ isTypedNamespaceNode()
+ .withBody(isSequence(
+ isTypedFunctionDefinitionNode()
+ .withBody(isTypedBlockNode(isSequence(
+ isTypedExpressionStatementNode(isTypedExpressionNode(Types.STRING))
+ ))),
+ isTypedStructDefinitionNode()
+ ))
+ );
+ }
+
+ @Test
public void structsCanHaveMutuallyRecursiveFields() {
var namespaceName = NamespaceName.of("Example", "Project");
var untyped = Untyped.namespace(namespaceName, List.of(