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);
65 : Word(P->lexWord()), Switch(Word), P(P),
66 WordCompletionPos(StringRef::npos) {
68 if (P->CompletionPos && P->CompletionPos <= Word.data() + Word.size()) {
69 if (P->CompletionPos < Word.data())
70 WordCompletionPos = 0;
72 WordCompletionPos = P->CompletionPos - Word.data();
77 bool IsCompletion =
true) {
79 if (WordCompletionPos == StringRef::npos)
80 Switch.
Case(CaseStr, Value);
81 else if (CaseStr.size() != 0 && IsCompletion && WordCompletionPos <= CaseStr.size() &&
82 CaseStr.substr(0, WordCompletionPos) ==
83 Word.substr(0, WordCompletionPos))
84 P->Completions.push_back(LineEditor::Completion(
85 (CaseStr.substr(WordCompletionPos) +
" ").str(), CaseStr));
89 T
Default(T Value) {
return Switch.Default(Value); }
99 return new InvalidQuery(
"expected 'true' or 'false', got '" + ValStr +
"'");
104 QueryRef QueryParser::parseSetOutputKind() {
111 if (OutKind == ~0u) {
112 return new InvalidQuery(
"expected 'diag', 'print' or 'dump', got '" +
119 const char *Extra = Begin;
120 if (!lexWord().empty())
122 StringRef(Extra, End - Extra) +
"'");
141 QueryRef makeInvalidQueryFromDiagnostics(
const Diagnostics &Diag) {
143 llvm::raw_string_ostream OS(ErrStr);
144 Diag.printToStreamFull(OS);
150 QueryRef QueryParser::completeMatcherExpression() {
151 std::vector<MatcherCompletion> Comps = Parser::completeExpression(
152 StringRef(Begin, End - Begin), CompletionPos - Begin,
nullptr,
154 for (
auto I = Comps.begin(), E = Comps.end(); I != E; ++I) {
155 Completions.push_back(LineEditor::Completion(I->TypedText, I->MatcherDecl));
161 StringRef CommandStr;
162 ParsedQueryKind QKind = LexOrCompleteWord<ParsedQueryKind>(
this, CommandStr)
164 .Case(
"help", PQK_Help)
165 .Case(
"m", PQK_Match,
false)
166 .Case(
"let", PQK_Let)
167 .Case(
"match", PQK_Match)
168 .Case(
"set", PQK_Set)
169 .Case(
"unlet", PQK_Unlet)
170 .Case(
"quit", PQK_Quit)
171 .Default(PQK_Invalid);
184 StringRef
Name = lexWord();
190 return completeMatcherExpression();
193 ast_matchers::dynamic::VariantValue Value;
194 if (!Parser::parseExpression(StringRef(Begin, End - Begin),
nullptr,
195 &QS.NamedValues, &Value, &Diag)) {
196 return makeInvalidQueryFromDiagnostics(Diag);
204 return completeMatcherExpression();
207 Optional<DynTypedMatcher> Matcher = Parser::parseMatcherExpression(
208 StringRef(Begin, End - Begin),
nullptr, &QS.NamedValues, &Diag);
210 return makeInvalidQueryFromDiagnostics(Diag);
219 .Case(
"output", PQV_Output)
220 .Case(
"bind-root", PQV_BindRoot)
221 .Default(PQV_Invalid);
224 if (Var == PQV_Invalid)
225 return new InvalidQuery(
"unknown variable: '" + VarStr +
"'");
230 Q = parseSetOutputKind();
233 Q = parseSetBool(&QuerySession::BindRoot);
236 llvm_unreachable(
"Invalid query kind");
243 StringRef
Name = lexWord();
248 return endQuery(
new LetQuery(Name, VariantValue()));
252 return new InvalidQuery(
"unknown command: " + CommandStr);
255 llvm_unreachable(
"Invalid query kind");
262 std::vector<LineEditor::Completion>
265 P.CompletionPos = Line.data() +
Pos;
268 return P.Completions;
Some operations such as code completion produce a set of candidates.
No-op query (i.e. a blank line).
Represents the state for a particular clang-query session.
Any query which resulted in a parse error. The error message is in ErrStr.
llvm::IntrusiveRefCntPtr< Query > QueryRef
Query for "match MATCHER".
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
LexOrCompleteWord & Case(llvm::StringLiteral CaseStr, const T &Value, bool IsCompletion=true)
Query for "set VAR VALUE".
LexOrCompleteWord(QueryParser *P, StringRef &OutWord)