13 #include "clang/ASTMatchers/Dynamic/Parser.h" 14 #include "clang/Basic/CharInfo.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/ADT/StringSwitch.h" 29 StringRef QueryParser::lexWord() {
32 return StringRef(Begin, 0);
34 if (!isWhitespace(*Begin))
40 const char *WordBegin = Begin;
45 if (Begin == End || isWhitespace(*Begin))
46 return StringRef(WordBegin, Begin - WordBegin);
62 : Switch(Word), P(P), Word(Word), WordCompletionPos(WCP) {}
66 bool IsCompletion =
true) {
67 StringRef CaseStr(S, N - 1);
69 if (WordCompletionPos == StringRef::npos)
70 Switch.Case(S, Value);
71 else if (N != 1 && IsCompletion && WordCompletionPos <= CaseStr.size() &&
72 CaseStr.substr(0, WordCompletionPos) ==
73 Word.substr(0, WordCompletionPos))
74 P->Completions.push_back(LineEditor::Completion(
75 (CaseStr.substr(WordCompletionPos) +
" ").str(), CaseStr));
79 T
Default(
const T &Value)
const {
return Switch.Default(Value); }
87 QueryParser::lexOrCompleteWord(StringRef &Word) {
89 size_t WordCompletionPos = StringRef::npos;
90 if (CompletionPos && CompletionPos <= Word.data() + Word.size()) {
91 if (CompletionPos < Word.data())
92 WordCompletionPos = 0;
94 WordCompletionPos = CompletionPos - Word.data();
101 unsigned Value = lexOrCompleteWord<unsigned>(ValStr)
106 return new InvalidQuery(
"expected 'true' or 'false', got '" + ValStr +
"'");
111 QueryRef QueryParser::parseSetOutputKind() {
113 unsigned OutKind = lexOrCompleteWord<unsigned>(ValStr)
118 if (OutKind == ~0u) {
119 return new InvalidQuery(
"expected 'diag', 'print' or 'dump', got '" +
126 const char *Extra = Begin;
127 if (!lexWord().empty())
129 StringRef(Extra, End - Extra) +
"'");
148 QueryRef makeInvalidQueryFromDiagnostics(
const Diagnostics &Diag) {
150 llvm::raw_string_ostream OS(ErrStr);
151 Diag.printToStreamFull(OS);
157 QueryRef QueryParser::completeMatcherExpression() {
158 std::vector<MatcherCompletion> Comps = Parser::completeExpression(
159 StringRef(Begin, End - Begin), CompletionPos - Begin,
nullptr,
161 for (
auto I = Comps.begin(), E = Comps.end(); I != E; ++I) {
162 Completions.push_back(LineEditor::Completion(I->TypedText, I->MatcherDecl));
168 StringRef CommandStr;
171 .Case(
"help", PQK_Help)
172 .Case(
"m", PQK_Match,
false)
173 .Case(
"let", PQK_Let)
174 .Case(
"match", PQK_Match)
175 .Case(
"set", PQK_Set)
176 .Case(
"unlet", PQK_Unlet)
177 .Case(
"quit", PQK_Quit)
178 .Default(PQK_Invalid);
191 StringRef
Name = lexWord();
197 return completeMatcherExpression();
200 ast_matchers::dynamic::VariantValue Value;
201 if (!Parser::parseExpression(StringRef(Begin, End - Begin),
nullptr,
202 &QS.NamedValues, &Value, &Diag)) {
203 return makeInvalidQueryFromDiagnostics(Diag);
211 return completeMatcherExpression();
214 Optional<DynTypedMatcher> Matcher = Parser::parseMatcherExpression(
215 StringRef(Begin, End - Begin),
nullptr, &QS.NamedValues, &Diag);
217 return makeInvalidQueryFromDiagnostics(Diag);
225 .Case(
"output", PQV_Output)
226 .Case(
"bind-root", PQV_BindRoot)
227 .Default(PQV_Invalid);
230 if (Var == PQV_Invalid)
231 return new InvalidQuery(
"unknown variable: '" + VarStr +
"'");
236 Q = parseSetOutputKind();
239 Q = parseSetBool(&QuerySession::BindRoot);
242 llvm_unreachable(
"Invalid query kind");
249 StringRef
Name = lexWord();
254 return endQuery(
new LetQuery(Name, VariantValue()));
258 return new InvalidQuery(
"unknown command: " + CommandStr);
261 llvm_unreachable(
"Invalid query kind");
268 std::vector<LineEditor::Completion>
271 P.CompletionPos = Line.data() + Pos;
274 return P.Completions;
No-op query (i.e. a blank line).
Represents the state for a particular clang-query session.
T Default(const T &Value) const
Any query which resulted in a parse error. The error message is in ErrStr.
llvm::IntrusiveRefCntPtr< Query > QueryRef
Query for "match MATCHER".
LexOrCompleteWord & Case(const char(&S)[N], const T &Value, bool IsCompletion=true)
Query for "set VAR VALUE".
LexOrCompleteWord(QueryParser *P, StringRef Word, size_t WCP)