// Part of the Carbon Language project, under the Apache License v2.0 with LLVM // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #ifndef CARBON_MIGRATE_CPP_CPP_REFACTORING_MATCHER_H_ #define CARBON_MIGRATE_CPP_CPP_REFACTORING_MATCHER_H_ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" #include "clang/Tooling/Core/Replacement.h" namespace Carbon { // This is an abstract class with helpers to make it easier to write matchers. // Note a MatcherFactory (below) is also typically required. class Matcher { public: using ReplacementMap = std::map; Matcher(const clang::ast_matchers::MatchFinder::MatchResult* in_match_result, ReplacementMap* in_replacements) : match_result(in_match_result), replacements(in_replacements) {} virtual ~Matcher() = default; // Performs main execution of the matcher when a result is found. virtual void Run() = 0; protected: // Replaces the given range with the specified text. void AddReplacement(clang::CharSourceRange range, llvm::StringRef replacement_text); // Returns a matched node by ID, exiting if not present. template auto GetNodeAsOrDie(llvm::StringRef id) -> const NodeType& { auto* node = match_result->Nodes.getNodeAs(id); if (!node) { llvm::report_fatal_error(std::string("getNodeAs failed for ") + id); } return *node; } // Returns the language options. auto GetLangOpts() -> const clang::LangOptions& { return match_result->Context->getLangOpts(); } // Returns the full source manager. auto GetSourceManager() -> const clang::SourceManager& { return *match_result->SourceManager; } // Returns the source text for a given range. auto GetSourceText(clang::CharSourceRange range) -> llvm::StringRef { return clang::Lexer::getSourceText(range, GetSourceManager(), GetLangOpts()); } private: const clang::ast_matchers::MatchFinder::MatchResult* const match_result; ReplacementMap* const replacements; }; // A factory used to instantiate per-MatchResult Matchers, to be registered with // the MatcherManager. class MatcherFactory { public: virtual ~MatcherFactory() = default; virtual auto CreateMatcher( const clang::ast_matchers::MatchFinder::MatchResult* match_result, Matcher::ReplacementMap* replacements) -> std::unique_ptr = 0; // Adds the Matcher to the finder with the provided callback. virtual void AddMatcher( clang::ast_matchers::MatchFinder* finder, clang::ast_matchers::MatchFinder::MatchCallback* callback) = 0; }; // A convenience factory that implements CreateMatcher for Matchers that have a // standard constructor. template class MatcherFactoryBase : public MatcherFactory { public: auto CreateMatcher( const clang::ast_matchers::MatchFinder::MatchResult* match_result, Matcher::ReplacementMap* replacements) -> std::unique_ptr override { return std::make_unique(match_result, replacements); } }; } // namespace Carbon #endif // CARBON_MIGRATE_CPP_CPP_REFACTORING_MATCHER_H_