summaryrefslogtreecommitdiffstats
path: root/clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2017-08-14 16:19:24 +0000
committerAlex Lorenz <arphaman@gmail.com>2017-08-14 16:19:24 +0000
commit44b94c7eb3dcd7b642934805f13c96c50867accd (patch)
tree7cf9997a6ef3f07c75182f269f16a844b7169500 /clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
parent325ff7c5e00760b111d455608c7bf2257d093f95 (diff)
downloadbcm5719-llvm-44b94c7eb3dcd7b642934805f13c96c50867accd.tar.gz
bcm5719-llvm-44b94c7eb3dcd7b642934805f13c96c50867accd.zip
[rename] Introduce symbol occurrences
Symbol occurrences store the results of local rename and will also be used for the global, indexed rename results. Their kind is used to determine whether they should be renamed automatically or not. They can be converted to a set of AtomicChanges as well. Differential Revision: https://reviews.llvm.org/D36156 llvm-svn: 310853
Diffstat (limited to 'clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp')
-rw-r--r--clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp84
1 files changed, 58 insertions, 26 deletions
diff --git a/clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp b/clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
index de6aba944a4..f4f4befc5d7 100644
--- a/clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
@@ -24,6 +24,7 @@
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Refactoring/Rename/USRLocFinder.h"
#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/STLExtras.h"
#include <string>
#include <vector>
@@ -32,6 +33,45 @@ using namespace llvm;
namespace clang {
namespace tooling {
+Expected<std::vector<AtomicChange>>
+createRenameReplacements(const SymbolOccurrences &Occurrences,
+ const SourceManager &SM,
+ ArrayRef<StringRef> NewNameStrings) {
+ // FIXME: A true local rename can use just one AtomicChange.
+ std::vector<AtomicChange> Changes;
+ for (const auto &Occurrence : Occurrences) {
+ ArrayRef<SourceRange> Ranges = Occurrence.getNameRanges();
+ assert(NewNameStrings.size() == Ranges.size() &&
+ "Mismatching number of ranges and name pieces");
+ AtomicChange Change(SM, Ranges[0].getBegin());
+ for (const auto &Range : llvm::enumerate(Ranges)) {
+ auto Error =
+ Change.replace(SM, CharSourceRange::getCharRange(Range.value()),
+ NewNameStrings[Range.index()]);
+ if (Error)
+ return std::move(Error);
+ }
+ Changes.push_back(std::move(Change));
+ }
+ return Changes;
+}
+
+/// Takes each atomic change and inserts its replacements into the set of
+/// replacements that belong to the appropriate file.
+static void convertChangesToFileReplacements(
+ ArrayRef<AtomicChange> AtomicChanges,
+ std::map<std::string, tooling::Replacements> *FileToReplaces) {
+ for (const auto &AtomicChange : AtomicChanges) {
+ for (const auto &Replace : AtomicChange.getReplacements()) {
+ llvm::Error Err = (*FileToReplaces)[Replace.getFilePath()].add(Replace);
+ if (Err) {
+ llvm::errs() << "Renaming failed in " << Replace.getFilePath() << "! "
+ << llvm::toString(std::move(Err)) << "\n";
+ }
+ }
+ }
+}
+
class RenamingASTConsumer : public ASTConsumer {
public:
RenamingASTConsumer(
@@ -52,29 +92,29 @@ public:
const std::string &PrevName,
const std::vector<std::string> &USRs) {
const SourceManager &SourceMgr = Context.getSourceManager();
- std::vector<SourceLocation> RenamingCandidates;
- std::vector<SourceLocation> NewCandidates;
- NewCandidates = tooling::getLocationsOfUSRs(
+ SymbolOccurrences Occurrences = tooling::getOccurrencesOfUSRs(
USRs, PrevName, Context.getTranslationUnitDecl());
- RenamingCandidates.insert(RenamingCandidates.end(), NewCandidates.begin(),
- NewCandidates.end());
-
- unsigned PrevNameLen = PrevName.length();
- for (const auto &Loc : RenamingCandidates) {
- if (PrintLocations) {
- FullSourceLoc FullLoc(Loc, SourceMgr);
- errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(Loc)
+ if (PrintLocations) {
+ for (const auto &Occurrence : Occurrences) {
+ FullSourceLoc FullLoc(Occurrence.getNameRanges()[0].getBegin(),
+ SourceMgr);
+ errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(FullLoc)
<< ":" << FullLoc.getSpellingLineNumber() << ":"
<< FullLoc.getSpellingColumnNumber() << "\n";
}
- // FIXME: better error handling.
- tooling::Replacement Replace(SourceMgr, Loc, PrevNameLen, NewName);
- llvm::Error Err = FileToReplaces[Replace.getFilePath()].add(Replace);
- if (Err)
- llvm::errs() << "Renaming failed in " << Replace.getFilePath() << "! "
- << llvm::toString(std::move(Err)) << "\n";
}
+ // FIXME: Support multi-piece names.
+ // FIXME: better error handling (propagate error out).
+ StringRef NewNameRef = NewName;
+ Expected<std::vector<AtomicChange>> Change =
+ createRenameReplacements(Occurrences, SourceMgr, NewNameRef);
+ if (!Change) {
+ llvm::errs() << "Failed to create renaming replacements for '" << PrevName
+ << "'! " << llvm::toString(Change.takeError()) << "\n";
+ return;
+ }
+ convertChangesToFileReplacements(*Change, &FileToReplaces);
}
private:
@@ -103,15 +143,7 @@ public:
// ready.
auto AtomicChanges = tooling::createRenameAtomicChanges(
USRList[I], NewNames[I], Context.getTranslationUnitDecl());
- for (const auto AtomicChange : AtomicChanges) {
- for (const auto &Replace : AtomicChange.getReplacements()) {
- llvm::Error Err = FileToReplaces[Replace.getFilePath()].add(Replace);
- if (Err) {
- llvm::errs() << "Renaming failed in " << Replace.getFilePath()
- << "! " << llvm::toString(std::move(Err)) << "\n";
- }
- }
- }
+ convertChangesToFileReplacements(AtomicChanges, &FileToReplaces);
}
}
OpenPOWER on IntegriCloud