1 //===- unittest/ASTMatchers/Dynamic/ParserTest.cpp - Parser unit tests -===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===-------------------------------------------------------------------===//
8 
9 #include "../ASTMatchersTest.h"
10 #include "clang/ASTMatchers/Dynamic/Parser.h"
11 #include "clang/ASTMatchers/Dynamic/Registry.h"
12 #include "llvm/ADT/Optional.h"
13 #include "gtest/gtest.h"
14 #include <string>
15 #include <vector>
16 
17 namespace clang {
18 namespace ast_matchers {
19 namespace dynamic {
20 namespace {
21 
22 class MockSema : public Parser::Sema {
23 public:
~MockSema()24   ~MockSema() override {}
25 
expectMatcher(StringRef MatcherName)26   uint64_t expectMatcher(StringRef MatcherName) {
27     // Optimizations on the matcher framework make simple matchers like
28     // 'stmt()' to be all the same matcher.
29     // Use a more complex expression to prevent that.
30     ast_matchers::internal::Matcher<Stmt> M = stmt(stmt(), stmt());
31     ExpectedMatchers.insert(std::make_pair(std::string(MatcherName), M));
32     return M.getID().second;
33   }
34 
isBuilderMatcher(MatcherCtor) const35   bool isBuilderMatcher(MatcherCtor) const override { return false; }
36 
nodeMatcherType(MatcherCtor) const37   ASTNodeKind nodeMatcherType(MatcherCtor) const override { return {}; }
38 
39   internal::MatcherDescriptorPtr
buildMatcherCtor(MatcherCtor,SourceRange NameRange,ArrayRef<ParserValue> Args,Diagnostics * Error) const40   buildMatcherCtor(MatcherCtor, SourceRange NameRange,
41                    ArrayRef<ParserValue> Args,
42                    Diagnostics *Error) const override {
43     return internal::MatcherDescriptorPtr{nullptr};
44   }
45 
parse(StringRef Code)46   void parse(StringRef Code) {
47     Diagnostics Error;
48     VariantValue Value;
49     Parser::parseExpression(Code, this, &Value, &Error);
50     Values.push_back(Value);
51     Errors.push_back(Error.toStringFull());
52   }
53 
54   llvm::Optional<MatcherCtor>
lookupMatcherCtor(StringRef MatcherName)55   lookupMatcherCtor(StringRef MatcherName) override {
56     const ExpectedMatchersTy::value_type *Matcher =
57         &*ExpectedMatchers.find(std::string(MatcherName));
58     return reinterpret_cast<MatcherCtor>(Matcher);
59   }
60 
actOnMatcherExpression(MatcherCtor Ctor,SourceRange NameRange,StringRef BindID,ArrayRef<ParserValue> Args,Diagnostics * Error)61   VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
62                                         SourceRange NameRange,
63                                         StringRef BindID,
64                                         ArrayRef<ParserValue> Args,
65                                         Diagnostics *Error) override {
66     const ExpectedMatchersTy::value_type *Matcher =
67         reinterpret_cast<const ExpectedMatchersTy::value_type *>(Ctor);
68     MatcherInfo ToStore = {Matcher->first, NameRange, Args,
69                            std::string(BindID)};
70     Matchers.push_back(ToStore);
71     return VariantMatcher::SingleMatcher(Matcher->second);
72   }
73 
74   struct MatcherInfo {
75     StringRef MatcherName;
76     SourceRange NameRange;
77     std::vector<ParserValue> Args;
78     std::string BoundID;
79   };
80 
81   std::vector<std::string> Errors;
82   std::vector<VariantValue> Values;
83   std::vector<MatcherInfo> Matchers;
84   typedef std::map<std::string, ast_matchers::internal::Matcher<Stmt> >
85   ExpectedMatchersTy;
86   ExpectedMatchersTy ExpectedMatchers;
87 };
88 
TEST(ParserTest,ParseBoolean)89 TEST(ParserTest, ParseBoolean) {
90   MockSema Sema;
91   Sema.parse("true");
92   Sema.parse("false");
93   EXPECT_EQ(2U, Sema.Values.size());
94   EXPECT_TRUE(Sema.Values[0].getBoolean());
95   EXPECT_FALSE(Sema.Values[1].getBoolean());
96 }
97 
TEST(ParserTest,ParseDouble)98 TEST(ParserTest, ParseDouble) {
99   MockSema Sema;
100   Sema.parse("1.0");
101   Sema.parse("2.0f");
102   Sema.parse("34.56e-78");
103   Sema.parse("4.E+6");
104   Sema.parse("1");
105   EXPECT_EQ(5U, Sema.Values.size());
106   EXPECT_EQ(1.0, Sema.Values[0].getDouble());
107   EXPECT_EQ("1:1: Error parsing numeric literal: <2.0f>", Sema.Errors[1]);
108   EXPECT_EQ(34.56e-78, Sema.Values[2].getDouble());
109   EXPECT_EQ(4e+6, Sema.Values[3].getDouble());
110   EXPECT_FALSE(Sema.Values[4].isDouble());
111 }
112 
TEST(ParserTest,ParseUnsigned)113 TEST(ParserTest, ParseUnsigned) {
114   MockSema Sema;
115   Sema.parse("0");
116   Sema.parse("123");
117   Sema.parse("0x1f");
118   Sema.parse("12345678901");
119   Sema.parse("1a1");
120   EXPECT_EQ(5U, Sema.Values.size());
121   EXPECT_EQ(0U, Sema.Values[0].getUnsigned());
122   EXPECT_EQ(123U, Sema.Values[1].getUnsigned());
123   EXPECT_EQ(31U, Sema.Values[2].getUnsigned());
124   EXPECT_EQ("1:1: Error parsing numeric literal: <12345678901>", Sema.Errors[3]);
125   EXPECT_EQ("1:1: Error parsing numeric literal: <1a1>", Sema.Errors[4]);
126 }
127 
TEST(ParserTest,ParseString)128 TEST(ParserTest, ParseString) {
129   MockSema Sema;
130   Sema.parse("\"Foo\"");
131   Sema.parse("\"\"");
132   Sema.parse("\"Baz");
133   EXPECT_EQ(3ULL, Sema.Values.size());
134   EXPECT_EQ("Foo", Sema.Values[0].getString());
135   EXPECT_EQ("", Sema.Values[1].getString());
136   EXPECT_EQ("1:1: Error parsing string token: <\"Baz>", Sema.Errors[2]);
137 }
138 
matchesRange(SourceRange Range,unsigned StartLine,unsigned EndLine,unsigned StartColumn,unsigned EndColumn)139 bool matchesRange(SourceRange Range, unsigned StartLine,
140                   unsigned EndLine, unsigned StartColumn, unsigned EndColumn) {
141   EXPECT_EQ(StartLine, Range.Start.Line);
142   EXPECT_EQ(EndLine, Range.End.Line);
143   EXPECT_EQ(StartColumn, Range.Start.Column);
144   EXPECT_EQ(EndColumn, Range.End.Column);
145   return Range.Start.Line == StartLine && Range.End.Line == EndLine &&
146          Range.Start.Column == StartColumn && Range.End.Column == EndColumn;
147 }
148 
getSingleMatcher(const VariantValue & Value)149 llvm::Optional<DynTypedMatcher> getSingleMatcher(const VariantValue &Value) {
150   llvm::Optional<DynTypedMatcher> Result =
151       Value.getMatcher().getSingleMatcher();
152   EXPECT_TRUE(Result);
153   return Result;
154 }
155 
TEST(ParserTest,ParseMatcher)156 TEST(ParserTest, ParseMatcher) {
157   MockSema Sema;
158   const uint64_t ExpectedFoo = Sema.expectMatcher("Foo");
159   const uint64_t ExpectedBar = Sema.expectMatcher("Bar");
160   const uint64_t ExpectedBaz = Sema.expectMatcher("Baz");
161   Sema.parse(" Foo ( Bar ( 17), Baz( \n \"B A,Z\") ) .bind( \"Yo!\") ");
162   for (const auto &E : Sema.Errors) {
163     EXPECT_EQ("", E);
164   }
165 
166   EXPECT_NE(ExpectedFoo, ExpectedBar);
167   EXPECT_NE(ExpectedFoo, ExpectedBaz);
168   EXPECT_NE(ExpectedBar, ExpectedBaz);
169 
170   EXPECT_EQ(1ULL, Sema.Values.size());
171   EXPECT_EQ(ExpectedFoo, getSingleMatcher(Sema.Values[0])->getID().second);
172 
173   EXPECT_EQ(3ULL, Sema.Matchers.size());
174   const MockSema::MatcherInfo Bar = Sema.Matchers[0];
175   EXPECT_EQ("Bar", Bar.MatcherName);
176   EXPECT_TRUE(matchesRange(Bar.NameRange, 1, 1, 8, 17));
177   EXPECT_EQ(1ULL, Bar.Args.size());
178   EXPECT_EQ(17U, Bar.Args[0].Value.getUnsigned());
179 
180   const MockSema::MatcherInfo Baz = Sema.Matchers[1];
181   EXPECT_EQ("Baz", Baz.MatcherName);
182   EXPECT_TRUE(matchesRange(Baz.NameRange, 1, 2, 19, 10));
183   EXPECT_EQ(1ULL, Baz.Args.size());
184   EXPECT_EQ("B A,Z", Baz.Args[0].Value.getString());
185 
186   const MockSema::MatcherInfo Foo = Sema.Matchers[2];
187   EXPECT_EQ("Foo", Foo.MatcherName);
188   EXPECT_TRUE(matchesRange(Foo.NameRange, 1, 2, 2, 12));
189   EXPECT_EQ(2ULL, Foo.Args.size());
190   EXPECT_EQ(ExpectedBar, getSingleMatcher(Foo.Args[0].Value)->getID().second);
191   EXPECT_EQ(ExpectedBaz, getSingleMatcher(Foo.Args[1].Value)->getID().second);
192   EXPECT_EQ("Yo!", Foo.BoundID);
193 }
194 
TEST(ParserTest,ParseComment)195 TEST(ParserTest, ParseComment) {
196   MockSema Sema;
197   Sema.expectMatcher("Foo");
198   Sema.parse(" Foo() # Bar() ");
199   for (const auto &E : Sema.Errors) {
200     EXPECT_EQ("", E);
201   }
202 
203   EXPECT_EQ(1ULL, Sema.Matchers.size());
204 
205   Sema.parse("Foo(#) ");
206 
207   EXPECT_EQ("1:4: Error parsing matcher. Found end-of-code while looking for ')'.", Sema.Errors[1]);
208 }
209 
210 using ast_matchers::internal::Matcher;
211 
getTestNamedValues()212 Parser::NamedValueMap getTestNamedValues() {
213   Parser::NamedValueMap Values;
214   Values["nameX"] = llvm::StringRef("x");
215   Values["hasParamA"] = VariantMatcher::SingleMatcher(
216       functionDecl(hasParameter(0, hasName("a"))));
217   return Values;
218 }
219 
TEST(ParserTest,FullParserTest)220 TEST(ParserTest, FullParserTest) {
221   Diagnostics Error;
222 
223   StringRef Code =
224       "varDecl(hasInitializer(binaryOperator(hasLHS(integerLiteral()),"
225       "                                      hasOperatorName(\"+\"))))";
226   llvm::Optional<DynTypedMatcher> VarDecl(
227       Parser::parseMatcherExpression(Code, &Error));
228   EXPECT_EQ("", Error.toStringFull());
229   Matcher<Decl> M = VarDecl->unconditionalConvertTo<Decl>();
230   EXPECT_TRUE(matches("int x = 1 + false;", M));
231   EXPECT_FALSE(matches("int x = true + 1;", M));
232   EXPECT_FALSE(matches("int x = 1 - false;", M));
233   EXPECT_FALSE(matches("int x = true - 1;", M));
234 
235   Code = "implicitCastExpr(hasCastKind(\"CK_IntegralToBoolean\"))";
236   llvm::Optional<DynTypedMatcher> implicitIntBooleanCast(
237       Parser::parseMatcherExpression(Code, nullptr, nullptr, &Error));
238   EXPECT_EQ("", Error.toStringFull());
239   Matcher<Stmt> MCastStmt =
240       traverse(TK_AsIs, implicitIntBooleanCast->unconditionalConvertTo<Stmt>());
241   EXPECT_TRUE(matches("bool X = 1;", MCastStmt));
242   EXPECT_FALSE(matches("bool X = true;", MCastStmt));
243 
244   Code = "functionDecl(hasParameter(1, hasName(\"x\")))";
245   llvm::Optional<DynTypedMatcher> HasParameter(
246       Parser::parseMatcherExpression(Code, &Error));
247   EXPECT_EQ("", Error.toStringFull());
248   M = HasParameter->unconditionalConvertTo<Decl>();
249 
250   EXPECT_TRUE(matches("void f(int a, int x);", M));
251   EXPECT_FALSE(matches("void f(int x, int a);", M));
252 
253   // Test named values.
254   auto NamedValues = getTestNamedValues();
255 
256   Code = "functionDecl(hasParamA, hasParameter(1, hasName(nameX)))";
257   llvm::Optional<DynTypedMatcher> HasParameterWithNamedValues(
258       Parser::parseMatcherExpression(Code, nullptr, &NamedValues, &Error));
259   EXPECT_EQ("", Error.toStringFull());
260   M = HasParameterWithNamedValues->unconditionalConvertTo<Decl>();
261 
262   EXPECT_TRUE(matches("void f(int a, int x);", M));
263   EXPECT_FALSE(matches("void f(int x, int a);", M));
264 
265   Code = "unaryExprOrTypeTraitExpr(ofKind(\"UETT_SizeOf\"))";
266   llvm::Optional<DynTypedMatcher> UnaryExprSizeOf(
267       Parser::parseMatcherExpression(Code, nullptr, nullptr, &Error));
268   EXPECT_EQ("", Error.toStringFull());
269   Matcher<Stmt> MStmt = UnaryExprSizeOf->unconditionalConvertTo<Stmt>();
270   EXPECT_TRUE(matches("unsigned X = sizeof(int);", MStmt));
271   EXPECT_FALSE(matches("unsigned X = alignof(int);", MStmt));
272 
273   Code =
274       R"query(namedDecl(matchesName("^::[ABC]*$", "IgnoreCase | BasicRegex")))query";
275   llvm::Optional<DynTypedMatcher> MatchesName(
276       Parser::parseMatcherExpression(Code, nullptr, nullptr, &Error));
277   EXPECT_EQ("", Error.toStringFull());
278   M = MatchesName->unconditionalConvertTo<Decl>();
279   EXPECT_TRUE(matches("unsigned AAACCBB;", M));
280   EXPECT_TRUE(matches("unsigned aaaccbb;", M));
281 
282   Code = "hasInitializer(\n    binaryOperator(hasLHS(\"A\")))";
283   EXPECT_TRUE(!Parser::parseMatcherExpression(Code, &Error));
284   EXPECT_EQ("1:1: Error parsing argument 1 for matcher hasInitializer.\n"
285             "2:5: Error parsing argument 1 for matcher binaryOperator.\n"
286             "2:20: Error building matcher hasLHS.\n"
287             "2:27: Incorrect type for arg 1. "
288             "(Expected = Matcher<Expr>) != (Actual = String)",
289             Error.toStringFull());
290 }
291 
TEST(ParserTest,VariadicMatchTest)292 TEST(ParserTest, VariadicMatchTest) {
293   Diagnostics Error;
294 
295   StringRef Code =
296       "stmt(objcMessageExpr(hasAnySelector(\"methodA\", \"methodB:\")))";
297   llvm::Optional<DynTypedMatcher> OM(
298       Parser::parseMatcherExpression(Code, &Error));
299   EXPECT_EQ("", Error.toStringFull());
300   auto M = OM->unconditionalConvertTo<Stmt>();
301   EXPECT_TRUE(matchesObjC("@interface I @end "
302                           "void foo(I* i) { [i methodA]; }", M));
303 }
304 
ParseWithError(StringRef Code)305 std::string ParseWithError(StringRef Code) {
306   Diagnostics Error;
307   VariantValue Value;
308   Parser::parseExpression(Code, &Value, &Error);
309   return Error.toStringFull();
310 }
311 
ParseMatcherWithError(StringRef Code)312 std::string ParseMatcherWithError(StringRef Code) {
313   Diagnostics Error;
314   Parser::parseMatcherExpression(Code, &Error);
315   return Error.toStringFull();
316 }
317 
TEST(ParserTest,Errors)318 TEST(ParserTest, Errors) {
319   EXPECT_EQ(
320       "1:5: Error parsing matcher. Found token <123> while looking for '('.",
321       ParseWithError("Foo 123"));
322   EXPECT_EQ(
323       "1:1: Matcher not found: Foo\n"
324       "1:9: Error parsing matcher. Found token <123> while looking for ','.",
325       ParseWithError("Foo(\"A\" 123)"));
326   EXPECT_EQ(
327       "1:1: Error parsing argument 1 for matcher stmt.\n"
328       "1:6: Value not found: someValue",
329       ParseWithError("stmt(someValue)"));
330   EXPECT_EQ(
331       "1:1: Matcher not found: Foo\n"
332       "1:4: Error parsing matcher. Found end-of-code while looking for ')'.",
333       ParseWithError("Foo("));
334   EXPECT_EQ("1:1: End of code found while looking for token.",
335             ParseWithError(""));
336   EXPECT_EQ("Input value is not a matcher expression.",
337             ParseMatcherWithError("\"A\""));
338   EXPECT_EQ("1:1: Matcher not found: Foo\n"
339             "1:1: Error parsing argument 1 for matcher Foo.\n"
340             "1:5: Invalid token <(> found when looking for a value.",
341             ParseWithError("Foo(("));
342   EXPECT_EQ("1:7: Expected end of code.", ParseWithError("expr()a"));
343   EXPECT_EQ("1:11: Period not followed by valid chained call.",
344             ParseWithError("isArrow().biind"));
345   EXPECT_EQ("1:15: Malformed bind() expression.",
346             ParseWithError("isArrow().bind"));
347   EXPECT_EQ("1:16: Malformed bind() expression.",
348             ParseWithError("isArrow().bind(foo"));
349   EXPECT_EQ("1:21: Malformed bind() expression.",
350             ParseWithError("isArrow().bind(\"foo\""));
351   EXPECT_EQ("1:1: Error building matcher isArrow.\n"
352             "1:1: Matcher does not support binding.",
353             ParseWithError("isArrow().bind(\"foo\")"));
354   EXPECT_EQ("1:1: Error building matcher isArrow.\n"
355             "1:11: Matcher does not support with call.",
356             ParseWithError("isArrow().with"));
357   EXPECT_EQ(
358       "1:22: Error parsing matcher. Found token <EOF> while looking for '('.",
359       ParseWithError("mapAnyOf(ifStmt).with"));
360   EXPECT_EQ(
361       "1:22: Error parsing matcher. Found end-of-code while looking for ')'.",
362       ParseWithError("mapAnyOf(ifStmt).with("));
363   EXPECT_EQ("1:1: Failed to build matcher: mapAnyOf.",
364             ParseWithError("mapAnyOf()"));
365   EXPECT_EQ("1:1: Error parsing argument 1 for matcher mapAnyOf.\n1:1: Failed "
366             "to build matcher: mapAnyOf.",
367             ParseWithError("mapAnyOf(\"foo\")"));
368   EXPECT_EQ("Input value has unresolved overloaded type: "
369             "Matcher<DoStmt|ForStmt|WhileStmt|CXXForRangeStmt|FunctionDecl>",
370             ParseMatcherWithError("hasBody(stmt())"));
371   EXPECT_EQ(
372       "1:1: Error parsing argument 1 for matcher decl.\n"
373       "1:6: Error building matcher hasAttr.\n"
374       "1:14: Unknown value 'attr::Fnal' for arg 1; did you mean 'attr::Final'",
375       ParseMatcherWithError(R"query(decl(hasAttr("attr::Fnal")))query"));
376   EXPECT_EQ("1:1: Error parsing argument 1 for matcher decl.\n"
377             "1:6: Error building matcher hasAttr.\n"
378             "1:14: Unknown value 'Final' for arg 1; did you mean 'attr::Final'",
379             ParseMatcherWithError(R"query(decl(hasAttr("Final")))query"));
380   EXPECT_EQ("1:1: Error parsing argument 1 for matcher decl.\n"
381             "1:6: Error building matcher hasAttr.\n"
382             "1:14: Value not found: unrelated",
383             ParseMatcherWithError(R"query(decl(hasAttr("unrelated")))query"));
384   EXPECT_EQ(
385       "1:1: Error parsing argument 1 for matcher namedDecl.\n"
386       "1:11: Error building matcher matchesName.\n"
387       "1:33: Unknown value 'Ignorecase' for arg 2; did you mean 'IgnoreCase'",
388       ParseMatcherWithError(
389           R"query(namedDecl(matchesName("[ABC]*", "Ignorecase")))query"));
390   EXPECT_EQ(
391       "1:1: Error parsing argument 1 for matcher namedDecl.\n"
392       "1:11: Error building matcher matchesName.\n"
393       "1:33: Value not found: IgnoreCase & BasicRegex",
394       ParseMatcherWithError(
395           R"query(namedDecl(matchesName("[ABC]*", "IgnoreCase & BasicRegex")))query"));
396   EXPECT_EQ(
397       "1:1: Error parsing argument 1 for matcher namedDecl.\n"
398       "1:11: Error building matcher matchesName.\n"
399       "1:33: Unknown value 'IgnoreCase | Basicregex' for arg 2; did you mean "
400       "'IgnoreCase | BasicRegex'",
401       ParseMatcherWithError(
402           R"query(namedDecl(matchesName("[ABC]*", "IgnoreCase | Basicregex")))query"));
403 }
404 
TEST(ParserTest,OverloadErrors)405 TEST(ParserTest, OverloadErrors) {
406   EXPECT_EQ("1:1: Error building matcher callee.\n"
407             "1:8: Candidate 1: Incorrect type for arg 1. "
408             "(Expected = Matcher<Stmt>) != (Actual = String)\n"
409             "1:8: Candidate 2: Incorrect type for arg 1. "
410             "(Expected = Matcher<Decl>) != (Actual = String)",
411             ParseWithError("callee(\"A\")"));
412 }
413 
TEST(ParserTest,ParseMultiline)414 TEST(ParserTest, ParseMultiline) {
415   StringRef Code;
416 
417   llvm::Optional<DynTypedMatcher> M;
418   {
419     Code = R"matcher(varDecl(
420   hasName("foo")
421   )
422 )matcher";
423     Diagnostics Error;
424     EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error));
425   }
426 
427   {
428     Code = R"matcher(varDecl(
429   # Internal comment
430   hasName("foo") # Internal comment
431 # Internal comment
432   )
433 )matcher";
434     Diagnostics Error;
435     EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error));
436   }
437 
438   {
439     Code = R"matcher(decl().bind(
440   "paramName")
441 )matcher";
442     Diagnostics Error;
443     EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error));
444   }
445 
446   {
447     Code = R"matcher(decl().bind(
448   "paramName"
449   )
450 )matcher";
451     Diagnostics Error;
452     EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error).has_value());
453   }
454 
455   {
456     Code = R"matcher(decl(decl()
457 , decl()))matcher";
458     Diagnostics Error;
459     EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error).has_value());
460   }
461 
462   {
463     Code = R"matcher(decl(decl(),
464 decl()))matcher";
465     Diagnostics Error;
466     EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error).has_value());
467   }
468 
469   {
470     Code = "namedDecl(hasName(\"n\"\n))";
471     Diagnostics Error;
472     EXPECT_TRUE(Parser::parseMatcherExpression(Code, &Error).has_value());
473   }
474 
475   {
476     Diagnostics Error;
477 
478     auto NamedValues = getTestNamedValues();
479 
480     Code = R"matcher(hasParamA.bind
481   ("paramName")
482 )matcher";
483     M = Parser::parseMatcherExpression(Code, nullptr, &NamedValues, &Error);
484     EXPECT_FALSE(M);
485     EXPECT_EQ("1:15: Malformed bind() expression.", Error.toStringFull());
486   }
487 
488   {
489     Diagnostics Error;
490 
491     auto NamedValues = getTestNamedValues();
492 
493     Code = R"matcher(hasParamA.
494   bind("paramName")
495 )matcher";
496     M = Parser::parseMatcherExpression(Code, nullptr, &NamedValues, &Error);
497     EXPECT_FALSE(M);
498     EXPECT_EQ("1:11: Period not followed by valid chained call.",
499               Error.toStringFull());
500   }
501 
502   {
503     Diagnostics Error;
504 
505     Code = R"matcher(varDecl
506 ()
507 )matcher";
508     M = Parser::parseMatcherExpression(Code, nullptr, nullptr, &Error);
509     EXPECT_FALSE(M);
510     EXPECT_EQ("1:8: Error parsing matcher. Found token "
511               "<NewLine> while looking for '('.",
512               Error.toStringFull());
513   }
514 
515   // Correct line/column numbers
516   {
517     Diagnostics Error;
518 
519     Code = R"matcher(varDecl(
520   doesNotExist()
521   )
522 )matcher";
523     M = Parser::parseMatcherExpression(Code, nullptr, nullptr, &Error);
524     EXPECT_FALSE(M);
525     StringRef Expected = R"error(1:1: Error parsing argument 1 for matcher varDecl.
526 2:3: Matcher not found: doesNotExist)error";
527     EXPECT_EQ(Expected, Error.toStringFull());
528   }
529 }
530 
TEST(ParserTest,CompletionRegistry)531 TEST(ParserTest, CompletionRegistry) {
532   StringRef Code = "while";
533   std::vector<MatcherCompletion> Comps = Parser::completeExpression(Code, 5);
534   ASSERT_EQ(1u, Comps.size());
535   EXPECT_EQ("Stmt(", Comps[0].TypedText);
536   EXPECT_EQ("Matcher<Stmt> whileStmt(Matcher<WhileStmt>...)",
537             Comps[0].MatcherDecl);
538 
539   Code = "whileStmt().";
540   Comps = Parser::completeExpression(Code, 12);
541   ASSERT_EQ(1u, Comps.size());
542   EXPECT_EQ("bind(\"", Comps[0].TypedText);
543   EXPECT_EQ("bind", Comps[0].MatcherDecl);
544 
545   Code = "mapAny";
546   Comps = Parser::completeExpression(Code, 6);
547   ASSERT_EQ(1u, Comps.size());
548   EXPECT_EQ("Of(", Comps[0].TypedText);
549   EXPECT_EQ("Matcher<NestedNameSpecifierLoc|QualType|TypeLoc|...> "
550             "mapAnyOf(NestedNameSpecifierLoc|QualType|TypeLoc|"
551             "NestedNameSpecifier|Decl|Stmt|Type...)",
552             Comps[0].MatcherDecl);
553 
554   Code = "mapAnyOf(ifStmt).";
555   Comps = Parser::completeExpression(Code, 17);
556   ASSERT_EQ(2u, Comps.size());
557   EXPECT_EQ("bind(\"", Comps[0].TypedText);
558   EXPECT_EQ("bind", Comps[0].MatcherDecl);
559   EXPECT_EQ("with(", Comps[1].TypedText);
560   EXPECT_EQ("with", Comps[1].MatcherDecl);
561 
562   Code = "mapAnyOf(ifS";
563   Comps = Parser::completeExpression(Code, 12);
564   ASSERT_EQ(1u, Comps.size());
565   EXPECT_EQ("tmt", Comps[0].TypedText);
566   EXPECT_EQ("ifStmt", Comps[0].MatcherDecl);
567 }
568 
TEST(ParserTest,CompletionNamedValues)569 TEST(ParserTest, CompletionNamedValues) {
570   // Can complete non-matcher types.
571   auto NamedValues = getTestNamedValues();
572   StringRef Code = "functionDecl(hasName(";
573   std::vector<MatcherCompletion> Comps =
574       Parser::completeExpression(Code, Code.size(), nullptr, &NamedValues);
575   ASSERT_EQ(1u, Comps.size());
576   EXPECT_EQ("nameX", Comps[0].TypedText);
577   EXPECT_EQ("String nameX", Comps[0].MatcherDecl);
578 
579   // Can complete if there are names in the expression.
580   Code = "cxxMethodDecl(hasName(nameX), ";
581   Comps = Parser::completeExpression(Code, Code.size(), nullptr, &NamedValues);
582   EXPECT_LT(0u, Comps.size());
583 
584   // Can complete names and registry together.
585   Code = "functionDecl(hasP";
586   Comps = Parser::completeExpression(Code, Code.size(), nullptr, &NamedValues);
587   ASSERT_EQ(3u, Comps.size());
588 
589   EXPECT_EQ("arameter(", Comps[0].TypedText);
590   EXPECT_EQ(
591       "Matcher<FunctionDecl> hasParameter(unsigned, Matcher<ParmVarDecl>)",
592       Comps[0].MatcherDecl);
593 
594   EXPECT_EQ("aramA", Comps[1].TypedText);
595   EXPECT_EQ("Matcher<Decl> hasParamA", Comps[1].MatcherDecl);
596 
597   EXPECT_EQ("arent(", Comps[2].TypedText);
598   EXPECT_EQ(
599       "Matcher<Decl> "
600       "hasParent(Matcher<NestedNameSpecifierLoc|TypeLoc|Decl|...>)",
601       Comps[2].MatcherDecl);
602 }
603 
TEST(ParserTest,ParseBindOnLet)604 TEST(ParserTest, ParseBindOnLet) {
605 
606   auto NamedValues = getTestNamedValues();
607 
608   Diagnostics Error;
609 
610   {
611     StringRef Code = "hasParamA.bind(\"parmABinding\")";
612     llvm::Optional<DynTypedMatcher> TopLevelLetBinding(
613         Parser::parseMatcherExpression(Code, nullptr, &NamedValues, &Error));
614     EXPECT_EQ("", Error.toStringFull());
615     auto M = TopLevelLetBinding->unconditionalConvertTo<Decl>();
616 
617     EXPECT_TRUE(matchAndVerifyResultTrue(
618         "void foo(int a);", M,
619         std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("parmABinding")));
620     EXPECT_TRUE(matchAndVerifyResultFalse(
621         "void foo(int b);", M,
622         std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("parmABinding")));
623   }
624 
625   {
626     StringRef Code = "functionDecl(hasParamA.bind(\"parmABinding\"))";
627     llvm::Optional<DynTypedMatcher> NestedLetBinding(
628         Parser::parseMatcherExpression(Code, nullptr, &NamedValues, &Error));
629     EXPECT_EQ("", Error.toStringFull());
630     auto M = NestedLetBinding->unconditionalConvertTo<Decl>();
631 
632     EXPECT_TRUE(matchAndVerifyResultTrue(
633         "void foo(int a);", M,
634         std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("parmABinding")));
635     EXPECT_TRUE(matchAndVerifyResultFalse(
636         "void foo(int b);", M,
637         std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("parmABinding")));
638   }
639 }
640 
641 }  // end anonymous namespace
642 }  // end namespace dynamic
643 }  // end namespace ast_matchers
644 }  // end namespace clang
645