From 8d3e6ce5e6c77ff27e99f0f8ca0b22ff943b7d3f Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 28 Sep 2023 10:56:25 +0100 Subject: Check structs can have mutually recursive fields --- .../compiler/ast/typed/TypedNodeMatchers.java | 6 ++++ .../typechecker/TypeCheckerNamespaceTests.java | 39 ++++++++++++++++++++++ .../TypeCheckerStructDefinitionTests.java | 1 - 3 files changed, 45 insertions(+), 1 deletion(-) (limited to 'src/test/java') 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 e5b13e6c..259c3215 100644 --- a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java +++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java @@ -281,6 +281,12 @@ public class TypedNodeMatchers { ); } + public static Matcher> isTypedTypeLevelExpressionNode( + TypeLevelValue value + ) { + return has("value", x -> x.value(), equalTo(value)); + } + public static Matcher> isTypedTypeLevelReferenceNode( String name, Matcher value diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java index d8fdc3ee..5a081076 100644 --- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java +++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java @@ -361,6 +361,45 @@ public class TypeCheckerNamespaceTests { ); } + @Test + public void structsCanHaveMutuallyRecursiveFields() { + var namespaceName = NamespaceName.of("Example", "Project"); + var untyped = Untyped.namespace(namespaceName, List.of( + UntypedStructDefinitionNode.builder() + .withName("A") + .addField(Untyped.structFieldDefinition("b", Untyped.typeLevelReference("B"))) + .build(), + UntypedStructDefinitionNode.builder() + .withName("B") + .addField(Untyped.structFieldDefinition("a", Untyped.typeLevelReference("A"))) + .build() + )); + var context = TypeCheckerContext.EMPTY; + + var result = TypeChecker.typeCheckNamespace(untyped, context); + + assertThat( + result.value(), + isTypedNamespaceNode() + .withBody(isSequence( + isTypedStructDefinitionNode() + .withName("A") + .withFields(isSequence( + isTypedStructFieldDefinitionNode() + .withName("b") + .withType(isTypedTypeLevelExpressionNode(Types.struct(namespaceName, "B"))) + )), + isTypedStructDefinitionNode() + .withName("B") + .withFields(isSequence( + isTypedStructFieldDefinitionNode() + .withName("a") + .withType(isTypedTypeLevelExpressionNode(Types.struct(namespaceName, "A"))) + )) + )) + ); + } + @Test public void typesOfFieldsAreStored() { var namespaceName = NamespaceName.of("Example"); diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java index dc23fa1c..f8cb0fc5 100644 --- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java +++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java @@ -6,7 +6,6 @@ import org.shedlang.compiler.ast.untyped.Untyped; import org.shedlang.compiler.ast.untyped.UntypedNamespaceStatementNode; import org.shedlang.compiler.ast.untyped.UntypedStructDefinitionNode; import org.shedlang.compiler.types.NamespaceName; -import org.shedlang.compiler.types.StructType; import org.shedlang.compiler.types.Types; import org.shedlang.compiler.util.P; -- cgit v1.2.3