blob: 150f8c929c96fbc9936682a653137f9a54d706da [file] [log] [blame]
Manuel Klimekf7f295f2013-05-14 09:13:00 +00001//===- unittest/ASTMatchers/Dynamic/RegistryTest.cpp - Registry unit tests -===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===-----------------------------------------------------------------------===//
9
Manuel Klimekf7f295f2013-05-14 09:13:00 +000010#include "../ASTMatchersTest.h"
11#include "clang/ASTMatchers/Dynamic/Registry.h"
12#include "gtest/gtest.h"
Stephen Hines651f13c2014-04-23 16:59:28 -070013#include <vector>
Manuel Klimekf7f295f2013-05-14 09:13:00 +000014
15namespace clang {
16namespace ast_matchers {
17namespace dynamic {
18namespace {
19
20using ast_matchers::internal::Matcher;
21
Samuel Benzaquen76c2f922013-06-20 14:28:32 +000022class RegistryTest : public ::testing::Test {
23public:
24 std::vector<ParserValue> Args() { return std::vector<ParserValue>(); }
25 std::vector<ParserValue> Args(const VariantValue &Arg1) {
26 std::vector<ParserValue> Out(1);
27 Out[0].Value = Arg1;
28 return Out;
29 }
30 std::vector<ParserValue> Args(const VariantValue &Arg1,
31 const VariantValue &Arg2) {
32 std::vector<ParserValue> Out(2);
33 Out[0].Value = Arg1;
34 Out[1].Value = Arg2;
35 return Out;
36 }
Manuel Klimekf7f295f2013-05-14 09:13:00 +000037
Stephen Hines651f13c2014-04-23 16:59:28 -070038 llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName,
39 Diagnostics *Error = 0) {
40 Diagnostics DummyError;
41 if (!Error) Error = &DummyError;
42 llvm::Optional<MatcherCtor> Ctor =
43 Registry::lookupMatcherCtor(MatcherName, SourceRange(), Error);
44 EXPECT_EQ("", DummyError.toStringFull());
45 return Ctor;
46 }
47
Samuel Benzaquen9d028072013-08-13 14:54:51 +000048 VariantMatcher constructMatcher(StringRef MatcherName,
49 Diagnostics *Error = NULL) {
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +000050 Diagnostics DummyError;
51 if (!Error) Error = &DummyError;
Stephen Hines651f13c2014-04-23 16:59:28 -070052 llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName, Error);
53 VariantMatcher Out;
54 if (Ctor)
55 Out = Registry::constructMatcher(*Ctor, SourceRange(), Args(), Error);
Samuel Benzaquen2f5a2312013-07-19 20:02:35 +000056 EXPECT_EQ("", DummyError.toStringFull());
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +000057 return Out;
Samuel Benzaquen76c2f922013-06-20 14:28:32 +000058 }
Manuel Klimekf7f295f2013-05-14 09:13:00 +000059
Samuel Benzaquen9d028072013-08-13 14:54:51 +000060 VariantMatcher constructMatcher(StringRef MatcherName,
61 const VariantValue &Arg1,
62 Diagnostics *Error = NULL) {
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +000063 Diagnostics DummyError;
64 if (!Error) Error = &DummyError;
Stephen Hines651f13c2014-04-23 16:59:28 -070065 llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName, Error);
66 VariantMatcher Out;
67 if (Ctor)
68 Out = Registry::constructMatcher(*Ctor, SourceRange(), Args(Arg1), Error);
69 EXPECT_EQ("", DummyError.toStringFull()) << MatcherName;
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +000070 return Out;
Samuel Benzaquen76c2f922013-06-20 14:28:32 +000071 }
Manuel Klimekf7f295f2013-05-14 09:13:00 +000072
Samuel Benzaquen9d028072013-08-13 14:54:51 +000073 VariantMatcher constructMatcher(StringRef MatcherName,
74 const VariantValue &Arg1,
75 const VariantValue &Arg2,
76 Diagnostics *Error = NULL) {
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +000077 Diagnostics DummyError;
78 if (!Error) Error = &DummyError;
Stephen Hines651f13c2014-04-23 16:59:28 -070079 llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName, Error);
80 VariantMatcher Out;
81 if (Ctor)
82 Out = Registry::constructMatcher(*Ctor, SourceRange(), Args(Arg1, Arg2),
83 Error);
Samuel Benzaquen2f5a2312013-07-19 20:02:35 +000084 EXPECT_EQ("", DummyError.toStringFull());
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +000085 return Out;
Samuel Benzaquen76c2f922013-06-20 14:28:32 +000086 }
Stephen Hines651f13c2014-04-23 16:59:28 -070087
88 typedef std::vector<MatcherCompletion> CompVector;
89
90 CompVector getCompletions() {
91 return Registry::getCompletions(
92 llvm::ArrayRef<std::pair<MatcherCtor, unsigned> >());
93 }
94
95 CompVector getCompletions(StringRef MatcherName1, unsigned ArgNo1) {
96 std::vector<std::pair<MatcherCtor, unsigned> > Context;
97 llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName1);
98 if (!Ctor)
99 return CompVector();
100 Context.push_back(std::make_pair(*Ctor, ArgNo1));
101 return Registry::getCompletions(Context);
102 }
103
104 CompVector getCompletions(StringRef MatcherName1, unsigned ArgNo1,
105 StringRef MatcherName2, unsigned ArgNo2) {
106 std::vector<std::pair<MatcherCtor, unsigned> > Context;
107 llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName1);
108 if (!Ctor)
109 return CompVector();
110 Context.push_back(std::make_pair(*Ctor, ArgNo1));
111 Ctor = lookupMatcherCtor(MatcherName2);
112 if (!Ctor)
113 return CompVector();
114 Context.push_back(std::make_pair(*Ctor, ArgNo2));
115 return Registry::getCompletions(Context);
116 }
117
118 bool hasCompletion(const CompVector &Comps, StringRef TypedText,
119 StringRef MatcherDecl = StringRef(), unsigned *Index = 0) {
120 for (CompVector::const_iterator I = Comps.begin(), E = Comps.end(); I != E;
121 ++I) {
122 if (I->TypedText == TypedText &&
123 (MatcherDecl.empty() || I->MatcherDecl == MatcherDecl)) {
124 if (Index)
125 *Index = I - Comps.begin();
126 return true;
127 }
128 }
129 return false;
130 }
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000131};
132
133TEST_F(RegistryTest, CanConstructNoArgs) {
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +0000134 Matcher<Stmt> IsArrowValue = constructMatcher(
135 "memberExpr", constructMatcher("isArrow")).getTypedMatcher<Stmt>();
136 Matcher<Stmt> BoolValue =
137 constructMatcher("boolLiteral").getTypedMatcher<Stmt>();
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000138
139 const std::string ClassSnippet = "struct Foo { int x; };\n"
140 "Foo *foo = new Foo;\n"
141 "int i = foo->x;\n";
142 const std::string BoolSnippet = "bool Foo = true;\n";
143
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000144 EXPECT_TRUE(matches(ClassSnippet, IsArrowValue));
145 EXPECT_TRUE(matches(BoolSnippet, BoolValue));
146 EXPECT_FALSE(matches(ClassSnippet, BoolValue));
147 EXPECT_FALSE(matches(BoolSnippet, IsArrowValue));
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000148}
149
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000150TEST_F(RegistryTest, ConstructWithSimpleArgs) {
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +0000151 Matcher<Decl> Value = constructMatcher(
152 "namedDecl", constructMatcher("hasName", std::string("X")))
153 .getTypedMatcher<Decl>();
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000154 EXPECT_TRUE(matches("class X {};", Value));
155 EXPECT_FALSE(matches("int x;", Value));
Samuel Benzaquen7a337af2013-06-04 15:46:22 +0000156
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +0000157 Value = functionDecl(constructMatcher("parameterCountIs", 2)
158 .getTypedMatcher<FunctionDecl>());
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000159 EXPECT_TRUE(matches("void foo(int,int);", Value));
160 EXPECT_FALSE(matches("void foo(int);", Value));
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000161}
162
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000163TEST_F(RegistryTest, ConstructWithMatcherArgs) {
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000164 Matcher<Decl> HasInitializerSimple = constructMatcher(
165 "varDecl", constructMatcher("hasInitializer", constructMatcher("stmt")))
166 .getTypedMatcher<Decl>();
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +0000167 Matcher<Decl> HasInitializerComplex = constructMatcher(
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000168 "varDecl",
169 constructMatcher("hasInitializer", constructMatcher("callExpr")))
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +0000170 .getTypedMatcher<Decl>();
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000171
172 std::string code = "int i;";
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000173 EXPECT_FALSE(matches(code, HasInitializerSimple));
174 EXPECT_FALSE(matches(code, HasInitializerComplex));
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000175
176 code = "int i = 1;";
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000177 EXPECT_TRUE(matches(code, HasInitializerSimple));
178 EXPECT_FALSE(matches(code, HasInitializerComplex));
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000179
180 code = "int y(); int i = y();";
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000181 EXPECT_TRUE(matches(code, HasInitializerSimple));
182 EXPECT_TRUE(matches(code, HasInitializerComplex));
Samuel Benzaquen7a337af2013-06-04 15:46:22 +0000183
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000184 Matcher<Decl> HasParameter =
185 functionDecl(constructMatcher(
186 "hasParameter", 1, constructMatcher("hasName", std::string("x")))
187 .getTypedMatcher<FunctionDecl>());
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000188 EXPECT_TRUE(matches("void f(int a, int x);", HasParameter));
189 EXPECT_FALSE(matches("void f(int x, int a);", HasParameter));
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000190}
191
Samuel Benzaquen0e1896a2013-07-22 16:13:57 +0000192TEST_F(RegistryTest, OverloadedMatchers) {
193 Matcher<Stmt> CallExpr0 = constructMatcher(
194 "callExpr",
195 constructMatcher("callee", constructMatcher("memberExpr",
196 constructMatcher("isArrow"))))
197 .getTypedMatcher<Stmt>();
198
199 Matcher<Stmt> CallExpr1 = constructMatcher(
200 "callExpr",
201 constructMatcher(
202 "callee",
203 constructMatcher("methodDecl",
204 constructMatcher("hasName", std::string("x")))))
205 .getTypedMatcher<Stmt>();
206
207 std::string Code = "class Y { public: void x(); }; void z() { Y y; y.x(); }";
208 EXPECT_FALSE(matches(Code, CallExpr0));
209 EXPECT_TRUE(matches(Code, CallExpr1));
210
211 Code = "class Z { public: void z() { this->z(); } };";
212 EXPECT_TRUE(matches(Code, CallExpr0));
213 EXPECT_FALSE(matches(Code, CallExpr1));
Stephen Hines651f13c2014-04-23 16:59:28 -0700214
215 Matcher<Decl> DeclDecl = declaratorDecl(hasTypeLoc(
216 constructMatcher(
217 "loc", constructMatcher("asString", std::string("const double *")))
218 .getTypedMatcher<TypeLoc>()));
219
220 Matcher<NestedNameSpecifierLoc> NNSL =
221 constructMatcher(
222 "loc", VariantMatcher::SingleMatcher(nestedNameSpecifier(
223 specifiesType(hasDeclaration(recordDecl(hasName("A")))))))
224 .getTypedMatcher<NestedNameSpecifierLoc>();
225
226 Code = "const double * x = 0;";
227 EXPECT_TRUE(matches(Code, DeclDecl));
228 EXPECT_FALSE(matches(Code, NNSL));
229
230 Code = "struct A { struct B {}; }; A::B a_b;";
231 EXPECT_FALSE(matches(Code, DeclDecl));
232 EXPECT_TRUE(matches(Code, NNSL));
Samuel Benzaquen0e1896a2013-07-22 16:13:57 +0000233}
234
Samuel Benzaquenef7eb022013-06-21 15:51:31 +0000235TEST_F(RegistryTest, PolymorphicMatchers) {
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000236 const VariantMatcher IsDefinition = constructMatcher("isDefinition");
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +0000237 Matcher<Decl> Var =
238 constructMatcher("varDecl", IsDefinition).getTypedMatcher<Decl>();
Samuel Benzaquenef7eb022013-06-21 15:51:31 +0000239 Matcher<Decl> Class =
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +0000240 constructMatcher("recordDecl", IsDefinition).getTypedMatcher<Decl>();
Samuel Benzaquenef7eb022013-06-21 15:51:31 +0000241 Matcher<Decl> Func =
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +0000242 constructMatcher("functionDecl", IsDefinition).getTypedMatcher<Decl>();
Samuel Benzaquenef7eb022013-06-21 15:51:31 +0000243 EXPECT_TRUE(matches("int a;", Var));
244 EXPECT_FALSE(matches("extern int a;", Var));
245 EXPECT_TRUE(matches("class A {};", Class));
246 EXPECT_FALSE(matches("class A;", Class));
247 EXPECT_TRUE(matches("void f(){};", Func));
248 EXPECT_FALSE(matches("void f();", Func));
249
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +0000250 Matcher<Decl> Anything = constructMatcher("anything").getTypedMatcher<Decl>();
Samuel Benzaquenb80aad82013-08-29 15:39:26 +0000251 Matcher<Decl> RecordDecl = constructMatcher(
252 "recordDecl", constructMatcher("hasName", std::string("Foo")),
253 VariantMatcher::SingleMatcher(Anything)).getTypedMatcher<Decl>();
Samuel Benzaquenef7eb022013-06-21 15:51:31 +0000254
Samuel Benzaquenb80aad82013-08-29 15:39:26 +0000255 EXPECT_TRUE(matches("int Foo;", Anything));
256 EXPECT_TRUE(matches("class Foo {};", Anything));
257 EXPECT_TRUE(matches("void Foo(){};", Anything));
258 EXPECT_FALSE(matches("int Foo;", RecordDecl));
259 EXPECT_TRUE(matches("class Foo {};", RecordDecl));
260 EXPECT_FALSE(matches("void Foo(){};", RecordDecl));
Samuel Benzaquen6c1dc782013-11-18 14:53:42 +0000261
262 Matcher<Stmt> ConstructExpr = constructMatcher(
263 "constructExpr",
264 constructMatcher(
265 "hasDeclaration",
266 constructMatcher(
267 "methodDecl",
268 constructMatcher(
269 "ofClass", constructMatcher("hasName", std::string("Foo"))))))
270 .getTypedMatcher<Stmt>();
271 EXPECT_FALSE(matches("class Foo { public: Foo(); };", ConstructExpr));
272 EXPECT_TRUE(
273 matches("class Foo { public: Foo(); }; Foo foo = Foo();", ConstructExpr));
Samuel Benzaquenef7eb022013-06-21 15:51:31 +0000274}
275
Samuel Benzaquen671840a2013-07-17 15:11:30 +0000276TEST_F(RegistryTest, TemplateArgument) {
277 Matcher<Decl> HasTemplateArgument = constructMatcher(
278 "classTemplateSpecializationDecl",
279 constructMatcher(
280 "hasAnyTemplateArgument",
281 constructMatcher("refersToType",
282 constructMatcher("asString", std::string("int")))))
283 .getTypedMatcher<Decl>();
284 EXPECT_TRUE(matches("template<typename T> class A {}; A<int> a;",
285 HasTemplateArgument));
286 EXPECT_FALSE(matches("template<typename T> class A {}; A<char> a;",
287 HasTemplateArgument));
288}
289
Samuel Benzaquen3f84bb32013-07-15 19:25:06 +0000290TEST_F(RegistryTest, TypeTraversal) {
291 Matcher<Type> M = constructMatcher(
292 "pointerType",
293 constructMatcher("pointee", constructMatcher("isConstQualified"),
294 constructMatcher("isInteger"))).getTypedMatcher<Type>();
295 EXPECT_FALSE(matches("int *a;", M));
296 EXPECT_TRUE(matches("int const *b;", M));
297
298 M = constructMatcher(
299 "arrayType",
300 constructMatcher("hasElementType", constructMatcher("builtinType")))
301 .getTypedMatcher<Type>();
302 EXPECT_FALSE(matches("struct A{}; A a[7];;", M));
303 EXPECT_TRUE(matches("int b[7];", M));
304}
305
Samuel Benzaquen86e4d742013-07-17 14:28:00 +0000306TEST_F(RegistryTest, CXXCtorInitializer) {
307 Matcher<Decl> CtorDecl = constructMatcher(
308 "constructorDecl",
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000309 constructMatcher(
310 "hasAnyConstructorInitializer",
311 constructMatcher("forField",
312 constructMatcher("hasName", std::string("foo")))))
Samuel Benzaquen86e4d742013-07-17 14:28:00 +0000313 .getTypedMatcher<Decl>();
314 EXPECT_TRUE(matches("struct Foo { Foo() : foo(1) {} int foo; };", CtorDecl));
315 EXPECT_FALSE(matches("struct Foo { Foo() {} int foo; };", CtorDecl));
316 EXPECT_FALSE(matches("struct Foo { Foo() : bar(1) {} int bar; };", CtorDecl));
317}
318
Samuel Benzaquen6de440e2013-07-24 14:48:01 +0000319TEST_F(RegistryTest, Adaptative) {
320 Matcher<Decl> D = constructMatcher(
321 "recordDecl",
322 constructMatcher(
323 "has",
324 constructMatcher("recordDecl",
325 constructMatcher("hasName", std::string("X")))))
326 .getTypedMatcher<Decl>();
327 EXPECT_TRUE(matches("class X {};", D));
328 EXPECT_TRUE(matches("class Y { class X {}; };", D));
329 EXPECT_FALSE(matches("class Y { class Z {}; };", D));
330
331 Matcher<Stmt> S = constructMatcher(
332 "forStmt",
333 constructMatcher(
334 "hasDescendant",
335 constructMatcher("varDecl",
336 constructMatcher("hasName", std::string("X")))))
337 .getTypedMatcher<Stmt>();
338 EXPECT_TRUE(matches("void foo() { for(int X;;); }", S));
339 EXPECT_TRUE(matches("void foo() { for(;;) { int X; } }", S));
340 EXPECT_FALSE(matches("void foo() { for(;;); }", S));
341 EXPECT_FALSE(matches("void foo() { if (int X = 0){} }", S));
342
343 S = constructMatcher(
344 "compoundStmt", constructMatcher("hasParent", constructMatcher("ifStmt")))
345 .getTypedMatcher<Stmt>();
346 EXPECT_TRUE(matches("void foo() { if (true) { int x = 42; } }", S));
347 EXPECT_FALSE(matches("void foo() { if (true) return; }", S));
348}
349
Samuel Benzaquena7350902013-08-28 18:42:04 +0000350TEST_F(RegistryTest, VariadicOp) {
351 Matcher<Decl> D = constructMatcher(
Samuel Benzaquenb80aad82013-08-29 15:39:26 +0000352 "anyOf",
353 constructMatcher("recordDecl",
354 constructMatcher("hasName", std::string("Foo"))),
Samuel Benzaquena7350902013-08-28 18:42:04 +0000355 constructMatcher("namedDecl",
356 constructMatcher("hasName", std::string("foo"))))
357 .getTypedMatcher<Decl>();
358
359 EXPECT_TRUE(matches("void foo(){}", D));
360 EXPECT_TRUE(matches("struct Foo{};", D));
361 EXPECT_FALSE(matches("int i = 0;", D));
362
363 D = constructMatcher(
364 "allOf", constructMatcher("recordDecl"),
365 constructMatcher(
366 "namedDecl",
367 constructMatcher("anyOf",
368 constructMatcher("hasName", std::string("Foo")),
369 constructMatcher("hasName", std::string("Bar")))))
370 .getTypedMatcher<Decl>();
371
372 EXPECT_FALSE(matches("void foo(){}", D));
373 EXPECT_TRUE(matches("struct Foo{};", D));
374 EXPECT_FALSE(matches("int i = 0;", D));
375 EXPECT_TRUE(matches("class Bar{};", D));
376 EXPECT_FALSE(matches("class OtherBar{};", D));
Stephen Hines651f13c2014-04-23 16:59:28 -0700377
378 D = recordDecl(
379 has(fieldDecl(hasName("Foo"))),
380 constructMatcher(
381 "unless",
382 constructMatcher("namedDecl",
383 constructMatcher("hasName", std::string("Bar"))))
384 .getTypedMatcher<Decl>());
385
386 EXPECT_FALSE(matches("class Bar{ int Foo; };", D));
387 EXPECT_TRUE(matches("class OtherBar{ int Foo; };", D));
Samuel Benzaquena7350902013-08-28 18:42:04 +0000388}
389
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000390TEST_F(RegistryTest, Errors) {
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000391 // Incorrect argument count.
Stephen Hines651f13c2014-04-23 16:59:28 -0700392 std::unique_ptr<Diagnostics> Error(new Diagnostics());
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000393 EXPECT_TRUE(constructMatcher("hasInitializer", Error.get()).isNull());
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000394 EXPECT_EQ("Incorrect argument count. (Expected = 1) != (Actual = 0)",
Samuel Benzaquen2f5a2312013-07-19 20:02:35 +0000395 Error->toString());
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000396 Error.reset(new Diagnostics());
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000397 EXPECT_TRUE(constructMatcher("isArrow", std::string(), Error.get()).isNull());
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000398 EXPECT_EQ("Incorrect argument count. (Expected = 0) != (Actual = 1)",
Samuel Benzaquen2f5a2312013-07-19 20:02:35 +0000399 Error->toString());
Stephen Hines651f13c2014-04-23 16:59:28 -0700400 Error.reset(new Diagnostics());
401 EXPECT_TRUE(constructMatcher("anyOf", Error.get()).isNull());
402 EXPECT_EQ("Incorrect argument count. (Expected = (2, )) != (Actual = 0)",
403 Error->toString());
404 Error.reset(new Diagnostics());
405 EXPECT_TRUE(constructMatcher("unless", std::string(), std::string(),
406 Error.get()).isNull());
407 EXPECT_EQ("Incorrect argument count. (Expected = (1, 1)) != (Actual = 2)",
408 Error->toString());
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000409
410 // Bad argument type
411 Error.reset(new Diagnostics());
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000412 EXPECT_TRUE(constructMatcher("ofClass", std::string(), Error.get()).isNull());
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000413 EXPECT_EQ("Incorrect type for arg 1. (Expected = Matcher<CXXRecordDecl>) != "
414 "(Actual = String)",
Samuel Benzaquen2f5a2312013-07-19 20:02:35 +0000415 Error->toString());
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000416 Error.reset(new Diagnostics());
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000417 EXPECT_TRUE(constructMatcher("recordDecl", constructMatcher("recordDecl"),
418 constructMatcher("parameterCountIs", 3),
419 Error.get()).isNull());
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000420 EXPECT_EQ("Incorrect type for arg 2. (Expected = Matcher<CXXRecordDecl>) != "
421 "(Actual = Matcher<FunctionDecl>)",
Samuel Benzaquen2f5a2312013-07-19 20:02:35 +0000422 Error->toString());
Samuel Benzaquena7350902013-08-28 18:42:04 +0000423
424 // Bad argument type with variadic.
425 Error.reset(new Diagnostics());
Stephen Hines651f13c2014-04-23 16:59:28 -0700426 EXPECT_TRUE(constructMatcher("anyOf", std::string(), std::string(),
427 Error.get()).isNull());
Samuel Benzaquena7350902013-08-28 18:42:04 +0000428 EXPECT_EQ(
429 "Incorrect type for arg 1. (Expected = Matcher<>) != (Actual = String)",
430 Error->toString());
431 Error.reset(new Diagnostics());
432 EXPECT_TRUE(constructMatcher(
433 "recordDecl",
434 constructMatcher("allOf",
435 constructMatcher("isDerivedFrom", std::string("FOO")),
436 constructMatcher("isArrow")),
437 Error.get()).isNull());
438 EXPECT_EQ("Incorrect type for arg 1. "
439 "(Expected = Matcher<CXXRecordDecl>) != "
440 "(Actual = Matcher<CXXRecordDecl>&Matcher<MemberExpr>)",
441 Error->toString());
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000442}
443
Stephen Hines651f13c2014-04-23 16:59:28 -0700444TEST_F(RegistryTest, Completion) {
445 CompVector Comps = getCompletions();
446 EXPECT_TRUE(hasCompletion(
447 Comps, "hasParent(", "Matcher<Decl|Stmt> hasParent(Matcher<Decl|Stmt>)"));
448 EXPECT_TRUE(hasCompletion(Comps, "whileStmt(",
449 "Matcher<Stmt> whileStmt(Matcher<WhileStmt>...)"));
450
451 CompVector WhileComps = getCompletions("whileStmt", 0);
452
453 unsigned HasBodyIndex, HasParentIndex, AllOfIndex;
454 EXPECT_TRUE(hasCompletion(WhileComps, "hasBody(",
455 "Matcher<WhileStmt> hasBody(Matcher<Stmt>)",
456 &HasBodyIndex));
457 EXPECT_TRUE(hasCompletion(WhileComps, "hasParent(",
458 "Matcher<Stmt> hasParent(Matcher<Decl|Stmt>)",
459 &HasParentIndex));
460 EXPECT_TRUE(hasCompletion(WhileComps, "allOf(",
461 "Matcher<T> allOf(Matcher<T>...)", &AllOfIndex));
462 EXPECT_GT(HasParentIndex, HasBodyIndex);
463 EXPECT_GT(AllOfIndex, HasParentIndex);
464
465 EXPECT_FALSE(hasCompletion(WhileComps, "whileStmt("));
466 EXPECT_FALSE(hasCompletion(WhileComps, "ifStmt("));
467
468 CompVector AllOfWhileComps =
469 getCompletions("allOf", 0, "whileStmt", 0);
470 ASSERT_EQ(AllOfWhileComps.size(), WhileComps.size());
471 EXPECT_TRUE(std::equal(WhileComps.begin(), WhileComps.end(),
472 AllOfWhileComps.begin()));
473
474 CompVector DeclWhileComps =
475 getCompletions("decl", 0, "whileStmt", 0);
476 EXPECT_EQ(0u, DeclWhileComps.size());
477
478 CompVector NamedDeclComps = getCompletions("namedDecl", 0);
479 EXPECT_TRUE(
480 hasCompletion(NamedDeclComps, "isPublic()", "Matcher<Decl> isPublic()"));
481 EXPECT_TRUE(hasCompletion(NamedDeclComps, "hasName(\"",
482 "Matcher<NamedDecl> hasName(string)"));
483}
484
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000485} // end anonymous namespace
486} // end namespace dynamic
487} // end namespace ast_matchers
488} // end namespace clang