matcher.h 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. // Adds the Matcher to the finder with the provided callback.
  60. virtual void AddMatcher(
  61. clang::ast_matchers::MatchFinder* finder,
  62. clang::ast_matchers::MatchFinder::MatchCallback* callback) = 0;
  63. };
  64. // A convenience factory that implements CreateMatcher for Matchers that have a
  65. // standard constructor.
  66. template <typename MatcherType>
  67. class MatcherFactoryBase : public MatcherFactory {
  68. public:
  69. auto CreateMatcher(
  70. const clang::ast_matchers::MatchFinder::MatchResult* match_result,
  71. Matcher::ReplacementMap* replacements)
  72. -> std::unique_ptr<Matcher> override {
  73. return std::make_unique<MatcherType>(match_result, replacements);
  74. }
  75. };
  76. } // namespace Carbon
  77. #endif // MIGRATE_CPP_CPP_REFACTORING_MATCHER_H_