1 //===- unittest/ASTMatchers/Dynamic/ParserTest.cpp - Parser unit tests -===//
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
7 //===-------------------------------------------------------------------===//
9 #include "../ASTMatchersTest.h"
10 #include "clang/ASTMatchers/Dynamic/Parser.h"
11 #include "clang/ASTMatchers/Dynamic/Registry.h"
12 #include "gtest/gtest.h"
18 namespace ast_matchers
{
22 class MockSema
: public Parser::Sema
{
24 ~MockSema() override
{}
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
;
35 bool isBuilderMatcher(MatcherCtor
) const override
{ return false; }
37 ASTNodeKind
nodeMatcherType(MatcherCtor
) const override
{ return {}; }
39 internal::MatcherDescriptorPtr
40 buildMatcherCtor(MatcherCtor
, SourceRange NameRange
,
41 ArrayRef
<ParserValue
> Args
,
42 Diagnostics
*Error
) const override
{
43 return internal::MatcherDescriptorPtr
{nullptr};
46 void parse(StringRef Code
) {
49 Parser::parseExpression(Code
, this, &Value
, &Error
);
50 Values
.push_back(Value
);
51 Errors
.push_back(Error
.toStringFull());
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
);
60 VariantMatcher
actOnMatcherExpression(MatcherCtor Ctor
,
61 SourceRange NameRange
,
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
,
69 Matchers
.push_back(ToStore
);
70 return VariantMatcher::SingleMatcher(Matcher
->second
);
74 StringRef MatcherName
;
75 SourceRange NameRange
;
76 std::vector
<ParserValue
> Args
;
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
> >
85 ExpectedMatchersTy ExpectedMatchers
;
88 TEST(ParserTest
, ParseBoolean
) {
92 EXPECT_EQ(2U, Sema
.Values
.size());
93 EXPECT_TRUE(Sema
.Values
[0].getBoolean());
94 EXPECT_FALSE(Sema
.Values
[1].getBoolean());
97 TEST(ParserTest
, ParseDouble
) {
101 Sema
.parse("34.56e-78");
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());
112 TEST(ParserTest
, ParseUnsigned
) {
117 Sema
.parse("12345678901");
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]);
127 TEST(ParserTest
, ParseString
) {
129 Sema
.parse("\"Foo\"");
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]);
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
;
148 std::optional
<DynTypedMatcher
> getSingleMatcher(const VariantValue
&Value
) {
149 std::optional
<DynTypedMatcher
> Result
= Value
.getMatcher().getSingleMatcher();
154 TEST(ParserTest
, ParseMatcher
) {
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
) {
164 EXPECT_NE(ExpectedFoo
, ExpectedBar
);
165 EXPECT_NE(ExpectedFoo
, ExpectedBaz
);
166 EXPECT_NE(ExpectedBar
, ExpectedBaz
);
168 EXPECT_EQ(1ULL, Sema
.Values
.size());
169 EXPECT_EQ(ExpectedFoo
, getSingleMatcher(Sema
.Values
[0])->getID().second
);
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());
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());
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
);
193 TEST(ParserTest
, ParseComment
) {
195 Sema
.expectMatcher("Foo");
196 Sema
.parse(" Foo() # Bar() ");
197 for (const auto &E
: Sema
.Errors
) {
201 EXPECT_EQ(1ULL, Sema
.Matchers
.size());
203 Sema
.parse("Foo(#) ");
205 EXPECT_EQ("1:4: Error parsing matcher. Found end-of-code while looking for ')'.", Sema
.Errors
[1]);
208 using ast_matchers::internal::Matcher
;
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"))));
218 TEST(ParserTest
, FullParserTest
) {
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
));
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
));
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
>();
248 EXPECT_TRUE(matches("void f(int a, int x);", M
));
249 EXPECT_FALSE(matches("void f(int x, int a);", M
));
251 // Test named values.
252 auto NamedValues
= getTestNamedValues();
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
>();
260 EXPECT_TRUE(matches("void f(int a, int x);", M
));
261 EXPECT_FALSE(matches("void f(int x, int a);", M
));
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
));
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
));
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());
290 TEST(ParserTest
, VariadicMatchTest
) {
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
));
303 std::string
ParseWithError(StringRef Code
) {
306 Parser::parseExpression(Code
, &Value
, &Error
);
307 return Error
.toStringFull();
310 std::string
ParseMatcherWithError(StringRef Code
) {
312 Parser::parseMatcherExpression(Code
, &Error
);
313 return Error
.toStringFull();
316 TEST(ParserTest
, Errors
) {
318 "1:5: Error parsing matcher. Found token <123> while looking for '('.",
319 ParseWithError("Foo 123"));
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)"));
325 "1:1: Error parsing argument 1 for matcher stmt.\n"
326 "1:6: Value not found: someValue",
327 ParseWithError("stmt(someValue)"));
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.",
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"));
356 "1:22: Error parsing matcher. Found token <EOF> while looking for '('.",
357 ParseWithError("mapAnyOf(ifStmt).with"));
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())"));
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"));
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"));
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"));
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"));
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\")"));
413 TEST(ParserTest
, ParseMultiline
) {
416 std::optional
<DynTypedMatcher
> M
;
418 Code
= R
"matcher(varDecl(
423 EXPECT_TRUE(Parser::parseMatcherExpression(Code
, &Error
));
427 Code
= R
"matcher(varDecl(
429 hasName("foo
") # Internal comment
434 EXPECT_TRUE(Parser::parseMatcherExpression(Code
, &Error
));
438 Code
= R
"matcher(decl().bind(
442 EXPECT_TRUE(Parser::parseMatcherExpression(Code
, &Error
));
446 Code
= R
"matcher(decl().bind(
451 EXPECT_TRUE(Parser::parseMatcherExpression(Code
, &Error
).has_value());
455 Code
= R
"matcher(decl(decl()
458 EXPECT_TRUE(Parser::parseMatcherExpression(Code
, &Error
).has_value());
462 Code
= R
"matcher(decl(decl(),
465 EXPECT_TRUE(Parser::parseMatcherExpression(Code
, &Error
).has_value());
469 Code
= "namedDecl(hasName(\"n\"\n))";
471 EXPECT_TRUE(Parser::parseMatcherExpression(Code
, &Error
).has_value());
477 auto NamedValues
= getTestNamedValues();
479 Code
= R
"matcher(hasParamA.bind
482 M
= Parser::parseMatcherExpression(Code
, nullptr, &NamedValues
, &Error
);
484 EXPECT_EQ("1:15: Malformed bind() expression.", Error
.toStringFull());
490 auto NamedValues
= getTestNamedValues();
492 Code
= R
"matcher(hasParamA.
495 M
= Parser::parseMatcherExpression(Code
, nullptr, &NamedValues
, &Error
);
497 EXPECT_EQ("1:11: Period not followed by valid chained call.",
498 Error
.toStringFull());
504 Code
= R
"matcher(varDecl
507 M
= Parser::parseMatcherExpression(Code
, nullptr, nullptr, &Error
);
509 EXPECT_EQ("1:8: Error parsing matcher. Found token "
510 "<NewLine> while looking for '('.",
511 Error
.toStringFull());
514 // Correct line/column numbers
518 Code
= R
"matcher(varDecl(
522 M
= Parser::parseMatcherExpression(Code
, nullptr, nullptr, &Error
);
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());
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
);
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
);
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
);
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
);
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
);
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
);
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());
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());
588 EXPECT_EQ("arameter(", Comps
[0].TypedText
);
590 "Matcher<FunctionDecl> hasParameter(unsigned, Matcher<ParmVarDecl>)",
591 Comps
[0].MatcherDecl
);
593 EXPECT_EQ("aramA", Comps
[1].TypedText
);
594 EXPECT_EQ("Matcher<Decl> hasParamA", Comps
[1].MatcherDecl
);
596 EXPECT_EQ("arent(", Comps
[2].TypedText
);
599 "hasParent(Matcher<NestedNameSpecifierLoc|TypeLoc|Decl|...>)",
600 Comps
[2].MatcherDecl
);
603 TEST(ParserTest
, ParseBindOnLet
) {
605 auto NamedValues
= getTestNamedValues();
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
>();
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")));
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
>();
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")));
640 } // end anonymous namespace
641 } // end namespace dynamic
642 } // end namespace ast_matchers
643 } // end namespace clang