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