16using llvm::StringError;
17using 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);
86 : FromId(
std::string(FromId)), ToText(
std::string(ToText)) {}
90 if (
const Stmt *FromMatch =
Result.Nodes.getNodeAs<
Stmt>(FromId)) {
97 llvm::errs() << llvm::toString(std::move(Err)) <<
"\n";
104 : FromId(
std::string(FromId)), ToId(
std::string(ToId)) {}
110 if (FromMatch && ToMatch) {
116 llvm::errs() << llvm::toString(std::move(Err)) <<
"\n";
124 :
Id(
std::string(
Id)), PickTrueBranch(PickTrueBranch) {}
129 const Stmt *Body = PickTrueBranch ?
Node->getThen() :
Node->getElse();
136 llvm::errs() << llvm::toString(std::move(Err)) <<
"\n";
139 }
else if (!PickTrueBranch) {
147 llvm::errs() << llvm::toString(std::move(Err)) <<
"\n";
154ReplaceNodeWithTemplate::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(
166 TemplateElement{TemplateElement::Literal,
"$"});
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());
175 std::string SourceNodeName = std::string(
176 ToTemplate.substr(Index + 2, EndOfIdentifier - Index - 2));
177 ParsedTemplate.push_back(
178 TemplateElement{TemplateElement::Identifier, SourceNodeName});
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{
189 TemplateElement::Literal,
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) {
205 case TemplateElement::Literal:
206 ToText += Element.Value;
208 case TemplateElement::Identifier: {
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());
234 <<
"! " << llvm::toString(std::move(Err)) <<
"\n";
235 llvm::report_fatal_error(
"Replacement failed");
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SourceLocation class and associated facilities.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Represents a character-granular source range.
static CharSourceRange getTokenRange(SourceRange R)
IfStmt - This represents an if/then/else.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
This class handles loading and caching of source files into memory.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
A class to allow finding matches over the Clang AST.
bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, MatchCallback *Action)
Adds a matcher to execute when running over the AST.
void matchAST(ASTContext &Context)
Finds all matches in the given AST.
ReplaceIfStmtWithItsBody(StringRef Id, bool PickTrueBranch)
void run(const ast_matchers::MatchFinder::MatchResult &Result) override
Called on every match by the MatchFinder.
ReplaceStmtWithText(StringRef FromId, StringRef ToText)
void run(const ast_matchers::MatchFinder::MatchResult &Result) override
Called on every match by the MatchFinder.
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
Contains all information for a given match.