diff --git a/parser/parse_test_helpers.h b/parser/parse_test_helpers.h index a6a3e7008d55..6be527c51f82 100644 --- a/parser/parse_test_helpers.h +++ b/parser/parse_test_helpers.h @@ -316,6 +316,26 @@ auto MatchNode(Args... args) -> ExpectedNode { return MatchNode(ParseNodeKind::kind(), args...); \ } #include "parse_node_kind.def" + +// Helper for matching a designator `lhs.rhs`. +auto MatchDesignator(ExpectedNode lhs, std::string rhs) -> ExpectedNode { + return MatchDesignatorExpression(lhs, MatchDesignatedName(rhs)); +} + +// Helper for matching a function parameter list. +template +auto MatchParameters(Args... args) -> ExpectedNode { + return MatchParameterList("(", args..., MatchParameterListEnd()); +} + +// Helper for matching the statements in the body of a simple function +// definition with no parameters. +template +auto MatchFunctionWithBody(Args... args) -> ExpectedNode { + return MatchFunctionDeclaration(MatchDeclaredName(), MatchParameters(), + MatchCodeBlock(args..., MatchCodeBlockEnd())); +} + } // namespace NodeMatchers } // namespace Testing diff --git a/parser/parse_tree_test.cpp b/parser/parse_tree_test.cpp index d2674a31aa8d..3c674cd23b98 100644 --- a/parser/parse_tree_test.cpp +++ b/parser/parse_tree_test.cpp @@ -89,13 +89,11 @@ TEST_F(ParseTreeTest, BasicFunctionDeclaration) { TokenizedBuffer tokens = GetTokenizedBuffer("fn F();"); ParseTree tree = ParseTree::Parse(tokens, consumer); EXPECT_FALSE(tree.HasErrors()); - EXPECT_THAT(tree, - MatchParseTreeNodes( - {MatchFunctionDeclaration( - "fn", MatchDeclaredName("F"), - MatchParameterList("(", MatchParameterListEnd(")")), - MatchDeclarationEnd(";")), - MatchFileEnd()})); + EXPECT_THAT(tree, MatchParseTreeNodes( + {MatchFunctionDeclaration("fn", MatchDeclaredName("F"), + MatchParameters(), + MatchDeclarationEnd(";")), + MatchFileEnd()})); } TEST_F(ParseTreeTest, NoDeclarationIntroducerOrSemi) { @@ -194,13 +192,11 @@ TEST_F(ParseTreeTest, FunctionDeclarationSkipToNewlineWithoutSemi) { ParseTree tree = ParseTree::Parse(tokens, consumer); EXPECT_TRUE(tree.HasErrors()); EXPECT_THAT( - tree, - MatchParseTreeNodes( - {MatchFunctionDeclaration(HasError), - MatchFunctionDeclaration(MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), - MatchDeclarationEnd()), - MatchFileEnd()})); + tree, MatchParseTreeNodes({MatchFunctionDeclaration(HasError), + MatchFunctionDeclaration( + MatchDeclaredName("F"), MatchParameters(), + MatchDeclarationEnd()), + MatchFileEnd()})); } TEST_F(ParseTreeTest, FunctionDeclarationSkipIndentedNewlineWithSemi) { @@ -215,8 +211,7 @@ TEST_F(ParseTreeTest, FunctionDeclarationSkipIndentedNewlineWithSemi) { tree, MatchParseTreeNodes( {MatchFunctionDeclaration(HasError, MatchDeclarationEnd()), - MatchFunctionDeclaration(MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), + MatchFunctionDeclaration(MatchDeclaredName("F"), MatchParameters(), MatchDeclarationEnd()), MatchFileEnd()})); } @@ -230,13 +225,11 @@ TEST_F(ParseTreeTest, FunctionDeclarationSkipIndentedNewlineWithoutSemi) { ParseTree tree = ParseTree::Parse(tokens, consumer); EXPECT_TRUE(tree.HasErrors()); EXPECT_THAT( - tree, - MatchParseTreeNodes( - {MatchFunctionDeclaration(HasError), - MatchFunctionDeclaration(MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), - MatchDeclarationEnd()), - MatchFileEnd()})); + tree, MatchParseTreeNodes({MatchFunctionDeclaration(HasError), + MatchFunctionDeclaration( + MatchDeclaredName("F"), MatchParameters(), + MatchDeclarationEnd()), + MatchFileEnd()})); } TEST_F(ParseTreeTest, FunctionDeclarationSkipIndentedNewlineUntilOutdent) { @@ -248,13 +241,11 @@ TEST_F(ParseTreeTest, FunctionDeclarationSkipIndentedNewlineUntilOutdent) { ParseTree tree = ParseTree::Parse(tokens, consumer); EXPECT_TRUE(tree.HasErrors()); EXPECT_THAT( - tree, - MatchParseTreeNodes( - {MatchFunctionDeclaration(HasError), - MatchFunctionDeclaration(MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), - MatchDeclarationEnd()), - MatchFileEnd()})); + tree, MatchParseTreeNodes({MatchFunctionDeclaration(HasError), + MatchFunctionDeclaration( + MatchDeclaredName("F"), MatchParameters(), + MatchDeclarationEnd()), + MatchFileEnd()})); } TEST_F(ParseTreeTest, FunctionDeclarationSkipWithoutSemiToCurly) { @@ -278,8 +269,7 @@ TEST_F(ParseTreeTest, BasicFunctionDefinition) { EXPECT_FALSE(tree.HasErrors()); EXPECT_THAT(tree, MatchParseTreeNodes( {MatchFunctionDeclaration( - MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), + MatchDeclaredName("F"), MatchParameters(), MatchCodeBlock("{", MatchCodeBlockEnd("}"))), MatchFileEnd()})); } @@ -296,8 +286,7 @@ TEST_F(ParseTreeTest, FunctionDefinitionWithNestedBlocks) { EXPECT_THAT( tree, MatchParseTreeNodes( {MatchFunctionDeclaration( - MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), + MatchDeclaredName("F"), MatchParameters(), MatchCodeBlock( MatchCodeBlock( MatchCodeBlock(MatchCodeBlock(MatchCodeBlockEnd()), @@ -318,8 +307,7 @@ TEST_F(ParseTreeTest, FunctionDefinitionWithIdenifierInStatements) { EXPECT_TRUE(tree.HasErrors()); EXPECT_THAT(tree, MatchParseTreeNodes( {MatchFunctionDeclaration( - MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), + MatchDeclaredName("F"), MatchParameters(), MatchCodeBlock(HasError, MatchNameReference("bar"), MatchCodeBlockEnd())), MatchFileEnd()})); @@ -337,8 +325,7 @@ TEST_F(ParseTreeTest, FunctionDefinitionWithIdenifierInNestedBlock) { EXPECT_THAT(tree, MatchParseTreeNodes( {MatchFunctionDeclaration( - MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), + MatchDeclaredName("F"), MatchParameters(), MatchCodeBlock( MatchCodeBlock(HasError, MatchNameReference("bar"), MatchCodeBlockEnd()), @@ -355,25 +342,15 @@ TEST_F(ParseTreeTest, FunctionDefinitionWithFunctionCall) { EXPECT_FALSE(tree.HasErrors()); ExpectedNode call_to_f = MatchCallExpression( - MatchDesignatorExpression( - MatchDesignatorExpression(MatchNameReference("a"), - MatchDesignatedName("b")), - MatchDesignatedName("f")), - MatchDesignatorExpression(MatchNameReference("c"), - MatchDesignatedName("d")), - MatchCallExpressionComma(), + MatchDesignator(MatchDesignator(MatchNameReference("a"), "b"), "f"), + MatchDesignator(MatchNameReference("c"), "d"), MatchCallExpressionComma(), MatchParenExpression(MatchNameReference("e"), MatchParenExpressionEnd()), MatchCallExpressionEnd()); ExpectedNode statement = MatchExpressionStatement(MatchCallExpression( - MatchDesignatorExpression(call_to_f, MatchDesignatedName("g")), - MatchCallExpressionEnd())); + MatchDesignator(call_to_f, "g"), MatchCallExpressionEnd())); EXPECT_THAT(tree, MatchParseTreeNodes( - {MatchFunctionDeclaration( - MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), - MatchCodeBlock(statement, MatchCodeBlockEnd())), - MatchFileEnd()})); + {MatchFunctionWithBody(statement), MatchFileEnd()})); } TEST_F(ParseTreeTest, InvalidDesignators) { @@ -386,26 +363,21 @@ TEST_F(ParseTreeTest, InvalidDesignators) { ParseTree tree = ParseTree::Parse(tokens, consumer); EXPECT_TRUE(tree.HasErrors()); - EXPECT_THAT( - tree, - MatchParseTreeNodes( - {MatchFunctionDeclaration( - MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), - MatchCodeBlock(MatchExpressionStatement( - MatchDesignatorExpression( - MatchNameReference("a"), ".", HasError), - ";"), - MatchExpressionStatement( - MatchDesignatorExpression( - MatchNameReference("a"), ".", HasError), - ";"), - MatchExpressionStatement( - MatchDesignatorExpression( - MatchNameReference("a"), ".", HasError), - HasError, ";"), - MatchCodeBlockEnd())), - MatchFileEnd()})); + EXPECT_THAT(tree, MatchParseTreeNodes( + {MatchFunctionWithBody( + MatchExpressionStatement( + MatchDesignatorExpression( + MatchNameReference("a"), ".", HasError), + ";"), + MatchExpressionStatement( + MatchDesignatorExpression( + MatchNameReference("a"), ".", HasError), + ";"), + MatchExpressionStatement( + MatchDesignatorExpression( + MatchNameReference("a"), ".", HasError), + HasError, ";")), + MatchFileEnd()})); } TEST_F(ParseTreeTest, Operators) { @@ -425,62 +397,56 @@ TEST_F(ParseTreeTest, Operators) { EXPECT_THAT( tree, MatchParseTreeNodes( - {MatchFunctionDeclaration( - MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), - MatchCodeBlock( - MatchExpressionStatement(MatchInfixOperator( - MatchNameReference("n"), "=", + {MatchFunctionWithBody( + MatchExpressionStatement(MatchInfixOperator( + MatchNameReference("n"), "=", + MatchInfixOperator( MatchInfixOperator( - MatchInfixOperator( - MatchInfixOperator(MatchNameReference("a"), "*", - MatchNameReference("b")), - "+", - MatchInfixOperator(MatchNameReference("c"), "*", - MatchNameReference("d"))), - "=", + MatchInfixOperator(MatchNameReference("a"), "*", + MatchNameReference("b")), + "+", + MatchInfixOperator(MatchNameReference("c"), "*", + MatchNameReference("d"))), + "=", + MatchInfixOperator( + HasError, MatchInfixOperator( HasError, MatchInfixOperator( HasError, - MatchInfixOperator( - HasError, - MatchInfixOperator( - MatchNameReference("d"), "*", - MatchNameReference("d")), - "<<", MatchNameReference("e")), - "&", MatchNameReference("f")), - "-", - MatchPrefixOperator("not", - MatchNameReference("g")))))), - MatchExpressionStatement(MatchPrefixOperator( - "++", - MatchPrefixOperator("++", MatchNameReference("n")))), - MatchExpressionStatement(MatchPostfixOperator( - MatchPostfixOperator(MatchNameReference("n"), "++"), - "++")), - MatchExpressionStatement(MatchInfixOperator( - MatchInfixOperator(MatchNameReference("a"), "and", - MatchNameReference("b")), - "and", MatchNameReference("c"))), - MatchExpressionStatement(MatchInfixOperator( - HasError, - MatchInfixOperator(MatchNameReference("a"), "and", - MatchNameReference("b")), - "or", MatchNameReference("c"))), - MatchExpressionStatement(MatchInfixOperator( - HasError, - MatchInfixOperator(MatchNameReference("a"), "or", - MatchNameReference("b")), - "and", MatchNameReference("c"))), - MatchExpressionStatement(MatchInfixOperator( - MatchInfixOperator( - MatchPrefixOperator("not", MatchNameReference("a")), - "and", - MatchPrefixOperator("not", MatchNameReference("b"))), + MatchInfixOperator(MatchNameReference("d"), + "*", + MatchNameReference("d")), + "<<", MatchNameReference("e")), + "&", MatchNameReference("f")), + "-", + MatchPrefixOperator("not", + MatchNameReference("g")))))), + MatchExpressionStatement(MatchPrefixOperator( + "++", MatchPrefixOperator("++", MatchNameReference("n")))), + MatchExpressionStatement(MatchPostfixOperator( + MatchPostfixOperator(MatchNameReference("n"), "++"), "++")), + MatchExpressionStatement(MatchInfixOperator( + MatchInfixOperator(MatchNameReference("a"), "and", + MatchNameReference("b")), + "and", MatchNameReference("c"))), + MatchExpressionStatement(MatchInfixOperator( + HasError, + MatchInfixOperator(MatchNameReference("a"), "and", + MatchNameReference("b")), + "or", MatchNameReference("c"))), + MatchExpressionStatement(MatchInfixOperator( + HasError, + MatchInfixOperator(MatchNameReference("a"), "or", + MatchNameReference("b")), + "and", MatchNameReference("c"))), + MatchExpressionStatement(MatchInfixOperator( + MatchInfixOperator( + MatchPrefixOperator("not", MatchNameReference("a")), "and", - MatchPrefixOperator("not", MatchNameReference("c")))), - MatchCodeBlockEnd())), + MatchPrefixOperator("not", MatchNameReference("b"))), + "and", + MatchPrefixOperator("not", MatchNameReference("c"))))), MatchFileEnd()})); } @@ -494,26 +460,20 @@ TEST_F(ParseTreeTest, VariableDeclarations) { ParseTree tree = ParseTree::Parse(tokens, consumer); EXPECT_FALSE(tree.HasErrors()); - EXPECT_THAT( - tree, - MatchParseTreeNodes( - {MatchVariableDeclaration(MatchNameReference("Int"), - MatchDeclaredName("v"), - MatchVariableInitializer(MatchLiteral("0")), - MatchDeclarationEnd()), - MatchVariableDeclaration(MatchNameReference("Int"), - MatchDeclaredName("w"), - MatchDeclarationEnd()), - MatchFunctionDeclaration( - MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), - MatchCodeBlock( - MatchVariableDeclaration( + EXPECT_THAT(tree, + MatchParseTreeNodes( + {MatchVariableDeclaration( + MatchNameReference("Int"), MatchDeclaredName("v"), + MatchVariableInitializer(MatchLiteral("0")), + MatchDeclarationEnd()), + MatchVariableDeclaration(MatchNameReference("Int"), + MatchDeclaredName("w"), + MatchDeclarationEnd()), + MatchFunctionWithBody(MatchVariableDeclaration( MatchNameReference("String"), MatchDeclaredName("s"), MatchVariableInitializer(MatchLiteral("\"hello\"")), - MatchDeclarationEnd()), - MatchCodeBlockEnd())), - MatchFileEnd()})); + MatchDeclarationEnd())), + MatchFileEnd()})); } TEST_F(ParseTreeTest, IfNoElse) { @@ -527,25 +487,18 @@ TEST_F(ParseTreeTest, IfNoElse) { ParseTree tree = ParseTree::Parse(tokens, consumer); EXPECT_FALSE(tree.HasErrors()); - EXPECT_THAT(tree, - MatchParseTreeNodes( - {MatchFunctionDeclaration( - MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), - MatchCodeBlock( - MatchIfStatement( - MatchCondition(MatchNameReference("a"), - MatchConditionEnd()), - MatchIfStatement( - MatchCondition(MatchNameReference("b"), - MatchConditionEnd()), - MatchIfStatement( - MatchCondition(MatchNameReference("c"), - MatchConditionEnd()), - MatchExpressionStatement( - MatchNameReference("d"))))), - MatchCodeBlockEnd())), - MatchFileEnd()})); + EXPECT_THAT( + tree, + MatchParseTreeNodes( + {MatchFunctionWithBody(MatchIfStatement( + MatchCondition(MatchNameReference("a"), MatchConditionEnd()), + MatchIfStatement( + MatchCondition(MatchNameReference("b"), MatchConditionEnd()), + MatchIfStatement( + MatchCondition(MatchNameReference("c"), + MatchConditionEnd()), + MatchExpressionStatement(MatchNameReference("d")))))), + MatchFileEnd()})); } TEST_F(ParseTreeTest, IfElse) { @@ -568,45 +521,39 @@ TEST_F(ParseTreeTest, IfElse) { EXPECT_THAT( tree, MatchParseTreeNodes( - {MatchFunctionDeclaration( - MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), - MatchCodeBlock( + {MatchFunctionWithBody( + MatchIfStatement( + MatchCondition(MatchNameReference("a"), MatchConditionEnd()), MatchIfStatement( - MatchCondition(MatchNameReference("a"), + MatchCondition(MatchNameReference("b"), MatchConditionEnd()), - MatchIfStatement( - MatchCondition(MatchNameReference("b"), - MatchConditionEnd()), - MatchExpressionStatement(MatchNameReference("c")), - MatchIfStatementElse(), - MatchExpressionStatement(MatchNameReference("d"))), + MatchExpressionStatement(MatchNameReference("c")), MatchIfStatementElse(), - MatchExpressionStatement(MatchNameReference("e"))), + MatchExpressionStatement(MatchNameReference("d"))), + MatchIfStatementElse(), + MatchExpressionStatement(MatchNameReference("e"))), + MatchIfStatement( + MatchCondition(MatchNameReference("x"), MatchConditionEnd()), + MatchCodeBlock( + MatchExpressionStatement(MatchCallExpression( + MatchNameReference("G"), MatchLiteral("1"), + MatchCallExpressionEnd())), + MatchCodeBlockEnd()), + MatchIfStatementElse(), MatchIfStatement( MatchCondition(MatchNameReference("x"), MatchConditionEnd()), MatchCodeBlock( MatchExpressionStatement(MatchCallExpression( - MatchNameReference("G"), MatchLiteral("1"), + MatchNameReference("G"), MatchLiteral("2"), MatchCallExpressionEnd())), MatchCodeBlockEnd()), MatchIfStatementElse(), - MatchIfStatement( - MatchCondition(MatchNameReference("x"), - MatchConditionEnd()), - MatchCodeBlock( - MatchExpressionStatement(MatchCallExpression( - MatchNameReference("G"), MatchLiteral("2"), - MatchCallExpressionEnd())), - MatchCodeBlockEnd()), - MatchIfStatementElse(), - MatchCodeBlock( - MatchExpressionStatement(MatchCallExpression( - MatchNameReference("G"), MatchLiteral("3"), - MatchCallExpressionEnd())), - MatchCodeBlockEnd()))), - MatchCodeBlockEnd())), + MatchCodeBlock( + MatchExpressionStatement(MatchCallExpression( + MatchNameReference("G"), MatchLiteral("3"), + MatchCallExpressionEnd())), + MatchCodeBlockEnd())))), MatchFileEnd()})); } @@ -622,25 +569,21 @@ TEST_F(ParseTreeTest, IfError) { EXPECT_TRUE(tree.HasErrors()); EXPECT_THAT( - tree, MatchParseTreeNodes( - {MatchFunctionDeclaration( - MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), - MatchCodeBlock( - MatchIfStatement(HasError, MatchNameReference("a"), - MatchCodeBlock(MatchCodeBlockEnd())), - MatchIfStatement( - MatchCondition(HasError, MatchConditionEnd()), - MatchCodeBlock(MatchCodeBlockEnd())), - MatchIfStatement( - MatchCondition(HasError, MatchNameReference("b"), - MatchConditionEnd()), - MatchCodeBlock(MatchCodeBlockEnd())), - MatchIfStatement( - HasError, MatchCondition(MatchNameReference("d"), - MatchConditionEnd())), - MatchCodeBlockEnd())), - MatchFileEnd()})); + tree, + MatchParseTreeNodes( + {MatchFunctionWithBody( + MatchIfStatement(HasError, MatchNameReference("a"), + MatchCodeBlock(MatchCodeBlockEnd())), + MatchIfStatement(MatchCondition(HasError, MatchConditionEnd()), + MatchCodeBlock(MatchCodeBlockEnd())), + MatchIfStatement( + MatchCondition(HasError, MatchNameReference("b"), + MatchConditionEnd()), + MatchCodeBlock(MatchCodeBlockEnd())), + MatchIfStatement(HasError, + MatchCondition(MatchNameReference("d"), + MatchConditionEnd()))), + MatchFileEnd()})); } TEST_F(ParseTreeTest, WhileBreakContinue) { @@ -658,24 +601,17 @@ TEST_F(ParseTreeTest, WhileBreakContinue) { EXPECT_THAT( tree, MatchParseTreeNodes( - {MatchFunctionDeclaration( - MatchDeclaredName("F"), - MatchParameterList(MatchParameterListEnd()), + {MatchFunctionWithBody(MatchWhileStatement( + MatchCondition(MatchNameReference("a"), MatchConditionEnd()), MatchCodeBlock( - MatchWhileStatement( - MatchCondition(MatchNameReference("a"), + MatchIfStatement(MatchCondition(MatchNameReference("b"), + MatchConditionEnd()), + MatchBreakStatement(MatchStatementEnd())), + MatchIfStatement( + MatchCondition(MatchNameReference("c"), MatchConditionEnd()), - MatchCodeBlock( - MatchIfStatement( - MatchCondition(MatchNameReference("b"), - MatchConditionEnd()), - MatchBreakStatement(MatchStatementEnd())), - MatchIfStatement( - MatchCondition(MatchNameReference("c"), - MatchConditionEnd()), - MatchContinueStatement(MatchStatementEnd())), - MatchCodeBlockEnd())), - MatchCodeBlockEnd())), + MatchContinueStatement(MatchStatementEnd())), + MatchCodeBlockEnd()))), MatchFileEnd()})); }