12 #include "clang/ASTMatchers/ASTMatchFinder.h" 13 #include "clang/Frontend/ASTUnit.h" 14 #include "clang/Frontend/TextDiagnostic.h" 15 #include "llvm/Support/raw_ostream.h" 25 bool InvalidQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
30 bool NoOpQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
34 bool HelpQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
35 OS <<
"Available commands:\n\n" 36 " match MATCHER, m MATCHER " 37 "Match the loaded ASTs against the given matcher.\n" 38 " let NAME MATCHER, l NAME MATCHER " 39 "Give a matcher expression a name, to be used later\n" 41 "as part of other expressions.\n" 42 " set bind-root (true|false) " 43 "Set whether to bind the root matcher to \"root\".\n" 44 " set print-matcher (true|false) " 45 "Set whether to print the current matcher,\n" 46 " set output <feature> " 47 "Set whether to output only <feature> content.\n" 48 " enable output <feature> " 49 "Enable <feature> content non-exclusively.\n" 50 " disable output <feature> " 51 "Disable <feature> content non-exclusively.\n" 53 "Terminates the query session.\n\n" 54 "Several commands accept a <feature> parameter. The available features " 57 "Pretty-print bound nodes.\n" 59 "Diagnostic location for bound nodes.\n" 61 "Detailed AST output for bound nodes.\n" 63 "Detailed AST output for bound nodes (alias of detailed-ast).\n\n";
67 bool QuitQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
74 struct CollectBoundNodes : MatchFinder::MatchCallback {
76 CollectBoundNodes(std::vector<BoundNodes> &Bindings) : Bindings(Bindings) {}
77 void run(
const MatchFinder::MatchResult &
Result)
override {
78 Bindings.push_back(Result.Nodes);
84 bool MatchQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
85 unsigned MatchCount = 0;
87 for (
auto &AST : QS.
ASTs) {
89 std::vector<BoundNodes> Matches;
90 DynTypedMatcher MaybeBoundMatcher = Matcher;
92 llvm::Optional<DynTypedMatcher> M = Matcher.tryBind(
"root");
94 MaybeBoundMatcher = *M;
96 CollectBoundNodes Collect(Matches);
97 if (!Finder.addDynamicMatcher(MaybeBoundMatcher, &Collect)) {
98 OS <<
"Not a valid top-level matcher.\n";
101 Finder.matchAST(AST->getASTContext());
104 std::string prefixText =
"Matcher: ";
105 OS <<
"\n " << prefixText << Source <<
"\n";
106 OS <<
" " << std::string(prefixText.size() + Source.size(),
'=') <<
'\n';
109 for (
auto MI = Matches.begin(), ME = Matches.end(); MI != ME; ++MI) {
110 OS <<
"\nMatch #" << ++MatchCount <<
":\n\n";
112 for (
auto BI = MI->getMap().begin(), BE = MI->getMap().end(); BI != BE;
115 clang::SourceRange R = BI->second.getSourceRange();
117 TextDiagnostic TD(OS, AST->getASTContext().getLangOpts(),
118 &AST->getDiagnostics().getDiagnosticOptions());
120 FullSourceLoc(R.getBegin(), AST->getSourceManager()),
121 DiagnosticsEngine::Note,
"\"" + BI->first +
"\" binds here",
122 CharSourceRange::getTokenRange(R), None);
126 OS <<
"Binding for \"" << BI->first <<
"\":\n";
127 BI->second.print(OS, AST->getASTContext().getPrintingPolicy());
131 OS <<
"Binding for \"" << BI->first <<
"\":\n";
132 BI->second.dump(OS, AST->getSourceManager());
137 if (MI->getMap().empty())
138 OS <<
"No bindings.\n";
142 OS << MatchCount << (MatchCount == 1 ?
" match.\n" :
" matches.\n");
Represents the state for a particular clang-query session.
llvm::ArrayRef< std::unique_ptr< ASTUnit > > ASTs
llvm::StringMap< ast_matchers::dynamic::VariantValue > NamedValues
static constexpr llvm::StringLiteral Name
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::vector< BoundNodes > & Bindings