]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Tooling/RefactoringCallbacks.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Tooling / RefactoringCallbacks.h
1 //===--- RefactoringCallbacks.h - Structural query framework ----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  Provides callbacks to make common kinds of refactorings easy.
11 //
12 //  The general idea is to construct a matcher expression that describes a
13 //  subtree match on the AST and then replace the corresponding source code
14 //  either by some specific text or some other AST node.
15 //
16 //  Example:
17 //  int main(int argc, char **argv) {
18 //    ClangTool Tool(argc, argv);
19 //    MatchFinder Finder;
20 //    ReplaceStmtWithText Callback("integer", "42");
21 //    Finder.AddMatcher(id("integer", expression(integerLiteral())), Callback);
22 //    return Tool.run(newFrontendActionFactory(&Finder));
23 //  }
24 //
25 //  This will replace all integer literals with "42".
26 //
27 //===----------------------------------------------------------------------===//
28
29 #ifndef LLVM_CLANG_TOOLING_REFACTORINGCALLBACKS_H
30 #define LLVM_CLANG_TOOLING_REFACTORINGCALLBACKS_H
31
32 #include "clang/ASTMatchers/ASTMatchFinder.h"
33 #include "clang/Tooling/Refactoring.h"
34
35 namespace clang {
36 namespace tooling {
37
38 /// Base class for RefactoringCallbacks.
39 ///
40 /// Collects \c tooling::Replacements while running.
41 class RefactoringCallback : public ast_matchers::MatchFinder::MatchCallback {
42 public:
43   RefactoringCallback();
44   Replacements &getReplacements();
45
46 protected:
47   Replacements Replace;
48 };
49
50 /// Adaptor between \c ast_matchers::MatchFinder and \c
51 /// tooling::RefactoringTool.
52 ///
53 /// Runs AST matchers and stores the \c tooling::Replacements in a map.
54 class ASTMatchRefactorer {
55 public:
56   explicit ASTMatchRefactorer(
57     std::map<std::string, Replacements> &FileToReplaces);
58
59   template <typename T>
60   void addMatcher(const T &Matcher, RefactoringCallback *Callback) {
61     MatchFinder.addMatcher(Matcher, Callback);
62     Callbacks.push_back(Callback);
63   }
64
65   void addDynamicMatcher(const ast_matchers::internal::DynTypedMatcher &Matcher,
66                          RefactoringCallback *Callback);
67
68   std::unique_ptr<ASTConsumer> newASTConsumer();
69
70 private:
71   friend class RefactoringASTConsumer;
72   std::vector<RefactoringCallback *> Callbacks;
73   ast_matchers::MatchFinder MatchFinder;
74   std::map<std::string, Replacements> &FileToReplaces;
75 };
76
77 /// Replace the text of the statement bound to \c FromId with the text in
78 /// \c ToText.
79 class ReplaceStmtWithText : public RefactoringCallback {
80 public:
81   ReplaceStmtWithText(StringRef FromId, StringRef ToText);
82   void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
83
84 private:
85   std::string FromId;
86   std::string ToText;
87 };
88
89 /// Replace the text of an AST node bound to \c FromId with the result of
90 /// evaluating the template in \c ToTemplate.
91 ///
92 /// Expressions of the form ${NodeName} in \c ToTemplate will be
93 /// replaced by the text of the node bound to ${NodeName}. The string
94 /// "$$" will be replaced by "$".
95 class ReplaceNodeWithTemplate : public RefactoringCallback {
96 public:
97   static llvm::Expected<std::unique_ptr<ReplaceNodeWithTemplate>>
98   create(StringRef FromId, StringRef ToTemplate);
99   void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
100
101 private:
102   struct TemplateElement {
103     enum { Literal, Identifier } Type;
104     std::string Value;
105   };
106   ReplaceNodeWithTemplate(llvm::StringRef FromId,
107                           std::vector<TemplateElement> Template);
108   std::string FromId;
109   std::vector<TemplateElement> Template;
110 };
111
112 /// Replace the text of the statement bound to \c FromId with the text of
113 /// the statement bound to \c ToId.
114 class ReplaceStmtWithStmt : public RefactoringCallback {
115 public:
116   ReplaceStmtWithStmt(StringRef FromId, StringRef ToId);
117   void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
118
119 private:
120   std::string FromId;
121   std::string ToId;
122 };
123
124 /// Replace an if-statement bound to \c Id with the outdented text of its
125 /// body, choosing the consequent or the alternative based on whether
126 /// \c PickTrueBranch is true.
127 class ReplaceIfStmtWithItsBody : public RefactoringCallback {
128 public:
129   ReplaceIfStmtWithItsBody(StringRef Id, bool PickTrueBranch);
130   void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
131
132 private:
133   std::string Id;
134   const bool PickTrueBranch;
135 };
136
137 } // end namespace tooling
138 } // end namespace clang
139
140 #endif