Tooling: When applying a set of replacements, do deletions before

insertions. It is unlikely to be the intention to delete parts of newly
inserted code. To do so, changed sorting Replacements at the same offset
to have decreasing length.

llvm-svn: 239809
This commit is contained in:
Daniel Jasper 2015-06-16 10:22:10 +00:00
parent c535d93b47
commit 0f29127636
2 changed files with 19 additions and 1 deletions

View File

@ -88,8 +88,13 @@ std::string Replacement::toString() const {
bool operator<(const Replacement &LHS, const Replacement &RHS) {
if (LHS.getOffset() != RHS.getOffset())
return LHS.getOffset() < RHS.getOffset();
// Apply longer replacements first, specifically so that deletions are
// executed before insertions. It is (hopefully) never the intention to
// delete parts of newly inserted code.
if (LHS.getLength() != RHS.getLength())
return LHS.getLength() < RHS.getLength();
return LHS.getLength() > RHS.getLength();
if (LHS.getFilePath() != RHS.getFilePath())
return LHS.getFilePath() < RHS.getFilePath();
return LHS.getReplacementText() < RHS.getReplacementText();

View File

@ -8,9 +8,12 @@
//===----------------------------------------------------------------------===//
#include "RewriterTestContext.h"
#include "clang/Tooling/Core/Replacement.h"
#include "gtest/gtest.h"
namespace clang {
namespace tooling {
namespace {
TEST(Rewriter, OverwritesChangedFiles) {
RewriterTestContext Context;
@ -34,4 +37,14 @@ TEST(Rewriter, ContinuesOverwritingFilesOnError) {
Context.getFileContentFromDisk("working.cpp"));
}
TEST(Rewriter, AdjacentInsertAndDelete) {
Replacements Replaces;
Replaces.emplace("<file>", 6, 6, "");
Replaces.emplace("<file>", 6, 0, "replaced\n");
EXPECT_EQ("line1\nreplaced\nline3\nline4",
applyAllReplacements("line1\nline2\nline3\nline4", Replaces));
}
} // end namespace
} // end namespace tooling
} // end namespace clang