Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:37:12

0001 //===--- RefactoringCallbacks.h - Structural query framework ----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  Provides callbacks to make common kinds of refactorings easy.
0010 //
0011 //  The general idea is to construct a matcher expression that describes a
0012 //  subtree match on the AST and then replace the corresponding source code
0013 //  either by some specific text or some other AST node.
0014 //
0015 //  Example:
0016 //  int main(int argc, char **argv) {
0017 //    ClangTool Tool(argc, argv);
0018 //    MatchFinder Finder;
0019 //    ReplaceStmtWithText Callback("integer", "42");
0020 //    Finder.AddMatcher(id("integer", expression(integerLiteral())), Callback);
0021 //    return Tool.run(newFrontendActionFactory(&Finder));
0022 //  }
0023 //
0024 //  This will replace all integer literals with "42".
0025 //
0026 //===----------------------------------------------------------------------===//
0027 
0028 #ifndef LLVM_CLANG_TOOLING_REFACTORINGCALLBACKS_H
0029 #define LLVM_CLANG_TOOLING_REFACTORINGCALLBACKS_H
0030 
0031 #include "clang/ASTMatchers/ASTMatchFinder.h"
0032 #include "clang/Tooling/Refactoring.h"
0033 
0034 namespace clang {
0035 namespace tooling {
0036 
0037 /// Base class for RefactoringCallbacks.
0038 ///
0039 /// Collects \c tooling::Replacements while running.
0040 class RefactoringCallback : public ast_matchers::MatchFinder::MatchCallback {
0041 public:
0042   RefactoringCallback();
0043   Replacements &getReplacements();
0044 
0045 protected:
0046   Replacements Replace;
0047 };
0048 
0049 /// Adaptor between \c ast_matchers::MatchFinder and \c
0050 /// tooling::RefactoringTool.
0051 ///
0052 /// Runs AST matchers and stores the \c tooling::Replacements in a map.
0053 class ASTMatchRefactorer {
0054 public:
0055   explicit ASTMatchRefactorer(
0056     std::map<std::string, Replacements> &FileToReplaces);
0057 
0058   template <typename T>
0059   void addMatcher(const T &Matcher, RefactoringCallback *Callback) {
0060     MatchFinder.addMatcher(Matcher, Callback);
0061     Callbacks.push_back(Callback);
0062   }
0063 
0064   void addDynamicMatcher(const ast_matchers::internal::DynTypedMatcher &Matcher,
0065                          RefactoringCallback *Callback);
0066 
0067   std::unique_ptr<ASTConsumer> newASTConsumer();
0068 
0069 private:
0070   friend class RefactoringASTConsumer;
0071   std::vector<RefactoringCallback *> Callbacks;
0072   ast_matchers::MatchFinder MatchFinder;
0073   std::map<std::string, Replacements> &FileToReplaces;
0074 };
0075 
0076 /// Replace the text of the statement bound to \c FromId with the text in
0077 /// \c ToText.
0078 class ReplaceStmtWithText : public RefactoringCallback {
0079 public:
0080   ReplaceStmtWithText(StringRef FromId, StringRef ToText);
0081   void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
0082 
0083 private:
0084   std::string FromId;
0085   std::string ToText;
0086 };
0087 
0088 /// Replace the text of an AST node bound to \c FromId with the result of
0089 /// evaluating the template in \c ToTemplate.
0090 ///
0091 /// Expressions of the form ${NodeName} in \c ToTemplate will be
0092 /// replaced by the text of the node bound to ${NodeName}. The string
0093 /// "$$" will be replaced by "$".
0094 class ReplaceNodeWithTemplate : public RefactoringCallback {
0095 public:
0096   static llvm::Expected<std::unique_ptr<ReplaceNodeWithTemplate>>
0097   create(StringRef FromId, StringRef ToTemplate);
0098   void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
0099 
0100 private:
0101   struct TemplateElement {
0102     enum { Literal, Identifier } Type;
0103     std::string Value;
0104   };
0105   ReplaceNodeWithTemplate(llvm::StringRef FromId,
0106                           std::vector<TemplateElement> Template);
0107   std::string FromId;
0108   std::vector<TemplateElement> Template;
0109 };
0110 
0111 /// Replace the text of the statement bound to \c FromId with the text of
0112 /// the statement bound to \c ToId.
0113 class ReplaceStmtWithStmt : public RefactoringCallback {
0114 public:
0115   ReplaceStmtWithStmt(StringRef FromId, StringRef ToId);
0116   void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
0117 
0118 private:
0119   std::string FromId;
0120   std::string ToId;
0121 };
0122 
0123 /// Replace an if-statement bound to \c Id with the outdented text of its
0124 /// body, choosing the consequent or the alternative based on whether
0125 /// \c PickTrueBranch is true.
0126 class ReplaceIfStmtWithItsBody : public RefactoringCallback {
0127 public:
0128   ReplaceIfStmtWithItsBody(StringRef Id, bool PickTrueBranch);
0129   void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
0130 
0131 private:
0132   std::string Id;
0133   const bool PickTrueBranch;
0134 };
0135 
0136 } // end namespace tooling
0137 } // end namespace clang
0138 
0139 #endif