From 34b02197132f215f651bb3ee3d54b16cc2fc0836 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 28 Sep 2023 10:25:04 +0100 Subject: Type check struct definition fields --- .../compiler/ast/typed/TypedNodeMatchers.java | 4 ++ .../TypedStructFieldDefinitionNodeMatcher.java | 45 ++++++++++++++++++++++ .../org/shedlang/compiler/ast/untyped/Untyped.java | 7 ++++ .../TypeCheckerStructDefinitionTests.java | 36 ++++++++++++++++- 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/shedlang/compiler/ast/typed/TypedStructFieldDefinitionNodeMatcher.java (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 bc5da178..82221c08 100644 --- a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java +++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java @@ -225,6 +225,10 @@ public class TypedNodeMatchers { return TypedStructDefinitionNodeMatcher.empty(); } + public static TypedStructFieldDefinitionNodeMatcher isTypedStructFieldDefinitionNode() { + return TypedStructFieldDefinitionNodeMatcher.empty(); + } + public static Matcher isTypedTargetIgnore() { return instanceOf(TypedTargetNode.Ignore.class); } diff --git a/src/test/java/org/shedlang/compiler/ast/typed/TypedStructFieldDefinitionNodeMatcher.java b/src/test/java/org/shedlang/compiler/ast/typed/TypedStructFieldDefinitionNodeMatcher.java new file mode 100644 index 00000000..f8ba23ae --- /dev/null +++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedStructFieldDefinitionNodeMatcher.java @@ -0,0 +1,45 @@ +package org.shedlang.compiler.ast.typed; + +import org.pcollections.PVector; +import org.shedlang.compiler.testing.MatcherBuilder; +import org.shedlang.compiler.util.P; +import org.zwobble.precisely.Matcher; + +import static org.zwobble.precisely.Matchers.equalTo; +import static org.zwobble.precisely.Matchers.has; + +public class TypedStructFieldDefinitionNodeMatcher extends MatcherBuilder< + TypedStructFieldDefinitionNode, + TypedStructFieldDefinitionNode, + TypedStructFieldDefinitionNodeMatcher +> { + public static TypedStructFieldDefinitionNodeMatcher empty() { + return new TypedStructFieldDefinitionNodeMatcher(P.vector()); + } + + private TypedStructFieldDefinitionNodeMatcher(PVector> submatchers) { + super(submatchers); + } + + @Override + protected Class expectedType() { + return TypedStructFieldDefinitionNode.class; + } + + @Override + protected TypedStructFieldDefinitionNodeMatcher create( + PVector> submatchers + ) { + return new TypedStructFieldDefinitionNodeMatcher(submatchers); + } + + public TypedStructFieldDefinitionNodeMatcher withName(String name) { + return with(has("name", x -> x.name(), equalTo(name))); + } + + public TypedStructFieldDefinitionNodeMatcher withType( + Matcher> type + ) { + return with(has("type", x -> x.type(), type)); + } +} 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 a87b1c48..dcdb9f46 100644 --- a/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java +++ b/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java @@ -138,6 +138,13 @@ public class Untyped { return new UntypedStringLiteralNode(value, Sources.NULL); } + public static UntypedStructFieldDefinitionNode structFieldDefinition( + String name, + UntypedTypeLevelReferenceNode type + ) { + return new UntypedStructFieldDefinitionNode(name, type, Sources.NULL); + } + public static UntypedBinaryOperationNode sub( UntypedExpressionNode left, UntypedExpressionNode right diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java index ac361f79..c8bfd742 100644 --- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java +++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java @@ -2,11 +2,15 @@ package org.shedlang.compiler.typechecker; import org.junit.jupiter.api.Test; import org.shedlang.compiler.ast.typed.TypedNamespaceStatementNode; +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.Types; import org.shedlang.compiler.util.P; -import static org.shedlang.compiler.ast.typed.TypedNodeMatchers.isTypedStructDefinitionNode; +import java.util.Map; + +import static org.shedlang.compiler.ast.typed.TypedNodeMatchers.*; import static org.zwobble.precisely.AssertThat.assertThat; import static org.zwobble.precisely.Matchers.isSequence; @@ -28,6 +32,36 @@ public class TypeCheckerStructDefinitionTests { ); } + @Test + public void canTypeCheckStructDefinitionWithFields() { + var untyped = UntypedStructDefinitionNode.builder() + .withName("ExampleStruct") + .addField(Untyped.structFieldDefinition("b", Untyped.typeLevelReference("Bool"))) + .addField(Untyped.structFieldDefinition("a", Untyped.typeLevelReference("Int"))) + .build(); + var context = TypeCheckerContext.EMPTY + .enterGlobal(P.map( + Map.entry("Bool", Types.metaType(Types.BOOL)), + Map.entry("Int", Types.metaType(Types.INT)) + )); + + var typed = typeCheckNamespaceStatement(untyped, context); + + assertThat( + typed.value(), + isTypedStructDefinitionNode() + .withName("ExampleStruct") + .withFields(isSequence( + isTypedStructFieldDefinitionNode() + .withName("b") + .withType(isTypedTypeLevelReferenceNode("Bool", Types.BOOL)), + isTypedStructFieldDefinitionNode() + .withName("a") + .withType(isTypedTypeLevelReferenceNode("Int", Types.INT)) + )) + ); + } + private static TypeCheckerResult typeCheckNamespaceStatement( UntypedNamespaceStatementNode untyped, TypeCheckerContext context -- cgit v1.2.3