1*67e74705SXin Li //===- unittest/ASTMatchers/Dynamic/ParserTest.cpp - Parser unit tests -===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===-------------------------------------------------------------------===//
9*67e74705SXin Li
10*67e74705SXin Li #include "../ASTMatchersTest.h"
11*67e74705SXin Li #include "clang/ASTMatchers/Dynamic/Parser.h"
12*67e74705SXin Li #include "clang/ASTMatchers/Dynamic/Registry.h"
13*67e74705SXin Li #include "llvm/ADT/Optional.h"
14*67e74705SXin Li #include "llvm/ADT/StringMap.h"
15*67e74705SXin Li #include "gtest/gtest.h"
16*67e74705SXin Li #include <string>
17*67e74705SXin Li #include <vector>
18*67e74705SXin Li
19*67e74705SXin Li namespace clang {
20*67e74705SXin Li namespace ast_matchers {
21*67e74705SXin Li namespace dynamic {
22*67e74705SXin Li namespace {
23*67e74705SXin Li
24*67e74705SXin Li class MockSema : public Parser::Sema {
25*67e74705SXin Li public:
~MockSema()26*67e74705SXin Li ~MockSema() override {}
27*67e74705SXin Li
expectMatcher(StringRef MatcherName)28*67e74705SXin Li uint64_t expectMatcher(StringRef MatcherName) {
29*67e74705SXin Li // Optimizations on the matcher framework make simple matchers like
30*67e74705SXin Li // 'stmt()' to be all the same matcher.
31*67e74705SXin Li // Use a more complex expression to prevent that.
32*67e74705SXin Li ast_matchers::internal::Matcher<Stmt> M = stmt(stmt(), stmt());
33*67e74705SXin Li ExpectedMatchers.insert(std::make_pair(MatcherName, M));
34*67e74705SXin Li return M.getID().second;
35*67e74705SXin Li }
36*67e74705SXin Li
parse(StringRef Code)37*67e74705SXin Li void parse(StringRef Code) {
38*67e74705SXin Li Diagnostics Error;
39*67e74705SXin Li VariantValue Value;
40*67e74705SXin Li Parser::parseExpression(Code, this, &Value, &Error);
41*67e74705SXin Li Values.push_back(Value);
42*67e74705SXin Li Errors.push_back(Error.toStringFull());
43*67e74705SXin Li }
44*67e74705SXin Li
45*67e74705SXin Li llvm::Optional<MatcherCtor>
lookupMatcherCtor(StringRef MatcherName)46*67e74705SXin Li lookupMatcherCtor(StringRef MatcherName) override {
47*67e74705SXin Li const ExpectedMatchersTy::value_type *Matcher =
48*67e74705SXin Li &*ExpectedMatchers.find(MatcherName);
49*67e74705SXin Li return reinterpret_cast<MatcherCtor>(Matcher);
50*67e74705SXin Li }
51*67e74705SXin Li
actOnMatcherExpression(MatcherCtor Ctor,SourceRange NameRange,StringRef BindID,ArrayRef<ParserValue> Args,Diagnostics * Error)52*67e74705SXin Li VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
53*67e74705SXin Li SourceRange NameRange,
54*67e74705SXin Li StringRef BindID,
55*67e74705SXin Li ArrayRef<ParserValue> Args,
56*67e74705SXin Li Diagnostics *Error) override {
57*67e74705SXin Li const ExpectedMatchersTy::value_type *Matcher =
58*67e74705SXin Li reinterpret_cast<const ExpectedMatchersTy::value_type *>(Ctor);
59*67e74705SXin Li MatcherInfo ToStore = { Matcher->first, NameRange, Args, BindID };
60*67e74705SXin Li Matchers.push_back(ToStore);
61*67e74705SXin Li return VariantMatcher::SingleMatcher(Matcher->second);
62*67e74705SXin Li }
63*67e74705SXin Li
64*67e74705SXin Li struct MatcherInfo {
65*67e74705SXin Li StringRef MatcherName;
66*67e74705SXin Li SourceRange NameRange;
67*67e74705SXin Li std::vector<ParserValue> Args;
68*67e74705SXin Li std::string BoundID;
69*67e74705SXin Li };
70*67e74705SXin Li
71*67e74705SXin Li std::vector<std::string> Errors;
72*67e74705SXin Li std::vector<VariantValue> Values;
73*67e74705SXin Li std::vector<MatcherInfo> Matchers;
74*67e74705SXin Li typedef std::map<std::string, ast_matchers::internal::Matcher<Stmt> >
75*67e74705SXin Li ExpectedMatchersTy;
76*67e74705SXin Li ExpectedMatchersTy ExpectedMatchers;
77*67e74705SXin Li };
78*67e74705SXin Li
TEST(ParserTest,ParseUnsigned)79*67e74705SXin Li TEST(ParserTest, ParseUnsigned) {
80*67e74705SXin Li MockSema Sema;
81*67e74705SXin Li Sema.parse("0");
82*67e74705SXin Li Sema.parse("123");
83*67e74705SXin Li Sema.parse("0x1f");
84*67e74705SXin Li Sema.parse("12345678901");
85*67e74705SXin Li Sema.parse("1a1");
86*67e74705SXin Li EXPECT_EQ(5U, Sema.Values.size());
87*67e74705SXin Li EXPECT_EQ(0U, Sema.Values[0].getUnsigned());
88*67e74705SXin Li EXPECT_EQ(123U, Sema.Values[1].getUnsigned());
89*67e74705SXin Li EXPECT_EQ(31U, Sema.Values[2].getUnsigned());
90*67e74705SXin Li EXPECT_EQ("1:1: Error parsing unsigned token: <12345678901>", Sema.Errors[3]);
91*67e74705SXin Li EXPECT_EQ("1:1: Error parsing unsigned token: <1a1>", Sema.Errors[4]);
92*67e74705SXin Li }
93*67e74705SXin Li
TEST(ParserTest,ParseString)94*67e74705SXin Li TEST(ParserTest, ParseString) {
95*67e74705SXin Li MockSema Sema;
96*67e74705SXin Li Sema.parse("\"Foo\"");
97*67e74705SXin Li Sema.parse("\"\"");
98*67e74705SXin Li Sema.parse("\"Baz");
99*67e74705SXin Li EXPECT_EQ(3ULL, Sema.Values.size());
100*67e74705SXin Li EXPECT_EQ("Foo", Sema.Values[0].getString());
101*67e74705SXin Li EXPECT_EQ("", Sema.Values[1].getString());
102*67e74705SXin Li EXPECT_EQ("1:1: Error parsing string token: <\"Baz>", Sema.Errors[2]);
103*67e74705SXin Li }
104*67e74705SXin Li
matchesRange(SourceRange Range,unsigned StartLine,unsigned EndLine,unsigned StartColumn,unsigned EndColumn)105*67e74705SXin Li bool matchesRange(SourceRange Range, unsigned StartLine,
106*67e74705SXin Li unsigned EndLine, unsigned StartColumn, unsigned EndColumn) {
107*67e74705SXin Li EXPECT_EQ(StartLine, Range.Start.Line);
108*67e74705SXin Li EXPECT_EQ(EndLine, Range.End.Line);
109*67e74705SXin Li EXPECT_EQ(StartColumn, Range.Start.Column);
110*67e74705SXin Li EXPECT_EQ(EndColumn, Range.End.Column);
111*67e74705SXin Li return Range.Start.Line == StartLine && Range.End.Line == EndLine &&
112*67e74705SXin Li Range.Start.Column == StartColumn && Range.End.Column == EndColumn;
113*67e74705SXin Li }
114*67e74705SXin Li
getSingleMatcher(const VariantValue & Value)115*67e74705SXin Li llvm::Optional<DynTypedMatcher> getSingleMatcher(const VariantValue &Value) {
116*67e74705SXin Li llvm::Optional<DynTypedMatcher> Result =
117*67e74705SXin Li Value.getMatcher().getSingleMatcher();
118*67e74705SXin Li EXPECT_TRUE(Result.hasValue());
119*67e74705SXin Li return Result;
120*67e74705SXin Li }
121*67e74705SXin Li
TEST(ParserTest,ParseMatcher)122*67e74705SXin Li TEST(ParserTest, ParseMatcher) {
123*67e74705SXin Li MockSema Sema;
124*67e74705SXin Li const uint64_t ExpectedFoo = Sema.expectMatcher("Foo");
125*67e74705SXin Li const uint64_t ExpectedBar = Sema.expectMatcher("Bar");
126*67e74705SXin Li const uint64_t ExpectedBaz = Sema.expectMatcher("Baz");
127*67e74705SXin Li Sema.parse(" Foo ( Bar ( 17), Baz( \n \"B A,Z\") ) .bind( \"Yo!\") ");
128*67e74705SXin Li for (size_t i = 0, e = Sema.Errors.size(); i != e; ++i) {
129*67e74705SXin Li EXPECT_EQ("", Sema.Errors[i]);
130*67e74705SXin Li }
131*67e74705SXin Li
132*67e74705SXin Li EXPECT_NE(ExpectedFoo, ExpectedBar);
133*67e74705SXin Li EXPECT_NE(ExpectedFoo, ExpectedBaz);
134*67e74705SXin Li EXPECT_NE(ExpectedBar, ExpectedBaz);
135*67e74705SXin Li
136*67e74705SXin Li EXPECT_EQ(1ULL, Sema.Values.size());
137*67e74705SXin Li EXPECT_EQ(ExpectedFoo, getSingleMatcher(Sema.Values[0])->getID().second);
138*67e74705SXin Li
139*67e74705SXin Li EXPECT_EQ(3ULL, Sema.Matchers.size());
140*67e74705SXin Li const MockSema::MatcherInfo Bar = Sema.Matchers[0];
141*67e74705SXin Li EXPECT_EQ("Bar", Bar.MatcherName);
142*67e74705SXin Li EXPECT_TRUE(matchesRange(Bar.NameRange, 1, 1, 8, 17));
143*67e74705SXin Li EXPECT_EQ(1ULL, Bar.Args.size());
144*67e74705SXin Li EXPECT_EQ(17U, Bar.Args[0].Value.getUnsigned());
145*67e74705SXin Li
146*67e74705SXin Li const MockSema::MatcherInfo Baz = Sema.Matchers[1];
147*67e74705SXin Li EXPECT_EQ("Baz", Baz.MatcherName);
148*67e74705SXin Li EXPECT_TRUE(matchesRange(Baz.NameRange, 1, 2, 19, 10));
149*67e74705SXin Li EXPECT_EQ(1ULL, Baz.Args.size());
150*67e74705SXin Li EXPECT_EQ("B A,Z", Baz.Args[0].Value.getString());
151*67e74705SXin Li
152*67e74705SXin Li const MockSema::MatcherInfo Foo = Sema.Matchers[2];
153*67e74705SXin Li EXPECT_EQ("Foo", Foo.MatcherName);
154*67e74705SXin Li EXPECT_TRUE(matchesRange(Foo.NameRange, 1, 2, 2, 12));
155*67e74705SXin Li EXPECT_EQ(2ULL, Foo.Args.size());
156*67e74705SXin Li EXPECT_EQ(ExpectedBar, getSingleMatcher(Foo.Args[0].Value)->getID().second);
157*67e74705SXin Li EXPECT_EQ(ExpectedBaz, getSingleMatcher(Foo.Args[1].Value)->getID().second);
158*67e74705SXin Li EXPECT_EQ("Yo!", Foo.BoundID);
159*67e74705SXin Li }
160*67e74705SXin Li
161*67e74705SXin Li using ast_matchers::internal::Matcher;
162*67e74705SXin Li
getTestNamedValues()163*67e74705SXin Li Parser::NamedValueMap getTestNamedValues() {
164*67e74705SXin Li Parser::NamedValueMap Values;
165*67e74705SXin Li Values["nameX"] = llvm::StringRef("x");
166*67e74705SXin Li Values["hasParamA"] =
167*67e74705SXin Li VariantMatcher::SingleMatcher(hasParameter(0, hasName("a")));
168*67e74705SXin Li return Values;
169*67e74705SXin Li }
170*67e74705SXin Li
TEST(ParserTest,FullParserTest)171*67e74705SXin Li TEST(ParserTest, FullParserTest) {
172*67e74705SXin Li Diagnostics Error;
173*67e74705SXin Li llvm::Optional<DynTypedMatcher> VarDecl(Parser::parseMatcherExpression(
174*67e74705SXin Li "varDecl(hasInitializer(binaryOperator(hasLHS(integerLiteral()),"
175*67e74705SXin Li " hasOperatorName(\"+\"))))",
176*67e74705SXin Li &Error));
177*67e74705SXin Li EXPECT_EQ("", Error.toStringFull());
178*67e74705SXin Li Matcher<Decl> M = VarDecl->unconditionalConvertTo<Decl>();
179*67e74705SXin Li EXPECT_TRUE(matches("int x = 1 + false;", M));
180*67e74705SXin Li EXPECT_FALSE(matches("int x = true + 1;", M));
181*67e74705SXin Li EXPECT_FALSE(matches("int x = 1 - false;", M));
182*67e74705SXin Li EXPECT_FALSE(matches("int x = true - 1;", M));
183*67e74705SXin Li
184*67e74705SXin Li llvm::Optional<DynTypedMatcher> HasParameter(Parser::parseMatcherExpression(
185*67e74705SXin Li "functionDecl(hasParameter(1, hasName(\"x\")))", &Error));
186*67e74705SXin Li EXPECT_EQ("", Error.toStringFull());
187*67e74705SXin Li M = HasParameter->unconditionalConvertTo<Decl>();
188*67e74705SXin Li
189*67e74705SXin Li EXPECT_TRUE(matches("void f(int a, int x);", M));
190*67e74705SXin Li EXPECT_FALSE(matches("void f(int x, int a);", M));
191*67e74705SXin Li
192*67e74705SXin Li // Test named values.
193*67e74705SXin Li auto NamedValues = getTestNamedValues();
194*67e74705SXin Li llvm::Optional<DynTypedMatcher> HasParameterWithNamedValues(
195*67e74705SXin Li Parser::parseMatcherExpression(
196*67e74705SXin Li "functionDecl(hasParamA, hasParameter(1, hasName(nameX)))",
197*67e74705SXin Li nullptr, &NamedValues, &Error));
198*67e74705SXin Li EXPECT_EQ("", Error.toStringFull());
199*67e74705SXin Li M = HasParameterWithNamedValues->unconditionalConvertTo<Decl>();
200*67e74705SXin Li
201*67e74705SXin Li EXPECT_TRUE(matches("void f(int a, int x);", M));
202*67e74705SXin Li EXPECT_FALSE(matches("void f(int x, int a);", M));
203*67e74705SXin Li
204*67e74705SXin Li
205*67e74705SXin Li EXPECT_TRUE(!Parser::parseMatcherExpression(
206*67e74705SXin Li "hasInitializer(\n binaryOperator(hasLHS(\"A\")))",
207*67e74705SXin Li &Error).hasValue());
208*67e74705SXin Li EXPECT_EQ("1:1: Error parsing argument 1 for matcher hasInitializer.\n"
209*67e74705SXin Li "2:5: Error parsing argument 1 for matcher binaryOperator.\n"
210*67e74705SXin Li "2:20: Error building matcher hasLHS.\n"
211*67e74705SXin Li "2:27: Incorrect type for arg 1. "
212*67e74705SXin Li "(Expected = Matcher<Expr>) != (Actual = String)",
213*67e74705SXin Li Error.toStringFull());
214*67e74705SXin Li }
215*67e74705SXin Li
ParseWithError(StringRef Code)216*67e74705SXin Li std::string ParseWithError(StringRef Code) {
217*67e74705SXin Li Diagnostics Error;
218*67e74705SXin Li VariantValue Value;
219*67e74705SXin Li Parser::parseExpression(Code, &Value, &Error);
220*67e74705SXin Li return Error.toStringFull();
221*67e74705SXin Li }
222*67e74705SXin Li
ParseMatcherWithError(StringRef Code)223*67e74705SXin Li std::string ParseMatcherWithError(StringRef Code) {
224*67e74705SXin Li Diagnostics Error;
225*67e74705SXin Li Parser::parseMatcherExpression(Code, &Error);
226*67e74705SXin Li return Error.toStringFull();
227*67e74705SXin Li }
228*67e74705SXin Li
TEST(ParserTest,Errors)229*67e74705SXin Li TEST(ParserTest, Errors) {
230*67e74705SXin Li EXPECT_EQ(
231*67e74705SXin Li "1:5: Error parsing matcher. Found token <123> while looking for '('.",
232*67e74705SXin Li ParseWithError("Foo 123"));
233*67e74705SXin Li EXPECT_EQ(
234*67e74705SXin Li "1:1: Matcher not found: Foo\n"
235*67e74705SXin Li "1:9: Error parsing matcher. Found token <123> while looking for ','.",
236*67e74705SXin Li ParseWithError("Foo(\"A\" 123)"));
237*67e74705SXin Li EXPECT_EQ(
238*67e74705SXin Li "1:1: Error parsing argument 1 for matcher stmt.\n"
239*67e74705SXin Li "1:6: Value not found: someValue",
240*67e74705SXin Li ParseWithError("stmt(someValue)"));
241*67e74705SXin Li EXPECT_EQ(
242*67e74705SXin Li "1:1: Matcher not found: Foo\n"
243*67e74705SXin Li "1:4: Error parsing matcher. Found end-of-code while looking for ')'.",
244*67e74705SXin Li ParseWithError("Foo("));
245*67e74705SXin Li EXPECT_EQ("1:1: End of code found while looking for token.",
246*67e74705SXin Li ParseWithError(""));
247*67e74705SXin Li EXPECT_EQ("Input value is not a matcher expression.",
248*67e74705SXin Li ParseMatcherWithError("\"A\""));
249*67e74705SXin Li EXPECT_EQ("1:1: Matcher not found: Foo\n"
250*67e74705SXin Li "1:1: Error parsing argument 1 for matcher Foo.\n"
251*67e74705SXin Li "1:5: Invalid token <(> found when looking for a value.",
252*67e74705SXin Li ParseWithError("Foo(("));
253*67e74705SXin Li EXPECT_EQ("1:7: Expected end of code.", ParseWithError("expr()a"));
254*67e74705SXin Li EXPECT_EQ("1:11: Malformed bind() expression.",
255*67e74705SXin Li ParseWithError("isArrow().biind"));
256*67e74705SXin Li EXPECT_EQ("1:15: Malformed bind() expression.",
257*67e74705SXin Li ParseWithError("isArrow().bind"));
258*67e74705SXin Li EXPECT_EQ("1:16: Malformed bind() expression.",
259*67e74705SXin Li ParseWithError("isArrow().bind(foo"));
260*67e74705SXin Li EXPECT_EQ("1:21: Malformed bind() expression.",
261*67e74705SXin Li ParseWithError("isArrow().bind(\"foo\""));
262*67e74705SXin Li EXPECT_EQ("1:1: Error building matcher isArrow.\n"
263*67e74705SXin Li "1:1: Matcher does not support binding.",
264*67e74705SXin Li ParseWithError("isArrow().bind(\"foo\")"));
265*67e74705SXin Li EXPECT_EQ("Input value has unresolved overloaded type: "
266*67e74705SXin Li "Matcher<DoStmt|ForStmt|WhileStmt|CXXForRangeStmt|FunctionDecl>",
267*67e74705SXin Li ParseMatcherWithError("hasBody(stmt())"));
268*67e74705SXin Li }
269*67e74705SXin Li
TEST(ParserTest,OverloadErrors)270*67e74705SXin Li TEST(ParserTest, OverloadErrors) {
271*67e74705SXin Li EXPECT_EQ("1:1: Error building matcher callee.\n"
272*67e74705SXin Li "1:8: Candidate 1: Incorrect type for arg 1. "
273*67e74705SXin Li "(Expected = Matcher<Stmt>) != (Actual = String)\n"
274*67e74705SXin Li "1:8: Candidate 2: Incorrect type for arg 1. "
275*67e74705SXin Li "(Expected = Matcher<Decl>) != (Actual = String)",
276*67e74705SXin Li ParseWithError("callee(\"A\")"));
277*67e74705SXin Li }
278*67e74705SXin Li
TEST(ParserTest,CompletionRegistry)279*67e74705SXin Li TEST(ParserTest, CompletionRegistry) {
280*67e74705SXin Li std::vector<MatcherCompletion> Comps =
281*67e74705SXin Li Parser::completeExpression("while", 5);
282*67e74705SXin Li ASSERT_EQ(1u, Comps.size());
283*67e74705SXin Li EXPECT_EQ("Stmt(", Comps[0].TypedText);
284*67e74705SXin Li EXPECT_EQ("Matcher<Stmt> whileStmt(Matcher<WhileStmt>...)",
285*67e74705SXin Li Comps[0].MatcherDecl);
286*67e74705SXin Li
287*67e74705SXin Li Comps = Parser::completeExpression("whileStmt().", 12);
288*67e74705SXin Li ASSERT_EQ(1u, Comps.size());
289*67e74705SXin Li EXPECT_EQ("bind(\"", Comps[0].TypedText);
290*67e74705SXin Li EXPECT_EQ("bind", Comps[0].MatcherDecl);
291*67e74705SXin Li }
292*67e74705SXin Li
TEST(ParserTest,CompletionNamedValues)293*67e74705SXin Li TEST(ParserTest, CompletionNamedValues) {
294*67e74705SXin Li // Can complete non-matcher types.
295*67e74705SXin Li auto NamedValues = getTestNamedValues();
296*67e74705SXin Li StringRef Code = "functionDecl(hasName(";
297*67e74705SXin Li std::vector<MatcherCompletion> Comps =
298*67e74705SXin Li Parser::completeExpression(Code, Code.size(), nullptr, &NamedValues);
299*67e74705SXin Li ASSERT_EQ(1u, Comps.size());
300*67e74705SXin Li EXPECT_EQ("nameX", Comps[0].TypedText);
301*67e74705SXin Li EXPECT_EQ("String nameX", Comps[0].MatcherDecl);
302*67e74705SXin Li
303*67e74705SXin Li // Can complete if there are names in the expression.
304*67e74705SXin Li Code = "cxxMethodDecl(hasName(nameX), ";
305*67e74705SXin Li Comps = Parser::completeExpression(Code, Code.size(), nullptr, &NamedValues);
306*67e74705SXin Li EXPECT_LT(0u, Comps.size());
307*67e74705SXin Li
308*67e74705SXin Li // Can complete names and registry together.
309*67e74705SXin Li Code = "cxxMethodDecl(hasP";
310*67e74705SXin Li Comps = Parser::completeExpression(Code, Code.size(), nullptr, &NamedValues);
311*67e74705SXin Li ASSERT_EQ(3u, Comps.size());
312*67e74705SXin Li EXPECT_EQ("aramA", Comps[0].TypedText);
313*67e74705SXin Li EXPECT_EQ("Matcher<FunctionDecl> hasParamA", Comps[0].MatcherDecl);
314*67e74705SXin Li
315*67e74705SXin Li EXPECT_EQ("arameter(", Comps[1].TypedText);
316*67e74705SXin Li EXPECT_EQ(
317*67e74705SXin Li "Matcher<FunctionDecl> hasParameter(unsigned, Matcher<ParmVarDecl>)",
318*67e74705SXin Li Comps[1].MatcherDecl);
319*67e74705SXin Li
320*67e74705SXin Li EXPECT_EQ("arent(", Comps[2].TypedText);
321*67e74705SXin Li EXPECT_EQ(
322*67e74705SXin Li "Matcher<Decl> "
323*67e74705SXin Li "hasParent(Matcher<NestedNameSpecifierLoc|TypeLoc|Decl|...>)",
324*67e74705SXin Li Comps[2].MatcherDecl);
325*67e74705SXin Li }
326*67e74705SXin Li
327*67e74705SXin Li } // end anonymous namespace
328*67e74705SXin Li } // end namespace dynamic
329*67e74705SXin Li } // end namespace ast_matchers
330*67e74705SXin Li } // end namespace clang
331