11 #include "clang/AST/ASTDumper.h" 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 SmallVector<StringRef, 4>
Lines;
105 Source.split(Lines,
"\n");
106 auto FirstLine = Lines[0];
107 Lines.erase(Lines.begin(), Lines.begin() + 1);
108 while (!Lines.empty() && Lines.back().empty()) {
109 Lines.resize(Lines.size() - 1);
111 unsigned MaxLength = FirstLine.size();
112 std::string PrefixText =
"Matcher: ";
113 OS <<
"\n " << PrefixText << FirstLine;
115 for (
auto Line : Lines) {
116 OS <<
"\n" << std::string(PrefixText.size() + 2,
' ') <<
Line;
117 MaxLength = std::max<int>(MaxLength,
Line.rtrim().size());
121 <<
" " << std::string(PrefixText.size() + MaxLength,
'=') <<
"\n\n";
124 for (
auto MI = Matches.begin(), ME = Matches.end(); MI != ME; ++MI) {
125 OS <<
"\nMatch #" << ++MatchCount <<
":\n\n";
127 for (
auto BI = MI->getMap().begin(), BE = MI->getMap().end(); BI != BE;
130 clang::SourceRange R = BI->second.getSourceRange();
132 TextDiagnostic TD(OS, AST->getASTContext().getLangOpts(),
133 &AST->getDiagnostics().getDiagnosticOptions());
135 FullSourceLoc(R.getBegin(), AST->getSourceManager()),
136 DiagnosticsEngine::Note,
"\"" + BI->first +
"\" binds here",
141 OS <<
"Binding for \"" << BI->first <<
"\":\n";
142 BI->second.print(OS, AST->getASTContext().getPrintingPolicy());
146 OS <<
"Binding for \"" << BI->first <<
"\":\n";
147 const ASTContext &
Ctx = AST->getASTContext();
148 const SourceManager &SM = Ctx.getSourceManager();
149 ASTDumper Dumper(OS, &Ctx.getCommentCommandTraits(), &SM,
150 SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
151 Dumper.Visit(BI->second);
156 if (MI->getMap().empty())
157 OS <<
"No bindings.\n";
161 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< Range > getTokenRange(const SourceManager &SM, const LangOptions &LangOpts, SourceLocation TokLoc)
Returns the taken range at TokLoc.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::vector< BoundNodes > & Bindings