16 using llvm::StringError;
17 using llvm::make_error;
28 std::map<std::string, Replacements> &FileToReplaces)
29 : FileToReplaces(FileToReplaces) {}
32 const ast_matchers::internal::DynTypedMatcher &Matcher,
35 Callbacks.push_back(Callback);
41 : Refactoring(Refactoring) {}
46 for (
const auto &Callback : Refactoring.Callbacks) {
47 Callback->getReplacements().clear();
49 Refactoring.MatchFinder.
matchAST(Context);
50 for (
const auto &Callback : Refactoring.Callbacks) {
51 for (
const auto &
Replacement : Callback->getReplacements()) {
57 <<
" due to this error:\n"
69 return std::make_unique<RefactoringASTConsumer>(*
this);
90 if (
const Stmt *FromMatch = Result.Nodes.getNodeAs<
Stmt>(FromId)) {
92 *Result.SourceManager,
108 const Stmt *FromMatch = Result.Nodes.getNodeAs<
Stmt>(FromId);
109 const Stmt *ToMatch = Result.Nodes.getNodeAs<
Stmt>(ToId);
110 if (FromMatch && ToMatch) {
129 const Stmt *Body = PickTrueBranch ?
Node->getThen() :
Node->getElse();
139 }
else if (!PickTrueBranch) {
154 ReplaceNodeWithTemplate::ReplaceNodeWithTemplate(
155 llvm::StringRef FromId, std::vector<TemplateElement> Template)
156 : FromId(
std::
string(FromId)), Template(
std::move(Template)) {}
160 std::vector<TemplateElement> ParsedTemplate;
161 for (
size_t Index = 0; Index < ToTemplate.size();) {
162 if (ToTemplate[Index] ==
'$') {
163 if (ToTemplate.substr(Index, 2) ==
"$$") {
165 ParsedTemplate.push_back(
167 }
else if (ToTemplate.substr(Index, 2) ==
"${") {
168 size_t EndOfIdentifier = ToTemplate.find(
"}", Index);
169 if (EndOfIdentifier == std::string::npos) {
170 return make_error<StringError>(
171 "Unterminated ${...} in replacement template near " +
172 ToTemplate.substr(Index),
173 llvm::inconvertibleErrorCode());
176 ToTemplate.substr(Index + 2, EndOfIdentifier - Index - 2));
177 ParsedTemplate.push_back(
179 Index = EndOfIdentifier + 1;
181 return make_error<StringError>(
182 "Invalid $ in replacement template near " +
183 ToTemplate.substr(Index),
184 llvm::inconvertibleErrorCode());
187 size_t NextIndex = ToTemplate.find(
'$', Index + 1);
188 ParsedTemplate.push_back(TemplateElement{
190 std::string(ToTemplate.substr(Index, NextIndex - Index))});
194 return std::unique_ptr<ReplaceNodeWithTemplate>(
200 const auto &NodeMap = Result.Nodes.getMap();
203 for (
const auto &Element : Template) {
204 switch (Element.Type) {
206 ToText += Element.Value;
209 auto NodeIter = NodeMap.find(Element.Value);
210 if (NodeIter == NodeMap.end()) {
211 llvm::errs() <<
"Node " << Element.Value
212 <<
" used in replacement template not bound in Matcher \n";
213 llvm::report_fatal_error(
"Unbound node in replacement template.");
218 Result.Context->getLangOpts());
223 if (NodeMap.count(FromId) == 0) {
224 llvm::errs() <<
"Node to be replaced " << FromId
225 <<
" not bound in query.\n";
226 llvm::report_fatal_error(
"FromId node not bound in MatchResult");
230 Result.Context->getLangOpts());
235 llvm::report_fatal_error(
"Replacement failed");