diff options
| author | Michael Williamson <mike@zwobble.org> | 2025-02-02 13:09:06 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2025-02-02 13:10:52 +0000 |
| commit | 1c88d4563baea119c86f90ba2ba0c1f9f2e37b91 (patch) | |
| tree | 421e7ed25dede77fd7823a8b4a1c310378d347bf /src/test/java | |
| parent | fb439df085eb1f7095d987973475a7753d0a1103 (diff) | |
Parse native type declarations
Diffstat (limited to 'src/test/java')
3 files changed, 244 insertions, 0 deletions
diff --git a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNativeTypeDeclarationNodeMatcher.java b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNativeTypeDeclarationNodeMatcher.java new file mode 100644 index 00000000..f88ecc59 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNativeTypeDeclarationNodeMatcher.java @@ -0,0 +1,60 @@ +package org.shedlang.compiler.ast.untyped; + +import org.pcollections.PVector; +import org.shedlang.compiler.testing.MatcherBuilder; +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; + +public class UntypedNativeTypeDeclarationNodeMatcher extends MatcherBuilder< + UntypedNamespaceStatementNode, + UntypedNativeTypeDeclarationNode, + UntypedNativeTypeDeclarationNodeMatcher +> { + public static UntypedNativeTypeDeclarationNodeMatcher empty() { + return new UntypedNativeTypeDeclarationNodeMatcher(P.vector()); + } + + public UntypedNativeTypeDeclarationNodeMatcher( + PVector<Matcher<? super UntypedNativeTypeDeclarationNode>> submatchers + ) { + super(submatchers); + } + + @Override + protected Class<UntypedNativeTypeDeclarationNode> expectedType() { + return UntypedNativeTypeDeclarationNode.class; + } + + @Override + protected UntypedNativeTypeDeclarationNodeMatcher create( + PVector<Matcher<? super UntypedNativeTypeDeclarationNode>> submatchers + ) { + return new UntypedNativeTypeDeclarationNodeMatcher(submatchers); + } + + public UntypedNativeTypeDeclarationNodeMatcher withName(String name) { + return with(has("name", x -> x.name(), equalTo(name))); + } + + public UntypedNativeTypeDeclarationNodeMatcher withTypeLevelParams( + Matcher<Optional<? extends Iterable<? extends UntypedTypeLevelParamNode>>> typeLevelParams + ) { + return with(has("typeLevelParams", x -> x.typeLevelParams(), typeLevelParams)); + } + + public UntypedNativeTypeDeclarationNodeMatcher withVisibility(Visibility visibility) { + return with(has("visibility", x -> x.visibility(), equalTo(visibility))); + } + + public UntypedNativeTypeDeclarationNodeMatcher withMethods( + Matcher<Iterable<? extends UntypedNativeFunctionDeclarationNode>> methods + ) { + return with(has("methods", x -> x.methods(), methods)); + } +} 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 94fc68e1..24cb61ca 100644 --- a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java +++ b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java @@ -239,6 +239,10 @@ public class UntypedNodeMatchers { return UntypedNativeFunctionDeclarationNodeMatcher.empty(); } + public static UntypedNativeTypeDeclarationNodeMatcher isUntypedNativeTypeDeclarationNode() { + return UntypedNativeTypeDeclarationNodeMatcher.empty(); + } + public static Matcher<UntypedExpressionNode> isUntypedNotEqualNode( Matcher<UntypedExpressionNode> left, Matcher<UntypedExpressionNode> right diff --git a/src/test/java/org/shedlang/compiler/parser/ParserNativeTypeDeclarationTests.java b/src/test/java/org/shedlang/compiler/parser/ParserNativeTypeDeclarationTests.java new file mode 100644 index 00000000..900ac1aa --- /dev/null +++ b/src/test/java/org/shedlang/compiler/parser/ParserNativeTypeDeclarationTests.java @@ -0,0 +1,180 @@ +package org.shedlang.compiler.parser; + +import org.junit.jupiter.api.Test; +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.*; + +public class ParserNativeTypeDeclarationTests { + @Test + public void canParseNameOfNativeType() { + var source = """ + native type X {} + """; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedNativeTypeDeclarationNode() + .withName("X") + ); + } + + @Test + public void defaultVisibilityIsPrivate() { + var source = "native type X {}"; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedNativeTypeDeclarationNode() + .withVisibility(Visibility.PRIVATE) + ); + } + + @Test + public void whenHasPubPrefixThenVisibilityIsPublic() { + var source = "pub native type X {}"; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedNativeTypeDeclarationNode() + .withVisibility(Visibility.PUBLIC) + ); + } + + @Test + public void canParseNativeTypeWithNoTypeLevelParams() { + var source = """ + native type X {} + """; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedNativeTypeDeclarationNode() + .withTypeLevelParams(isOptionalEmpty()) + ); + } + + @Test + public void canParseNativeTypeWithSingleTypeLevelParam() { + var source = """ + native type X[T1] {} + """; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedNativeTypeDeclarationNode() + .withTypeLevelParams(isOptionalOf(isSequence( + isUntypedTypeParamNode("T1") + ))) + ); + } + + @Test + public void canParseNativeTypeWithMultipleTypeLevelParams() { + var source = """ + native type X[T1, T2, T3] {} + """; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedNativeTypeDeclarationNode() + .withTypeLevelParams(isOptionalOf(isSequence( + isUntypedTypeParamNode("T1"), + isUntypedTypeParamNode("T2"), + isUntypedTypeParamNode("T3") + ))) + ); + } + + @Test + public void typeLevelParamsCanHaveTrailingComma() { + var source = """ + native type X[T1,] {} + """; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedNativeTypeDeclarationNode() + .withTypeLevelParams(isOptionalOf(isSequence( + isUntypedTypeParamNode("T1") + ))) + ); + } + + @Test + public void canParseNativeTypeWithNoMethods() { + var source = """ + native type X {} + """; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedNativeTypeDeclarationNode() + .withMethods(isSequence()) + ); + } + + @Test + public void canParseNativeTypeWithSingleMethod() { + var source = """ + native type X { + native fun a(this); + } + """; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedNativeTypeDeclarationNode() + .withMethods(isSequence( + isUntypedNativeFunctionDeclarationNode().withName("a") + )) + ); + } + + @Test + public void canParseNativeTypeWithMultipleMethods() { + var source = """ + native type X { + native fun a(this); + + native fun b(this); + + native fun c(this); + + } + """; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedNativeTypeDeclarationNode() + .withMethods(isSequence( + isUntypedNativeFunctionDeclarationNode().withName("a"), + isUntypedNativeFunctionDeclarationNode().withName("b"), + isUntypedNativeFunctionDeclarationNode().withName("c") + )) + ); + } +} |
