Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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