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