summaryrefslogtreecommitdiffstats
path: root/clang/lib/Tooling
diff options
context:
space:
mode:
authorEdwin Vane <edwin.vane@intel.com>2013-08-08 13:31:14 +0000
committerEdwin Vane <edwin.vane@intel.com>2013-08-08 13:31:14 +0000
commit938f68816a0e4e1a0559d6fd8b12de165b853131 (patch)
tree2c7b3be408c6e8d173ae9456b2f2db85d6bdde7b /clang/lib/Tooling
parent233455cba845004af5c59cc8a456a8199cf85521 (diff)
downloadbcm5719-llvm-938f68816a0e4e1a0559d6fd8b12de165b853131.tar.gz
bcm5719-llvm-938f68816a0e4e1a0559d6fd8b12de165b853131.zip
Introduce Replacement deduplication and conflict detection function
Summary: This patch adds tooling::deduplicate() which removes duplicates from and looks for conflicts in a vector of Replacements. Differential Revision: http://llvm-reviews.chandlerc.com/D1314 llvm-svn: 187979
Diffstat (limited to 'clang/lib/Tooling')
-rw-r--r--clang/lib/Tooling/Refactoring.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/clang/lib/Tooling/Refactoring.cpp b/clang/lib/Tooling/Refactoring.cpp
index a61bf9aa34c..8599f975120 100644
--- a/clang/lib/Tooling/Refactoring.cpp
+++ b/clang/lib/Tooling/Refactoring.cpp
@@ -90,6 +90,12 @@ bool Replacement::Less::operator()(const Replacement &R1,
return R1.ReplacementText < R2.ReplacementText;
}
+bool Replacement::operator==(const Replacement &Other) const {
+ return ReplacementRange.getOffset() == Other.ReplacementRange.getOffset() &&
+ ReplacementRange.getLength() == Other.ReplacementRange.getLength() &&
+ FilePath == Other.FilePath && ReplacementText == Other.ReplacementText;
+}
+
void Replacement::setFromSourceLocation(SourceManager &Sources,
SourceLocation Start, unsigned Length,
StringRef ReplacementText) {
@@ -179,6 +185,44 @@ unsigned shiftedCodePosition(const Replacements &Replaces, unsigned Position) {
return NewPosition;
}
+void deduplicate(std::vector<Replacement> &Replaces,
+ std::vector<Range> &Conflicts) {
+ if (Replaces.empty())
+ return;
+
+ // Deduplicate
+ std::sort(Replaces.begin(), Replaces.end(), Replacement::Less());
+ std::vector<Replacement>::iterator End =
+ std::unique(Replaces.begin(), Replaces.end());
+ Replaces.erase(End, Replaces.end());
+
+ // Detect conflicts
+ Range ConflictRange(Replaces.front().getOffset(),
+ Replaces.front().getLength());
+ unsigned ConflictStart = 0;
+ unsigned ConflictLength = 1;
+ for (unsigned i = 1; i < Replaces.size(); ++i) {
+ Range Current(Replaces[i].getOffset(), Replaces[i].getLength());
+ if (ConflictRange.overlapsWith(Current)) {
+ // Extend conflicted range
+ ConflictRange = Range(ConflictRange.getOffset(),
+ Current.getOffset() + Current.getLength() -
+ ConflictRange.getOffset());
+ ++ConflictLength;
+ } else {
+ if (ConflictLength > 1)
+ Conflicts.push_back(Range(ConflictStart, ConflictLength));
+ ConflictRange = Current;
+ ConflictStart = i;
+ ConflictLength = 1;
+ }
+ }
+
+ if (ConflictLength > 1)
+ Conflicts.push_back(Range(ConflictStart, ConflictLength));
+}
+
+
RefactoringTool::RefactoringTool(const CompilationDatabase &Compilations,
ArrayRef<std::string> SourcePaths)
: ClangTool(Compilations, SourcePaths) {}
OpenPOWER on IntegriCloud