summaryrefslogtreecommitdiffstats
path: root/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2019-12-18 22:35:46 +0000
committerStephen Kelly <steveire@gmail.com>2019-12-27 15:25:57 +0000
commitf0722333dd167245eb3c2b4263529a1ce3679b5c (patch)
treee2bb3191dedf0f83247cbd6eedb7cf8af92d3f82 /clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp
parent2abda66848e5b7f502f978f030254118ec6751d6 (diff)
downloadbcm5719-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.cpp165
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>();
OpenPOWER on IntegriCloud