diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2014-09-09 13:53:29 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2014-09-09 13:53:29 +0000 |
commit | efffbee024a8789a0528486d431e27f170b489a7 (patch) | |
tree | 118e5747774cb1ef8c312a34b4e24f7fe6cf0ad7 /clang/lib/Tooling/Refactoring.cpp | |
parent | 2664779b27e0c612a32ed85ae9b3e2e38dc3563a (diff) | |
download | llvm-efffbee024a8789a0528486d431e27f170b489a7.zip llvm-efffbee024a8789a0528486d431e27f170b489a7.tar.gz llvm-efffbee024a8789a0528486d431e27f170b489a7.tar.bz2 |
Tooling: Ignore file names in tooling::deduplicate.
This was horribly broken due to how the sort predicate works. We would
report a conflict for files with a replacement in the same position but
different names if the length differed. Just ignore paths as this is often
what the user wants. Files can occur with different names (due to symlinks
or relative paths) and we don't ever want to do the same edit in one file
twice.
llvm-svn: 217439
Diffstat (limited to 'clang/lib/Tooling/Refactoring.cpp')
-rw-r--r-- | clang/lib/Tooling/Refactoring.cpp | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/clang/lib/Tooling/Refactoring.cpp b/clang/lib/Tooling/Refactoring.cpp index b2a02cb..1dadaa7 100644 --- a/clang/lib/Tooling/Refactoring.cpp +++ b/clang/lib/Tooling/Refactoring.cpp @@ -238,11 +238,25 @@ void deduplicate(std::vector<Replacement> &Replaces, if (Replaces.empty()) return; - // Deduplicate - std::sort(Replaces.begin(), Replaces.end()); - std::vector<Replacement>::iterator End = - std::unique(Replaces.begin(), Replaces.end()); - Replaces.erase(End, Replaces.end()); + auto LessNoPath = [](const Replacement &LHS, const Replacement &RHS) { + if (LHS.getOffset() != RHS.getOffset()) + return LHS.getOffset() < RHS.getOffset(); + if (LHS.getLength() != RHS.getLength()) + return LHS.getLength() < RHS.getLength(); + return LHS.getReplacementText() < RHS.getReplacementText(); + }; + + auto EqualNoPath = [](const Replacement &LHS, const Replacement &RHS) { + return LHS.getOffset() == RHS.getOffset() && + LHS.getLength() == RHS.getLength() && + LHS.getReplacementText() == RHS.getReplacementText(); + }; + + // Deduplicate. We don't want to deduplicate based on the path as we assume + // that all replacements refer to the same file (or are symlinks). + std::sort(Replaces.begin(), Replaces.end(), LessNoPath); + Replaces.erase(std::unique(Replaces.begin(), Replaces.end(), EqualNoPath), + Replaces.end()); // Detect conflicts Range ConflictRange(Replaces.front().getOffset(), |