17 using llvm::StringError;
18 using llvm::make_error;
29 std::map<std::string, Replacements> &FileToReplaces)
30 : FileToReplaces(FileToReplaces) {}
33 const ast_matchers::internal::DynTypedMatcher &Matcher,
36 Callbacks.push_back(Callback);
42 : Refactoring(Refactoring) {}
47 for (
const auto &Callback : Refactoring.Callbacks) {
48 Callback->getReplacements().clear();
50 Refactoring.MatchFinder.matchAST(Context);
51 for (
const auto &Callback : Refactoring.Callbacks) {
52 for (
const auto &
Replacement : Callback->getReplacements()) {
58 <<
" due to this error:\n" 70 return llvm::make_unique<RefactoringASTConsumer>(*this);
87 : FromId(FromId), ToText(ToText) {}
105 : FromId(FromId), ToId(ToId) {}
111 if (FromMatch && ToMatch) {
125 : Id(Id), PickTrueBranch(PickTrueBranch) {}
130 const Stmt *Body = PickTrueBranch ?
Node->getThen() :
Node->getElse();
140 }
else if (!PickTrueBranch) {
155 ReplaceNodeWithTemplate::ReplaceNodeWithTemplate(
156 llvm::StringRef FromId, std::vector<TemplateElement> Template)
157 : FromId(FromId), Template(std::move(Template)) {}
161 std::vector<TemplateElement> ParsedTemplate;
162 for (
size_t Index = 0; Index < ToTemplate.size();) {
163 if (ToTemplate[Index] ==
'$') {
164 if (ToTemplate.substr(Index, 2) ==
"$$") {
166 ParsedTemplate.push_back(
167 TemplateElement{TemplateElement::Literal,
"$"});
168 }
else if (ToTemplate.substr(Index, 2) ==
"${") {
169 size_t EndOfIdentifier = ToTemplate.find(
"}", Index);
170 if (EndOfIdentifier == std::string::npos) {
171 return make_error<StringError>(
172 "Unterminated ${...} in replacement template near " +
173 ToTemplate.substr(Index),
174 llvm::inconvertibleErrorCode());
176 std::string SourceNodeName =
177 ToTemplate.substr(Index + 2, EndOfIdentifier - Index - 2);
178 ParsedTemplate.push_back(
179 TemplateElement{TemplateElement::Identifier, SourceNodeName});
180 Index = EndOfIdentifier + 1;
182 return make_error<StringError>(
183 "Invalid $ in replacement template near " +
184 ToTemplate.substr(Index),
185 llvm::inconvertibleErrorCode());
188 size_t NextIndex = ToTemplate.find(
'$', Index + 1);
189 ParsedTemplate.push_back(
190 TemplateElement{TemplateElement::Literal,
191 ToTemplate.substr(Index, NextIndex - Index)});
195 return std::unique_ptr<ReplaceNodeWithTemplate>(
204 for (
const auto &Element : Template) {
205 switch (Element.Type) {
206 case TemplateElement::Literal:
207 ToText += Element.Value;
209 case TemplateElement::Identifier: {
210 auto NodeIter = NodeMap.find(Element.Value);
211 if (NodeIter == NodeMap.end()) {
212 llvm::errs() <<
"Node " << Element.Value
213 <<
" used in replacement template not bound in Matcher \n";
214 llvm::report_fatal_error(
"Unbound node in replacement template.");
224 if (NodeMap.count(FromId) == 0) {
225 llvm::errs() <<
"Node to be replaced " << FromId
226 <<
" not bound in query.\n";
227 llvm::report_fatal_error(
"FromId node not bound in MatchResult");
236 llvm::report_fatal_error(
"Replacement failed");
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
Stmt - This represents one statement.
IfStmt - This represents an if/then/else.
static CharSourceRange getTokenRange(SourceRange R)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const IDToNodeMap & getMap() const
Retrieve mapping from binding identifiers to bound nodes.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
void run(const ast_matchers::MatchFinder::MatchResult &Result) override
Called on every match by the MatchFinder.
ReplaceIfStmtWithItsBody(StringRef Id, bool PickTrueBranch)
const T * getNodeAs(StringRef ID) const
Returns the AST node bound to ID.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
Represents a character-granular source range.
Contains all information for a given match.
ReplaceStmtWithText(StringRef FromId, StringRef ToText)
clang::ASTContext *const Context
Utilities for interpreting the matched AST structures.
const BoundNodes Nodes
Contains the nodes bound on the current match.
ast_type_traits::DynTypedNode Node
Dataflow Directional Tag Classes.
void run(const ast_matchers::MatchFinder::MatchResult &Result) override
Called on every match by the MatchFinder.
std::string toString(const til::SExpr *E)
Defines the clang::SourceLocation class and associated facilities.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
clang::SourceManager *const SourceManager
const LangOptions & getLangOpts() const
This class handles loading and caching of source files into memory.
bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, MatchCallback *Action)
Adds a matcher to execute when running over the AST.