From f497e7f884856ca91f3697886db559af070a92ba Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 5 Jul 2023 21:30:56 +0100 Subject: Parse function definition params --- .../compiler/ast/untyped/UntypedNodeMatchers.java | 10 ++ .../parser/ParserFunctionDefinitionTests.java | 119 +++++++++++++++++++++ 2 files changed, 129 insertions(+) (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 acddc159..ad6c8a49 100644 --- a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java +++ b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java @@ -52,6 +52,16 @@ public class UntypedNodeMatchers { ); } + public static Matcher isUntypedParamNode( + String name, + Matcher type + ) { + return allOf( + has("name", x -> x.name(), equalTo(name)), + has("type", x -> x.type(), type) + ); + } + public static Matcher isUntypedParamsNode( Matcher> positional, Matcher> named diff --git a/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java b/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java index f718bfca..607a06bf 100644 --- a/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java +++ b/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java @@ -2,6 +2,7 @@ package org.shedlang.compiler.parser; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.shedlang.compiler.ast.untyped.UntypedNodeMatchers.*; import static org.shedlang.compiler.parser.ParserTesting.parseString; import static org.zwobble.precisely.AssertThat.assertThat; @@ -27,6 +28,124 @@ public class ParserFunctionDefinitionTests { ); } + @Test + public void canParseFunctionWithSinglePositionalParam() { + var source = """ + fun f(a: Int) -> Unit { + }"""; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedFunctionDefinitionNode() + .withParams(isUntypedParamsNode( + isSequence( + isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")) + ), + isSequence() + )) + ); + } + + @Test + public void canParseFunctionWithManyPositionalParams() { + var source = """ + fun f(a: Int, b: String, c: Bool) -> Unit { + }"""; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedFunctionDefinitionNode() + .withParams(isUntypedParamsNode( + isSequence( + isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")), + isUntypedParamNode("b", isUntypedTypeLevelReferenceNode("String")), + isUntypedParamNode("c", isUntypedTypeLevelReferenceNode("Bool")) + ), + isSequence() + )) + ); + } + + @Test + public void canParseFunctionWithSingleNamedParam() { + var source = """ + fun f(.a: Int) -> Unit { + }"""; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedFunctionDefinitionNode() + .withParams(isUntypedParamsNode( + isSequence(), + isSequence( + isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")) + ) + )) + ); + } + + @Test + public void canParseFunctionWithManyNamedParams() { + var source = """ + fun f(.a: Int, .b: String, .c: Bool) -> Unit { + }"""; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedFunctionDefinitionNode() + .withParams(isUntypedParamsNode( + isSequence(), + isSequence( + isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")), + isUntypedParamNode("b", isUntypedTypeLevelReferenceNode("String")), + isUntypedParamNode("c", isUntypedTypeLevelReferenceNode("Bool")) + ) + )) + ); + } + + @Test + public void canParseNamedParamAfterPositionalParam() { + var source = """ + fun f(a: Int, .b: String) -> Unit { + }"""; + + var node = parseString(source, Parser::parseNamespaceStatement); + + assertThat( + node, + isUntypedFunctionDefinitionNode() + .withParams(isUntypedParamsNode( + isSequence( + isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")) + ), + isSequence( + isUntypedParamNode("b", isUntypedTypeLevelReferenceNode("String")) + ) + )) + ); + } + + @Test + public void cannotParsePositionalParamAfterNamedParam() { + var source = """ + fun f(.a: Int, b: String) -> Unit { + }"""; + + assertThrows( + PositionalParamAfterNamedParamError.class, + () -> parseString(source, Parser::parseNamespaceStatement) + ); + } + @Test public void canParseFunctionWithEffect() { var source = """ -- cgit v1.2.3