1 //===---- QueryParserTest.cpp - clang-query test --------------------------===// 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 "QueryParser.h" 10 #include "Query.h" 11 #include "QuerySession.h" 12 #include "llvm/LineEditor/LineEditor.h" 13 #include "gtest/gtest.h" 14 15 using namespace clang; 16 using namespace clang::query; 17 18 class QueryParserTest : public ::testing::Test { 19 protected: 20 QueryParserTest() : QS(llvm::ArrayRef<std::unique_ptr<ASTUnit>>()) {} 21 QueryRef parse(StringRef Code) { return QueryParser::parse(Code, QS); } 22 23 QuerySession QS; 24 }; 25 26 TEST_F(QueryParserTest, NoOp) { 27 QueryRef Q = parse(""); 28 EXPECT_TRUE(isa<NoOpQuery>(Q)); 29 30 Q = parse("\n"); 31 EXPECT_TRUE(isa<NoOpQuery>(Q)); 32 } 33 34 TEST_F(QueryParserTest, Invalid) { 35 QueryRef Q = parse("foo"); 36 ASSERT_TRUE(isa<InvalidQuery>(Q)); 37 EXPECT_EQ("unknown command: foo", cast<InvalidQuery>(Q)->ErrStr); 38 } 39 40 TEST_F(QueryParserTest, Help) { 41 QueryRef Q = parse("help"); 42 ASSERT_TRUE(isa<HelpQuery>(Q)); 43 44 Q = parse("help me"); 45 ASSERT_TRUE(isa<InvalidQuery>(Q)); 46 EXPECT_EQ("unexpected extra input: ' me'", cast<InvalidQuery>(Q)->ErrStr); 47 } 48 49 TEST_F(QueryParserTest, Quit) { 50 QueryRef Q = parse("quit"); 51 ASSERT_TRUE(isa<QuitQuery>(Q)); 52 53 Q = parse("q"); 54 ASSERT_TRUE(isa<QuitQuery>(Q)); 55 56 Q = parse("quit me"); 57 ASSERT_TRUE(isa<InvalidQuery>(Q)); 58 EXPECT_EQ("unexpected extra input: ' me'", cast<InvalidQuery>(Q)->ErrStr); 59 } 60 61 TEST_F(QueryParserTest, Set) { 62 QueryRef Q = parse("set"); 63 ASSERT_TRUE(isa<InvalidQuery>(Q)); 64 EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); 65 66 Q = parse("set foo bar"); 67 ASSERT_TRUE(isa<InvalidQuery>(Q)); 68 EXPECT_EQ("unknown variable: 'foo'", cast<InvalidQuery>(Q)->ErrStr); 69 70 Q = parse("set output"); 71 ASSERT_TRUE(isa<InvalidQuery>(Q)); 72 EXPECT_EQ("expected 'diag', 'print', 'detailed-ast' or 'dump', got ''", 73 cast<InvalidQuery>(Q)->ErrStr); 74 75 Q = parse("set bind-root true foo"); 76 ASSERT_TRUE(isa<InvalidQuery>(Q)); 77 EXPECT_EQ("unexpected extra input: ' foo'", cast<InvalidQuery>(Q)->ErrStr); 78 79 Q = parse("set output foo"); 80 ASSERT_TRUE(isa<InvalidQuery>(Q)); 81 EXPECT_EQ("expected 'diag', 'print', 'detailed-ast' or 'dump', got 'foo'", 82 cast<InvalidQuery>(Q)->ErrStr); 83 84 Q = parse("set output dump"); 85 ASSERT_TRUE(isa<SetExclusiveOutputQuery >(Q)); 86 EXPECT_EQ(&QuerySession::DetailedASTOutput, cast<SetExclusiveOutputQuery>(Q)->Var); 87 88 Q = parse("set output detailed-ast"); 89 ASSERT_TRUE(isa<SetExclusiveOutputQuery>(Q)); 90 EXPECT_EQ(&QuerySession::DetailedASTOutput, cast<SetExclusiveOutputQuery>(Q)->Var); 91 92 Q = parse("enable output detailed-ast"); 93 ASSERT_TRUE(isa<EnableOutputQuery>(Q)); 94 EXPECT_EQ(&QuerySession::DetailedASTOutput, cast<EnableOutputQuery>(Q)->Var); 95 96 Q = parse("enable"); 97 ASSERT_TRUE(isa<InvalidQuery>(Q)); 98 EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); 99 100 Q = parse("disable output detailed-ast"); 101 ASSERT_TRUE(isa<DisableOutputQuery>(Q)); 102 EXPECT_EQ(&QuerySession::DetailedASTOutput, cast<DisableOutputQuery>(Q)->Var); 103 104 Q = parse("set bind-root foo"); 105 ASSERT_TRUE(isa<InvalidQuery>(Q)); 106 EXPECT_EQ("expected 'true' or 'false', got 'foo'", 107 cast<InvalidQuery>(Q)->ErrStr); 108 109 Q = parse("set bind-root true"); 110 ASSERT_TRUE(isa<SetQuery<bool> >(Q)); 111 EXPECT_EQ(&QuerySession::BindRoot, cast<SetQuery<bool> >(Q)->Var); 112 EXPECT_EQ(true, cast<SetQuery<bool> >(Q)->Value); 113 } 114 115 TEST_F(QueryParserTest, Match) { 116 QueryRef Q = parse("match decl()"); 117 ASSERT_TRUE(isa<MatchQuery>(Q)); 118 EXPECT_TRUE(cast<MatchQuery>(Q)->Matcher.canConvertTo<Decl>()); 119 120 Q = parse("m stmt()"); 121 ASSERT_TRUE(isa<MatchQuery>(Q)); 122 EXPECT_TRUE(cast<MatchQuery>(Q)->Matcher.canConvertTo<Stmt>()); 123 } 124 125 TEST_F(QueryParserTest, LetUnlet) { 126 QueryRef Q = parse("let foo decl()"); 127 ASSERT_TRUE(isa<LetQuery>(Q)); 128 EXPECT_EQ("foo", cast<LetQuery>(Q)->Name); 129 EXPECT_TRUE(cast<LetQuery>(Q)->Value.isMatcher()); 130 EXPECT_TRUE(cast<LetQuery>(Q)->Value.getMatcher().hasTypedMatcher<Decl>()); 131 132 Q = parse("l foo decl()"); 133 ASSERT_TRUE(isa<LetQuery>(Q)); 134 EXPECT_EQ("foo", cast<LetQuery>(Q)->Name); 135 EXPECT_TRUE(cast<LetQuery>(Q)->Value.isMatcher()); 136 EXPECT_TRUE(cast<LetQuery>(Q)->Value.getMatcher().hasTypedMatcher<Decl>()); 137 138 Q = parse("let bar \"str\""); 139 ASSERT_TRUE(isa<LetQuery>(Q)); 140 EXPECT_EQ("bar", cast<LetQuery>(Q)->Name); 141 EXPECT_TRUE(cast<LetQuery>(Q)->Value.isString()); 142 EXPECT_EQ("str", cast<LetQuery>(Q)->Value.getString()); 143 144 Q = parse("let"); 145 ASSERT_TRUE(isa<InvalidQuery>(Q)); 146 EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); 147 148 Q = parse("unlet x"); 149 ASSERT_TRUE(isa<LetQuery>(Q)); 150 EXPECT_EQ("x", cast<LetQuery>(Q)->Name); 151 EXPECT_FALSE(cast<LetQuery>(Q)->Value.hasValue()); 152 153 Q = parse("unlet"); 154 ASSERT_TRUE(isa<InvalidQuery>(Q)); 155 EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); 156 157 Q = parse("unlet x bad_data"); 158 ASSERT_TRUE(isa<InvalidQuery>(Q)); 159 EXPECT_EQ("unexpected extra input: ' bad_data'", 160 cast<InvalidQuery>(Q)->ErrStr); 161 } 162 163 TEST_F(QueryParserTest, Comment) { 164 QueryRef Q = parse("# let foo decl()"); 165 ASSERT_TRUE(isa<NoOpQuery>(Q)); 166 167 Q = parse("let foo decl() # creates a decl() matcher called foo"); 168 ASSERT_TRUE(isa<LetQuery>(Q)); 169 170 Q = parse("set bind-root false # reduce noise"); 171 ASSERT_TRUE(isa<SetQuery<bool>>(Q)); 172 } 173 174 TEST_F(QueryParserTest, Complete) { 175 std::vector<llvm::LineEditor::Completion> Comps = 176 QueryParser::complete("", 0, QS); 177 ASSERT_EQ(8u, Comps.size()); 178 EXPECT_EQ("help ", Comps[0].TypedText); 179 EXPECT_EQ("help", Comps[0].DisplayText); 180 EXPECT_EQ("let ", Comps[1].TypedText); 181 EXPECT_EQ("let", Comps[1].DisplayText); 182 EXPECT_EQ("match ", Comps[2].TypedText); 183 EXPECT_EQ("match", Comps[2].DisplayText); 184 EXPECT_EQ("quit ", Comps[3].TypedText); 185 EXPECT_EQ("quit", Comps[3].DisplayText); 186 EXPECT_EQ("set ", Comps[4].TypedText); 187 EXPECT_EQ("set", Comps[4].DisplayText); 188 EXPECT_EQ("enable ", Comps[5].TypedText); 189 EXPECT_EQ("enable", Comps[5].DisplayText); 190 EXPECT_EQ("disable ", Comps[6].TypedText); 191 EXPECT_EQ("disable", Comps[6].DisplayText); 192 EXPECT_EQ("unlet ", Comps[7].TypedText); 193 EXPECT_EQ("unlet", Comps[7].DisplayText); 194 195 Comps = QueryParser::complete("set o", 5, QS); 196 ASSERT_EQ(1u, Comps.size()); 197 EXPECT_EQ("utput ", Comps[0].TypedText); 198 EXPECT_EQ("output", Comps[0].DisplayText); 199 200 Comps = QueryParser::complete("enable ", 7, QS); 201 ASSERT_EQ(1u, Comps.size()); 202 EXPECT_EQ("output ", Comps[0].TypedText); 203 EXPECT_EQ("output", Comps[0].DisplayText); 204 205 Comps = QueryParser::complete("enable output ", 14, QS); 206 ASSERT_EQ(4u, Comps.size()); 207 208 EXPECT_EQ("diag ", Comps[0].TypedText); 209 EXPECT_EQ("diag", Comps[0].DisplayText); 210 EXPECT_EQ("print ", Comps[1].TypedText); 211 EXPECT_EQ("print", Comps[1].DisplayText); 212 EXPECT_EQ("detailed-ast ", Comps[2].TypedText); 213 EXPECT_EQ("detailed-ast", Comps[2].DisplayText); 214 EXPECT_EQ("dump ", Comps[3].TypedText); 215 EXPECT_EQ("dump", Comps[3].DisplayText); 216 217 Comps = QueryParser::complete("match while", 11, QS); 218 ASSERT_EQ(1u, Comps.size()); 219 EXPECT_EQ("Stmt(", Comps[0].TypedText); 220 EXPECT_EQ("Matcher<Stmt> whileStmt(Matcher<WhileStmt>...)", 221 Comps[0].DisplayText); 222 223 Comps = QueryParser::complete("m", 1, QS); 224 ASSERT_EQ(1u, Comps.size()); 225 EXPECT_EQ("atch ", Comps[0].TypedText); 226 EXPECT_EQ("match", Comps[0].DisplayText); 227 228 Comps = QueryParser::complete("l", 1, QS); 229 ASSERT_EQ(1u, Comps.size()); 230 EXPECT_EQ("et ", Comps[0].TypedText); 231 EXPECT_EQ("let", Comps[0].DisplayText); 232 } 233