From 1c60ecab9d6323b4d1fe6a2b2a510c6c5a5672e3 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 23 Dec 2023 11:44:45 +0000 Subject: Parse struct type level params --- .../compiler/ast/untyped/UntypedNodeMatchers.java | 4 ++ .../UntypedStructDefinitionNodeMatcher.java | 8 +++ .../parser/ParserStructDefinitionTests.java | 70 +++++++++++++++++++++- 3 files changed, 81 insertions(+), 1 deletion(-) (limited to 'src/test/java') diff --git a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java index 32f1d085..5b290949 100644 --- a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java +++ b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java @@ -355,6 +355,10 @@ public class UntypedNodeMatchers { ); } + public static Matcher isUntypedTypeLevelParamNode(String name) { + return has("name", x -> x.name(), equalTo(name)); + } + public static Matcher isUntypedTypeLevelReferenceNode(String name) { return instanceOf( UntypedTypeLevelReferenceNode.class, diff --git a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedStructDefinitionNodeMatcher.java b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedStructDefinitionNodeMatcher.java index 98bb535f..ba87b50f 100644 --- a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedStructDefinitionNodeMatcher.java +++ b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedStructDefinitionNodeMatcher.java @@ -6,6 +6,8 @@ import org.shedlang.compiler.types.Visibility; import org.shedlang.compiler.util.P; import org.zwobble.precisely.Matcher; +import java.util.Optional; + import static org.zwobble.precisely.Matchers.equalTo; import static org.zwobble.precisely.Matchers.has; @@ -32,6 +34,12 @@ public class UntypedStructDefinitionNodeMatcher extends MatcherBuilder x.name(), equalTo(name))); } + public UntypedStructDefinitionNodeMatcher withTypeLevelParams( + Matcher>> typeLevelParams + ) { + return with(has("typeLevelParams", x -> x.typeLevelParams(), typeLevelParams)); + } + public UntypedStructDefinitionNodeMatcher withFields(Matcher> fields) { return with(has("fields", x -> x.fields(), fields)); } diff --git a/src/test/java/org/shedlang/compiler/parser/ParserStructDefinitionTests.java b/src/test/java/org/shedlang/compiler/parser/ParserStructDefinitionTests.java index cfe3e58e..ff8f3559 100644 --- a/src/test/java/org/shedlang/compiler/parser/ParserStructDefinitionTests.java +++ b/src/test/java/org/shedlang/compiler/parser/ParserStructDefinitionTests.java @@ -6,7 +6,7 @@ import org.shedlang.compiler.types.Visibility; import static org.shedlang.compiler.ast.untyped.UntypedNodeMatchers.*; import static org.shedlang.compiler.parser.ParserTesting.parseString; import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.isSequence; +import static org.zwobble.precisely.Matchers.*; public class ParserStructDefinitionTests { @Test @@ -71,4 +71,72 @@ public class ParserStructDefinitionTests { isUntypedStructDefinitionNode().withVisibility(Visibility.PUBLIC) ); } + + @Test + public void canParseStructWithNoTypeLevelParams() { + var source = """ + struct X() {} + """; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedStructDefinitionNode() + .withTypeLevelParams(isOptionalEmpty()) + ); + } + + @Test + public void canParseStructWithSingleTypeLevelParam() { + var source = """ + struct X[T1]() {} + """; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedStructDefinitionNode() + .withTypeLevelParams(isOptionalOf(isSequence( + isUntypedTypeLevelParamNode("T1") + ))) + ); + } + + @Test + public void canParseStructWithMultipleTypeLevelParams() { + var source = """ + struct X[T1, T2, T3]() {} + """; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedStructDefinitionNode() + .withTypeLevelParams(isOptionalOf(isSequence( + isUntypedTypeLevelParamNode("T1"), + isUntypedTypeLevelParamNode("T2"), + isUntypedTypeLevelParamNode("T3") + ))) + ); + } + + @Test + public void typeLevelParamsCanHaveTrailingComma() { + var source = """ + struct X[T1,]() {} + """; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedStructDefinitionNode() + .withTypeLevelParams(isOptionalOf(isSequence( + isUntypedTypeLevelParamNode("T1") + ))) + ); + } } -- cgit v1.2.3