diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-10-25 21:44:51 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-10-25 21:44:51 +0100 |
| commit | 5a5e3cad6edd5af97522c99f7b0ffe145d200db0 (patch) | |
| tree | 92dee5f887b80ad7bb94a723504878c2909e178e /src/test/java/org/shedlang/compiler/parser | |
| parent | 2cecc44c63d3dbbcc09cb234babde8d849fe04ac (diff) | |
Introduce UntypedFunctionSignatureNode
Diffstat (limited to 'src/test/java/org/shedlang/compiler/parser')
4 files changed, 201 insertions, 322 deletions
diff --git a/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java b/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java index 431ef6d0..9c3148a3 100644 --- a/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java +++ b/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java @@ -1,7 +1,6 @@ package org.shedlang.compiler.parser; import org.junit.jupiter.api.Test; -import org.shedlang.compiler.parser.errors.PositionalParamAfterNamedParamError; import org.shedlang.compiler.tokeniser.UnexpectedTokenException; import org.shedlang.compiler.types.Visibility; @@ -24,9 +23,12 @@ public class ParserFunctionDefinitionTests { node, isUntypedFunctionDefinitionNode() .withName("f") - .withParams(isUntypedParamsNode(isSequence(), isSequence())) - .withEffect(isOptionalEmpty()) - .withReturnType(isUntypedTypeLevelReferenceNode("Unit")) + .withSignature( + isUntypedFunctionSignatureNode() + .withParams(isUntypedParamsNode(isSequence(), isSequence())) + .withEffect(isOptionalEmpty()) + .withReturnType(isUntypedTypeLevelReferenceNode("Unit")) + ) .withBody(isUntypedBlockNode(isSequence())) ); } @@ -46,7 +48,7 @@ public class ParserFunctionDefinitionTests { } @Test - public void whenFunIsPrefixWithPubThenVisibilityIsPublic() { + public void whenFunIsPrefixedWithPubThenVisibilityIsPublic() { var source = """ pub fun f() -> Unit { }"""; @@ -60,159 +62,6 @@ 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 paramsCanHaveTrailingComma() { - 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 canParseFunctionWithEffect() { - var source = """ - fun f() ! Io -> Unit { - }"""; - - var node = parseString(source, Parser::parseNamespaceStatement); - - assertThat( - node, - isUntypedFunctionDefinitionNode() - .withEffect(isOptionalOf(isUntypedTypeLevelReferenceNode("Io"))) - ); - } - - @Test public void canParseFunctionWithBodyWithoutReturn() { var source = """ fun f() -> Unit { diff --git a/src/test/java/org/shedlang/compiler/parser/ParserFunctionExpressionTests.java b/src/test/java/org/shedlang/compiler/parser/ParserFunctionExpressionTests.java index d86776be..8b4c72a6 100644 --- a/src/test/java/org/shedlang/compiler/parser/ParserFunctionExpressionTests.java +++ b/src/test/java/org/shedlang/compiler/parser/ParserFunctionExpressionTests.java @@ -1,7 +1,6 @@ package org.shedlang.compiler.parser; import org.junit.jupiter.api.Test; -import org.shedlang.compiler.parser.errors.PositionalParamAfterNamedParamError; import org.shedlang.compiler.tokeniser.UnexpectedTokenException; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -22,167 +21,17 @@ public class ParserFunctionExpressionTests { assertThat( node, isUntypedFunctionExpressionNode() - .withParams(isUntypedParamsNode(isSequence(), isSequence())) - .withEffect(isOptionalEmpty()) - .withReturnType(isUntypedTypeLevelReferenceNode("Unit")) + .withSignature( + isUntypedFunctionSignatureNode() + .withParams(isUntypedParamsNode(isSequence(), isSequence())) + .withEffect(isOptionalEmpty()) + .withReturnType(isUntypedTypeLevelReferenceNode("Unit")) + ) .withBody(isUntypedBlockNode(isSequence())) ); } @Test - public void canParseFunctionWithSinglePositionalParam() { - var source = """ - fn (a: Int) -> Unit { - }"""; - - var node = parseString(source, Parser::parseTopLevelExpression); - - assertThat( - node, - isUntypedFunctionExpressionNode() - .withParams(isUntypedParamsNode( - isSequence( - isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")) - ), - isSequence() - )) - ); - } - - @Test - public void canParseFunctionWithManyPositionalParams() { - var source = """ - fn (a: Int, b: String, c: Bool) -> Unit { - }"""; - - var node = parseString(source, Parser::parseTopLevelExpression); - - assertThat( - node, - isUntypedFunctionExpressionNode() - .withParams(isUntypedParamsNode( - isSequence( - isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")), - isUntypedParamNode("b", isUntypedTypeLevelReferenceNode("String")), - isUntypedParamNode("c", isUntypedTypeLevelReferenceNode("Bool")) - ), - isSequence() - )) - ); - } - - @Test - public void canParseFunctionWithSingleNamedParam() { - var source = """ - fn (.a: Int) -> Unit { - }"""; - - var node = parseString(source, Parser::parseTopLevelExpression); - - assertThat( - node, - isUntypedFunctionExpressionNode() - .withParams(isUntypedParamsNode( - isSequence(), - isSequence( - isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")) - ) - )) - ); - } - - @Test - public void canParseFunctionWithManyNamedParams() { - var source = """ - fn (.a: Int, .b: String, .c: Bool) -> Unit { - }"""; - - var node = parseString(source, Parser::parseTopLevelExpression); - - assertThat( - node, - isUntypedFunctionExpressionNode() - .withParams(isUntypedParamsNode( - isSequence(), - isSequence( - isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")), - isUntypedParamNode("b", isUntypedTypeLevelReferenceNode("String")), - isUntypedParamNode("c", isUntypedTypeLevelReferenceNode("Bool")) - ) - )) - ); - } - - @Test - public void canParseNamedParamAfterPositionalParam() { - var source = """ - fn (a: Int, .b: String) -> Unit { - }"""; - - var node = parseString(source, Parser::parseTopLevelExpression); - - assertThat( - node, - isUntypedFunctionExpressionNode() - .withParams(isUntypedParamsNode( - isSequence( - isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")) - ), - isSequence( - isUntypedParamNode("b", isUntypedTypeLevelReferenceNode("String")) - ) - )) - ); - } - - @Test - public void cannotParsePositionalParamAfterNamedParam() { - var source = """ - fn (.a: Int, b: String) -> Unit { - }"""; - - assertThrows( - PositionalParamAfterNamedParamError.class, - () -> parseString(source, Parser::parseTopLevelExpression) - ); - } - - @Test - public void paramsCanHaveTrailingComma() { - var source = """ - fn (a: Int, ) -> Unit { - }"""; - - var node = parseString(source, Parser::parseTopLevelExpression); - - assertThat( - node, - isUntypedFunctionExpressionNode() - .withParams(isUntypedParamsNode( - isSequence( - isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")) - ), - isSequence() - )) - ); - } - - @Test - public void canParseFunctionWithEffect() { - var source = """ - fn () ! Io -> Unit { - }"""; - - var node = parseString(source, Parser::parseTopLevelExpression); - - assertThat( - node, - isUntypedFunctionExpressionNode() - .withEffect(isOptionalOf(isUntypedTypeLevelReferenceNode("Io"))) - ); - } - - @Test public void canParseFunctionWithBodyWithoutReturn() { var source = """ fn () -> Unit { diff --git a/src/test/java/org/shedlang/compiler/parser/ParserFunctionSignatureTests.java b/src/test/java/org/shedlang/compiler/parser/ParserFunctionSignatureTests.java new file mode 100644 index 00000000..cfb610af --- /dev/null +++ b/src/test/java/org/shedlang/compiler/parser/ParserFunctionSignatureTests.java @@ -0,0 +1,183 @@ +package org.shedlang.compiler.parser; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.parser.errors.PositionalParamAfterNamedParamError; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.shedlang.compiler.ast.untyped.UntypedNodeMatchers.*; +import static org.shedlang.compiler.ast.untyped.UntypedNodeMatchers.isUntypedTypeLevelReferenceNode; +import static org.shedlang.compiler.parser.ParserTesting.parseString; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.*; + +public class ParserFunctionSignatureTests { + @Test + public void canParseEmptyParams() { + var source = "() -> Unit"; + + var node = parseString(source, Parser::parseFunctionSignature); + + assertThat( + node, + isUntypedFunctionSignatureNode() + .withParams(isUntypedParamsNode(isSequence(), isSequence())) + ); + } + + @Test + public void canParseSinglePositionalParam() { + var source = "(a: Int) -> Unit"; + + var node = parseString(source, Parser::parseFunctionSignature); + + assertThat( + node, + isUntypedFunctionSignatureNode().withParams(isUntypedParamsNode( + isSequence( + isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")) + ), + isSequence() + )) + ); + } + + @Test + public void canParseManyPositionalParams() { + var source = "(a: Int, b: String, c: Bool) -> Unit"; + + var node = parseString(source, Parser::parseFunctionSignature); + + assertThat( + node, + isUntypedFunctionSignatureNode().withParams(isUntypedParamsNode( + isSequence( + isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")), + isUntypedParamNode("b", isUntypedTypeLevelReferenceNode("String")), + isUntypedParamNode("c", isUntypedTypeLevelReferenceNode("Bool")) + ), + isSequence() + )) + ); + } + + @Test + public void canParseSingleNamedParam() { + var source = "(.a: Int) -> Unit"; + + var node = parseString(source, Parser::parseFunctionSignature); + + assertThat( + node, + isUntypedFunctionSignatureNode().withParams(isUntypedParamsNode( + isSequence(), + isSequence( + isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")) + ) + )) + ); + } + + @Test + public void canParseManyNamedParams() { + var source = "(.a: Int, .b: String, .c: Bool) -> Unit"; + + var node = parseString(source, Parser::parseFunctionSignature); + + assertThat( + node, + isUntypedFunctionSignatureNode().withParams(isUntypedParamsNode( + isSequence(), + isSequence( + isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")), + isUntypedParamNode("b", isUntypedTypeLevelReferenceNode("String")), + isUntypedParamNode("c", isUntypedTypeLevelReferenceNode("Bool")) + ) + )) + ); + } + + @Test + public void canParseNamedParamAfterPositionalParam() { + var source = "(a: Int, .b: String) -> Unit"; + + var node = parseString(source, Parser::parseFunctionSignature); + + assertThat( + node, + isUntypedFunctionSignatureNode().withParams(isUntypedParamsNode( + isSequence( + isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")) + ), + isSequence( + isUntypedParamNode("b", isUntypedTypeLevelReferenceNode("String")) + ) + )) + ); + } + + @Test + public void cannotParsePositionalParamAfterNamedParam() { + var source = "(.a: Int, b: String) -> Unit"; + + assertThrows( + PositionalParamAfterNamedParamError.class, + () -> parseString(source, Parser::parseFunctionSignature) + ); + } + + @Test + public void paramsCanHaveTrailingComma() { + var source = "(a: Int, ) -> Unit"; + + var node = parseString(source, Parser::parseFunctionSignature); + + assertThat( + node, + isUntypedFunctionSignatureNode().withParams(isUntypedParamsNode( + isSequence( + isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")) + ), + isSequence() + )) + ); + } + + @Test + public void canParseSignatureWithoutEffect() { + var source = "() -> Unit"; + + var node = parseString(source, Parser::parseFunctionSignature); + + assertThat( + node, + isUntypedFunctionSignatureNode() + .withEffect(isOptionalEmpty()) + ); + } + + @Test + public void canParseSignatureWithEffect() { + var source = "() ! Io -> Unit"; + + var node = parseString(source, Parser::parseFunctionSignature); + + assertThat( + node, + isUntypedFunctionSignatureNode() + .withEffect(isOptionalOf(isUntypedTypeLevelReferenceNode("Io"))) + ); + } + + @Test + public void canParseReturnType() { + var source = "() -> Unit"; + + var node = parseString(source, Parser::parseFunctionSignature); + + assertThat( + node, + isUntypedFunctionSignatureNode() + .withReturnType(isUntypedTypeLevelReferenceNode("Unit")) + ); + } +} diff --git a/src/test/java/org/shedlang/compiler/parser/ParserFunctionTypeTests.java b/src/test/java/org/shedlang/compiler/parser/ParserFunctionTypeTests.java index 038baef4..76311a97 100644 --- a/src/test/java/org/shedlang/compiler/parser/ParserFunctionTypeTests.java +++ b/src/test/java/org/shedlang/compiler/parser/ParserFunctionTypeTests.java @@ -136,18 +136,16 @@ public class ParserFunctionTypeTests { @Test public void paramsCanHaveTrailingComma() { - var source = """ - fun f(a: Int, ) -> Unit { - }"""; + var source = "fn (Int, ) -> Unit"; - var node = parseString(source, Parser::parseNamespaceStatement); + var node = parseString(source, Parser::parseTopLevelTypeLevelExpression); assertThat( node, - isUntypedFunctionDefinitionNode() - .withParams(isUntypedParamsNode( + isUntypedFunctionTypeNode() + .withParams(isUntypedParamTypesNode( isSequence( - isUntypedParamNode("a", isUntypedTypeLevelReferenceNode("Int")) + isUntypedTypeLevelReferenceNode("Int") ), isSequence() )) |
