32#include "llvm/ADT/STLExtras.h"
33#include "llvm/Support/Errc.h"
34#include "llvm/Support/Error.h"
46findSymbolOccurrences(
const NamedDecl *ND, RefactoringRuleContext &Context) {
47 std::vector<std::string> USRs =
49 std::string PrevName = ND->getNameAsString();
51 Context.getASTContext().getTranslationUnitDecl());
60 "Finds and renames symbols in code with no indexer support",
71 return Context.createDiagnosticError(
72 SelectionRange.
getBegin(), diag::err_refactor_selection_no_symbol);
83 return Occurrences.takeError();
87 *Occurrences, Context.getASTContext().getSourceManager(), Name);
92 std::string OldQualifiedName,
93 std::string NewQualifiedName) {
97 return llvm::make_error<llvm::StringError>(
"Could not find symbol " +
99 llvm::errc::invalid_argument);
105 "local-qualified-rename",
108 R
"(Finds and renames qualified symbols in code within a translation unit.
109It is used to move/rename a symbol to a new namespace/name:
110 * Supported symbols: classes, class members, functions, enums, and type alias.
111 * Renames all symbol occurrences from the old qualified name to the new
112 qualified name. All symbol references will be correctly qualified; For
113 symbol definitions, only name will be changed.
114For example, rename "A::Foo" to "B::Bar":
124 New code after rename:
137QualifiedRenameRule::createSourceReplacements(RefactoringRuleContext &Context) {
139 assert(!USRs.empty());
141 USRs, NewQualifiedName, Context.getASTContext().getTranslationUnitDecl());
148 std::vector<AtomicChange> Changes;
149 for (
const auto &Occurrence : Occurrences) {
152 "Mismatching number of ranges and name pieces");
154 for (
const auto &
Range : llvm::enumerate(Ranges)) {
159 return std::move(Error);
161 Changes.push_back(std::move(Change));
163 return std::move(Changes);
170 std::map<std::string, tooling::Replacements> *FileToReplaces) {
174 (*FileToReplaces)[std::string(Replace.getFilePath())].add(Replace);
176 llvm::errs() <<
"Renaming failed in " << Replace.getFilePath() <<
"! "
177 << llvm::toString(std::move(Err)) <<
"\n";
186 const std::vector<std::string> &NewNames,
187 const std::vector<std::string> &PrevNames,
188 const std::vector<std::vector<std::string>> &USRList,
189 std::map<std::string, tooling::Replacements> &FileToReplaces,
191 : NewNames(NewNames), PrevNames(PrevNames), USRList(USRList),
192 FileToReplaces(FileToReplaces), PrintLocations(PrintLocations) {}
195 for (
unsigned I = 0; I < NewNames.size(); ++I) {
197 if (PrevNames[I].empty())
205 const std::string &PrevName,
206 const std::vector<std::string> &USRs) {
207 const SourceManager &SourceMgr = Context.getSourceManager();
210 USRs, PrevName, Context.getTranslationUnitDecl());
211 if (PrintLocations) {
212 for (
const auto &Occurrence : Occurrences) {
213 FullSourceLoc FullLoc(Occurrence.getNameRanges()[0].getBegin(),
215 errs() <<
"clang-rename: renamed at: " << SourceMgr.getFilename(FullLoc)
216 <<
":" << FullLoc.getSpellingLineNumber() <<
":"
217 << FullLoc.getSpellingColumnNumber() <<
"\n";
226 llvm::errs() <<
"Failed to create renaming replacements for '" << PrevName
227 <<
"'! " << llvm::toString(Change.takeError()) <<
"\n";
234 const std::vector<std::string> &NewNames, &PrevNames;
235 const std::vector<std::vector<std::string>> &USRList;
236 std::map<std::string, tooling::Replacements> &FileToReplaces;
247 const std::vector<std::vector<std::string>> &USRList,
248 std::map<std::string, tooling::Replacements> &FileToReplaces)
249 : NewNames(NewNames), USRList(USRList), FileToReplaces(FileToReplaces) {
250 assert(USRList.size() == NewNames.size());
254 for (
unsigned I = 0; I < NewNames.size(); ++I) {
258 USRList[I], NewNames[I], Context.getTranslationUnitDecl());
264 const std::vector<std::string> &NewNames;
265 const std::vector<std::vector<std::string>> &USRList;
266 std::map<std::string, tooling::Replacements> &FileToReplaces;
270 return std::make_unique<RenamingASTConsumer>(NewNames, PrevNames, USRList,
271 FileToReplaces, PrintLocations);
275 return std::make_unique<USRSymbolRenamer>(NewNames, USRList, FileToReplaces);
Defines the clang::ASTContext interface.
Defines the clang::FileManager interface and associated types.
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
Defines the clang::Preprocessor interface.
Provides an action to rename every symbol at a point.
Methods for determining the USR of a symbol at a location in source code.
Provides an action to find all relevant USRs at a point.
Provides functionality for finding all instances of a USR in a given AST.
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 ...
static CharSourceRange getCharRange(SourceRange R)
This represents a decl that may have a name.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
The refactoring rule context stores all of the inputs that might be needed by a refactoring action ru...
The JSON file list parser is used to communicate input to InstallAPI.
Diagnostic wrappers for TextAPI types for error reporting.