diff options
author | Stephen Kelly <steveire@gmail.com> | 2019-12-18 22:35:46 +0000 |
---|---|---|
committer | Stephen Kelly <steveire@gmail.com> | 2019-12-27 15:25:57 +0000 |
commit | f0722333dd167245eb3c2b4263529a1ce3679b5c (patch) | |
tree | e2bb3191dedf0f83247cbd6eedb7cf8af92d3f82 /clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp | |
parent | 2abda66848e5b7f502f978f030254118ec6751d6 (diff) | |
download | bcm5719-llvm-f0722333dd167245eb3c2b4263529a1ce3679b5c.tar.gz bcm5719-llvm-f0722333dd167245eb3c2b4263529a1ce3679b5c.zip |
Allow newlines in AST Matchers in clang-query files
Reviewers: aaron.ballman
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71842
Diffstat (limited to 'clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp')
-rw-r--r-- | clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp | 165 |
1 files changed, 142 insertions, 23 deletions
diff --git a/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp index db16ca41875..67fc7079029 100644 --- a/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp +++ b/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp @@ -207,10 +207,12 @@ Parser::NamedValueMap getTestNamedValues() { TEST(ParserTest, FullParserTest) { Diagnostics Error; - llvm::Optional<DynTypedMatcher> VarDecl(Parser::parseMatcherExpression( + + StringRef Code = "varDecl(hasInitializer(binaryOperator(hasLHS(integerLiteral())," - " hasOperatorName(\"+\"))))", - &Error)); + " hasOperatorName(\"+\"))))"; + llvm::Optional<DynTypedMatcher> VarDecl( + Parser::parseMatcherExpression(Code, &Error)); EXPECT_EQ("", Error.toStringFull()); Matcher<Decl> M = VarDecl->unconditionalConvertTo<Decl>(); EXPECT_TRUE(matches("int x = 1 + false;", M)); @@ -218,8 +220,9 @@ TEST(ParserTest, FullParserTest) { EXPECT_FALSE(matches("int x = 1 - false;", M)); EXPECT_FALSE(matches("int x = true - 1;", M)); - llvm::Optional<DynTypedMatcher> HasParameter(Parser::parseMatcherExpression( - "functionDecl(hasParameter(1, hasName(\"x\")))", &Error)); + Code = "functionDecl(hasParameter(1, hasName(\"x\")))"; + llvm::Optional<DynTypedMatcher> HasParameter( + Parser::parseMatcherExpression(Code, &Error)); EXPECT_EQ("", Error.toStringFull()); M = HasParameter->unconditionalConvertTo<Decl>(); @@ -228,20 +231,18 @@ TEST(ParserTest, FullParserTest) { // Test named values. auto NamedValues = getTestNamedValues(); + + Code = "functionDecl(hasParamA, hasParameter(1, hasName(nameX)))"; llvm::Optional<DynTypedMatcher> HasParameterWithNamedValues( - Parser::parseMatcherExpression( - "functionDecl(hasParamA, hasParameter(1, hasName(nameX)))", - nullptr, &NamedValues, &Error)); + Parser::parseMatcherExpression(Code, nullptr, &NamedValues, &Error)); EXPECT_EQ("", Error.toStringFull()); M = HasParameterWithNamedValues->unconditionalConvertTo<Decl>(); EXPECT_TRUE(matches("void f(int a, int x);", M)); EXPECT_FALSE(matches("void f(int x, int a);", M)); - - EXPECT_TRUE(!Parser::parseMatcherExpression( - "hasInitializer(\n binaryOperator(hasLHS(\"A\")))", - &Error).hasValue()); + Code = "hasInitializer(\n binaryOperator(hasLHS(\"A\")))"; + EXPECT_TRUE(!Parser::parseMatcherExpression(Code, &Error).hasValue()); EXPECT_EQ("1:1: Error parsing argument 1 for matcher hasInitializer.\n" "2:5: Error parsing argument 1 for matcher binaryOperator.\n" "2:20: Error building matcher hasLHS.\n" @@ -252,9 +253,11 @@ TEST(ParserTest, FullParserTest) { TEST(ParserTest, VariadicMatchTest) { Diagnostics Error; - llvm::Optional<DynTypedMatcher> OM(Parser::parseMatcherExpression( - "stmt(objcMessageExpr(hasAnySelector(\"methodA\", \"methodB:\")))", - &Error)); + + StringRef Code = + "stmt(objcMessageExpr(hasAnySelector(\"methodA\", \"methodB:\")))"; + llvm::Optional<DynTypedMatcher> OM( + Parser::parseMatcherExpression(Code, &Error)); EXPECT_EQ("", Error.toStringFull()); auto M = OM->unconditionalConvertTo<Stmt>(); EXPECT_TRUE(matchesObjC("@interface I @end " @@ -324,15 +327,132 @@ TEST(ParserTest, OverloadErrors) { ParseWithError("callee(\"A\")")); } +TEST(ParserTest, ParseMultiline) { + StringRef Code; + + llvm::Optional<DynTypedMatcher> M; + { + Code = R"matcher(varDecl( + hasName("foo") + ) +)matcher"; + Diagnostics Error; + EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error).hasValue()); + } + + { + Code = R"matcher(varDecl( + # Internal comment + hasName("foo") # Internal comment +# Internal comment + ) +)matcher"; + Diagnostics Error; + EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error).hasValue()); + } + + { + Code = R"matcher(decl().bind( + "paramName") +)matcher"; + Diagnostics Error; + EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error).hasValue()); + } + + { + Code = R"matcher(decl().bind( + "paramName" + ) +)matcher"; + Diagnostics Error; + EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error).hasValue()); + } + + { + Code = R"matcher(decl(decl() +, decl()))matcher"; + Diagnostics Error; + EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error).hasValue()); + } + + { + Code = R"matcher(decl(decl(), +decl()))matcher"; + Diagnostics Error; + EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error).hasValue()); + } + + { + Code = "namedDecl(hasName(\"n\"\n))"; + Diagnostics Error; + EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error).hasValue()); + } + + { + Diagnostics Error; + + auto NamedValues = getTestNamedValues(); + + Code = R"matcher(hasParamA.bind + ("paramName") +)matcher"; + M = Parser::parseMatcherExpression(Code, nullptr, &NamedValues, &Error); + EXPECT_FALSE(M.hasValue()); + EXPECT_EQ("1:15: Malformed bind() expression.", Error.toStringFull()); + } + + { + Diagnostics Error; + + auto NamedValues = getTestNamedValues(); + + Code = R"matcher(hasParamA. + bind("paramName") +)matcher"; + M = Parser::parseMatcherExpression(Code, nullptr, &NamedValues, &Error); + EXPECT_FALSE(M.hasValue()); + EXPECT_EQ("1:11: Malformed bind() expression.", Error.toStringFull()); + } + + { + Diagnostics Error; + + Code = R"matcher(varDecl +() +)matcher"; + M = Parser::parseMatcherExpression(Code, nullptr, nullptr, &Error); + EXPECT_FALSE(M.hasValue()); + EXPECT_EQ("1:8: Error parsing matcher. Found token " + "<NewLine> while looking for '('.", + Error.toStringFull()); + } + + // Correct line/column numbers + { + Diagnostics Error; + + Code = R"matcher(varDecl( + doesNotExist() + ) +)matcher"; + M = Parser::parseMatcherExpression(Code, nullptr, nullptr, &Error); + EXPECT_FALSE(M.hasValue()); + EXPECT_EQ(R"error(1:1: Error parsing argument 1 for matcher varDecl. +2:3: Matcher not found: doesNotExist)error", + Error.toStringFull()); + } +} + TEST(ParserTest, CompletionRegistry) { - std::vector<MatcherCompletion> Comps = - Parser::completeExpression("while", 5); + StringRef Code = "while"; + std::vector<MatcherCompletion> Comps = Parser::completeExpression(Code, 5); ASSERT_EQ(1u, Comps.size()); EXPECT_EQ("Stmt(", Comps[0].TypedText); EXPECT_EQ("Matcher<Stmt> whileStmt(Matcher<WhileStmt>...)", Comps[0].MatcherDecl); - Comps = Parser::completeExpression("whileStmt().", 12); + Code = "whileStmt()."; + Comps = Parser::completeExpression(Code, 12); ASSERT_EQ(1u, Comps.size()); EXPECT_EQ("bind(\"", Comps[0].TypedText); EXPECT_EQ("bind", Comps[0].MatcherDecl); @@ -380,9 +500,9 @@ TEST(ParserTest, ParseBindOnLet) { Diagnostics Error; { + StringRef Code = "hasParamA.bind(\"parmABinding\")"; llvm::Optional<DynTypedMatcher> TopLevelLetBinding( - Parser::parseMatcherExpression("hasParamA.bind(\"parmABinding\")", - nullptr, &NamedValues, &Error)); + Parser::parseMatcherExpression(Code, nullptr, &NamedValues, &Error)); EXPECT_EQ("", Error.toStringFull()); auto M = TopLevelLetBinding->unconditionalConvertTo<Decl>(); @@ -395,10 +515,9 @@ TEST(ParserTest, ParseBindOnLet) { } { + StringRef Code = "functionDecl(hasParamA.bind(\"parmABinding\"))"; llvm::Optional<DynTypedMatcher> NestedLetBinding( - Parser::parseMatcherExpression( - "functionDecl(hasParamA.bind(\"parmABinding\"))", nullptr, - &NamedValues, &Error)); + Parser::parseMatcherExpression(Code, nullptr, &NamedValues, &Error)); EXPECT_EQ("", Error.toStringFull()); auto M = NestedLetBinding->unconditionalConvertTo<Decl>(); |