matcher.h 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef MIGRATE_CPP_CPP_REFACTORING_MATCHER_H_
  5. #define MIGRATE_CPP_CPP_REFACTORING_MATCHER_H_
  6. #include "clang/ASTMatchers/ASTMatchFinder.h"
  7. #include "clang/Lex/Lexer.h"
  8. #include "clang/Tooling/Core/Replacement.h"
  9. namespace Carbon {
  10. // This is an abstract class with helpers to make it easier to write matchers.
  11. // Note a MatcherFactory (below) is also typically required.
  12. class Matcher {
  13. public:
  14. using ReplacementMap = std::map<std::string, clang::tooling::Replacements>;
  15. Matcher(const clang::ast_matchers::MatchFinder::MatchResult* in_match_result,
  16. ReplacementMap* in_replacements)
  17. : match_result(in_match_result), replacements(in_replacements) {}
  18. virtual ~Matcher() = default;
  19. // Performs main execution of the matcher when a result is found.
  20. virtual void Run() = 0;
  21. protected:
  22. // Replaces the given range with the specified text.
  23. void AddReplacement(clang::CharSourceRange range,
  24. llvm::StringRef replacement_text);
  25. // Returns a matched node by ID, exiting if not present.
  26. template <typename NodeType>
  27. auto GetNodeAsOrDie(llvm::StringRef id) -> const NodeType& {
  28. auto* node = match_result->Nodes.getNodeAs<NodeType>(id);
  29. if (!node) {
  30. llvm::report_fatal_error(std::string("getNodeAs failed for ") + id);
  31. }
  32. return *node;
  33. }
  34. // Returns the language options.
  35. auto GetLangOpts() -> const clang::LangOptions& {
  36. return match_result->Context->getLangOpts();
  37. }
  38. // Returns the full source manager.
  39. auto GetSourceManager() -> const clang::SourceManager& {
  40. return *match_result->SourceManager;
  41. }
  42. // Returns the source text for a given range.
  43. auto GetSourceText(clang::CharSourceRange range) -> llvm::StringRef {
  44. return clang::Lexer::getSourceText(range, GetSourceManager(),
  45. GetLangOpts());
  46. }
  47. private:
  48. const clang::ast_matchers::MatchFinder::MatchResult* const match_result;
  49. ReplacementMap* const replacements;
  50. };
  51. // A factory used to instantiate per-MatchResult Matchers, to be registered with
  52. // the MatcherManager.
  53. class MatcherFactory {
  54. public:
  55. virtual ~MatcherFactory() = default;
  56. virtual auto CreateMatcher(
  57. const clang::ast_matchers::MatchFinder::MatchResult* match_result,
  58. Matcher::ReplacementMap* replacements) -> std::unique_ptr<Matcher> = 0;
  59. // Returns the AST matcher which determines when the Matcher is instantiated
  60. // and run.
  61. virtual auto GetAstMatcher() -> clang::ast_matchers::DeclarationMatcher = 0;
  62. };
  63. // A convenience factory that implements CreateMatcher for Matchers that have a
  64. // standard constructor.
  65. template <typename MatcherType>
  66. class MatcherFactoryBase : public MatcherFactory {
  67. public:
  68. auto CreateMatcher(
  69. const clang::ast_matchers::MatchFinder::MatchResult* match_result,
  70. Matcher::ReplacementMap* replacements)
  71. -> std::unique_ptr<Matcher> override {
  72. return std::make_unique<MatcherType>(match_result, replacements);
  73. }
  74. };
  75. } // namespace Carbon
  76. #endif // MIGRATE_CPP_CPP_REFACTORING_MATCHER_H_