diff options
author | Edwin Vane <edwin.vane@intel.com> | 2013-08-08 13:31:14 +0000 |
---|---|---|
committer | Edwin Vane <edwin.vane@intel.com> | 2013-08-08 13:31:14 +0000 |
commit | 938f68816a0e4e1a0559d6fd8b12de165b853131 (patch) | |
tree | 2c7b3be408c6e8d173ae9456b2f2db85d6bdde7b /clang/lib/Tooling | |
parent | 233455cba845004af5c59cc8a456a8199cf85521 (diff) | |
download | bcm5719-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.cpp | 44 |
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) {} |