diff options
author | Eric Liu <ioeric@google.com> | 2016-09-28 11:02:16 +0000 |
---|---|---|
committer | Eric Liu <ioeric@google.com> | 2016-09-28 11:02:16 +0000 |
commit | 6ef82b6754e6198e0f22b1badaf9b8da9f81e5d0 (patch) | |
tree | 47329162b22b63b4c4c4ef5462cb9326a245a348 /clang/unittests/Tooling/RefactoringTest.cpp | |
parent | 2234e0da4c33cd77f82fd4b7c99a54f711e3057c (diff) | |
download | llvm-6ef82b6754e6198e0f22b1badaf9b8da9f81e5d0.zip llvm-6ef82b6754e6198e0f22b1badaf9b8da9f81e5d0.tar.gz llvm-6ef82b6754e6198e0f22b1badaf9b8da9f81e5d0.tar.bz2 |
Merge conflicting replacements when they are order-independent.
Summary:
Now two replacements are considered order-independent if applying them in
either order produces the same result. These include (but not restricted
to) replacements that:
- don't overlap (being directly adjacent is fine) and
- are overlapping deletions.
- are insertions at the same offset and applying them in either order
has the same effect, i.e. X + Y = Y + X if one inserts text X and the
other inserts text Y.
Discussion about this design can be found in D24717
Reviewers: djasper, klimek
Subscribers: omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24800
llvm-svn: 282577
Diffstat (limited to 'clang/unittests/Tooling/RefactoringTest.cpp')
-rw-r--r-- | clang/unittests/Tooling/RefactoringTest.cpp | 192 |
1 files changed, 180 insertions, 12 deletions
diff --git a/clang/unittests/Tooling/RefactoringTest.cpp b/clang/unittests/Tooling/RefactoringTest.cpp index b4c269d..0a70a11 100644 --- a/clang/unittests/Tooling/RefactoringTest.cpp +++ b/clang/unittests/Tooling/RefactoringTest.cpp @@ -101,18 +101,56 @@ TEST_F(ReplacementTest, ReturnsInvalidPath) { TEST_F(ReplacementTest, FailAddReplacements) { Replacements Replaces; - auto Err = Replaces.add(Replacement("x.cc", 0, 10, "3")); + Replacement Deletion("x.cc", 0, 10, "3"); + auto Err = Replaces.add(Deletion); EXPECT_TRUE(!Err); llvm::consumeError(std::move(Err)); - Err = Replaces.add(Replacement("x.cc", 0, 2, "")); + Err = Replaces.add(Replacement("x.cc", 0, 2, "a")); EXPECT_TRUE((bool)Err); llvm::consumeError(std::move(Err)); - Err = Replaces.add(Replacement("x.cc", 2, 2, "")); + Err = Replaces.add(Replacement("x.cc", 2, 2, "a")); EXPECT_TRUE((bool)Err); llvm::consumeError(std::move(Err)); Err = Replaces.add(Replacement("y.cc", 20, 2, "")); EXPECT_TRUE((bool)Err); llvm::consumeError(std::move(Err)); + EXPECT_EQ(1u, Replaces.size()); + EXPECT_EQ(Deletion, *Replaces.begin()); +} + +TEST_F(ReplacementTest, DeletionInReplacements) { + Replacements Replaces; + Replacement R("x.cc", 0, 10, "3"); + auto Err = Replaces.add(R); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + Err = Replaces.add(Replacement("x.cc", 0, 2, "")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + Err = Replaces.add(Replacement("x.cc", 2, 2, "")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + EXPECT_EQ(1u, Replaces.size()); + EXPECT_EQ(R, *Replaces.begin()); +} + +TEST_F(ReplacementTest, OverlappingReplacements) { + Replacements Replaces; + auto Err = Replaces.add(Replacement("x.cc", 0, 3, "345")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + Err = Replaces.add(Replacement("x.cc", 2, 3, "543")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + EXPECT_EQ(1u, Replaces.size()); + EXPECT_EQ(Replacement("x.cc", 0, 5, "34543"), *Replaces.begin()); + + Err = Replaces.add(Replacement("x.cc", 2, 1, "5")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + EXPECT_EQ(1u, Replaces.size()); + EXPECT_EQ(Replacement("x.cc", 0, 5, "34543"), *Replaces.begin()); } TEST_F(ReplacementTest, AddAdjacentInsertionAndReplacement) { @@ -137,6 +175,116 @@ TEST_F(ReplacementTest, AddAdjacentInsertionAndReplacement) { EXPECT_EQ(Replaces.size(), 2u); } +TEST_F(ReplacementTest, MergeNewDeletions) { + Replacements Replaces; + Replacement ContainingReplacement("x.cc", 0, 10, ""); + auto Err = Replaces.add(ContainingReplacement); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + Err = Replaces.add(Replacement("x.cc", 5, 3, "")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + Err = Replaces.add(Replacement("x.cc", 0, 10, "")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + Err = Replaces.add(Replacement("x.cc", 5, 5, "")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + EXPECT_EQ(1u, Replaces.size()); + EXPECT_EQ(*Replaces.begin(), ContainingReplacement); +} + +TEST_F(ReplacementTest, MergeOverlappingButNotAdjacentReplacement) { + Replacements Replaces; + auto Err = Replaces.add(Replacement("x.cc", 0, 2, "")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + Err = Replaces.add(Replacement("x.cc", 5, 5, "")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + Replacement After = Replacement("x.cc", 10, 5, ""); + Err = Replaces.add(After); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + Replacement ContainingReplacement("x.cc", 0, 10, ""); + Err = Replaces.add(ContainingReplacement); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + EXPECT_EQ(2u, Replaces.size()); + EXPECT_EQ(*Replaces.begin(), ContainingReplacement); + EXPECT_EQ(*(++Replaces.begin()), After); +} + +TEST_F(ReplacementTest, InsertionBeforeMergedDeletions) { + Replacements Replaces; + + Replacement Insertion("x.cc", 0, 0, "123"); + auto Err = Replaces.add(Insertion); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + Err = Replaces.add(Replacement("x.cc", 5, 5, "")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + Replacement Deletion("x.cc", 0, 10, ""); + Err = Replaces.add(Deletion); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + EXPECT_EQ(2u, Replaces.size()); + EXPECT_EQ(*Replaces.begin(), Insertion); + EXPECT_EQ(*(++Replaces.begin()), Deletion); +} + +TEST_F(ReplacementTest, MergeOverlappingDeletions) { + Replacements Replaces; + auto Err = Replaces.add(Replacement("x.cc", 0, 2, "")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + Err = Replaces.add(Replacement("x.cc", 0, 5, "")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + EXPECT_EQ(1u, Replaces.size()); + EXPECT_EQ(Replacement("x.cc", 0, 5, ""), *Replaces.begin()); + + Err = Replaces.add(Replacement("x.cc", 1, 5, "")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + EXPECT_EQ(1u, Replaces.size()); + EXPECT_EQ(Replacement("x.cc", 0, 6, ""), *Replaces.begin()); +} + +TEST_F(ReplacementTest, FailedMergeExistingDeletions) { + Replacements Replaces; + Replacement First("x.cc", 0, 2, ""); + auto Err = Replaces.add(First); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + Replacement Second("x.cc", 5, 5, ""); + Err = Replaces.add(Second); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + Err = Replaces.add(Replacement("x.cc", 1, 10, "")); + EXPECT_TRUE(!Err); + llvm::consumeError(std::move(Err)); + + EXPECT_EQ(1u, Replaces.size()); + EXPECT_EQ(Replacement("x.cc", 0, 11, ""), *Replaces.begin()); +} + TEST_F(ReplacementTest, FailAddRegression) { Replacements Replaces; // Create two replacements, where the second one is an insertion of the empty @@ -155,7 +303,7 @@ TEST_F(ReplacementTest, FailAddRegression) { llvm::consumeError(std::move(Err)); Err = Replaces.add(Replacement("x.cc", 10, 0, "")); - EXPECT_TRUE((bool)Err); + EXPECT_TRUE(!Err); llvm::consumeError(std::move(Err)); } @@ -179,7 +327,7 @@ TEST_F(ReplacementTest, InsertAtOffsetOfReplacement) { EXPECT_EQ(Replaces.size(), 2u); } -TEST_F(ReplacementTest, FailAddInsertAtOtherInsert) { +TEST_F(ReplacementTest, AddInsertAtOtherInsertWhenOderIndependent) { Replacements Replaces; auto Err = Replaces.add(Replacement("x.cc", 10, 0, "a")); EXPECT_TRUE(!Err); @@ -189,12 +337,14 @@ TEST_F(ReplacementTest, FailAddInsertAtOtherInsert) { llvm::consumeError(std::move(Err)); Replaces.clear(); - Err = Replaces.add(Replacement("x.cc", 10, 0, "")); + Err = Replaces.add(Replacement("x.cc", 10, 0, "a")); EXPECT_TRUE(!Err); llvm::consumeError(std::move(Err)); - Err = Replaces.add(Replacement("x.cc", 10, 0, "")); - EXPECT_TRUE((bool)Err); + Err = Replaces.add(Replacement("x.cc", 10, 0, "aa")); + EXPECT_TRUE(!Err); llvm::consumeError(std::move(Err)); + EXPECT_EQ(1u, Replaces.size()); + EXPECT_EQ(Replacement("x.cc", 10, 0, "aaa"), *Replaces.begin()); Replaces.clear(); Err = Replaces.add(Replacement("x.cc", 10, 0, "")); @@ -204,8 +354,11 @@ TEST_F(ReplacementTest, FailAddInsertAtOtherInsert) { EXPECT_TRUE(!Err); llvm::consumeError(std::move(Err)); Err = Replaces.add(Replacement("x.cc", 10, 0, "")); - EXPECT_TRUE((bool)Err); + EXPECT_TRUE(!Err); llvm::consumeError(std::move(Err)); + EXPECT_EQ(2u, Replaces.size()); + EXPECT_EQ(Replacement("x.cc", 10, 0, ""), *Replaces.begin()); + EXPECT_EQ(Replacement("x.cc", 10, 3, ""), *std::next(Replaces.begin())); } TEST_F(ReplacementTest, InsertBetweenAdjacentReplacements) { @@ -256,7 +409,7 @@ TEST_F(ReplacementTest, AdjacentReplacements) { EXPECT_EQ("xy", Context.getRewrittenText(ID)); } -TEST_F(ReplacementTest, SkipsDuplicateReplacements) { +TEST_F(ReplacementTest, AddDuplicateReplacements) { FileID ID = Context.createInMemoryFile("input.cpp", "line1\nline2\nline3\nline4"); auto Replaces = toReplacements({Replacement( @@ -264,18 +417,33 @@ TEST_F(ReplacementTest, SkipsDuplicateReplacements) { auto Err = Replaces.add(Replacement( Context.Sources, Context.getLocation(ID, 2, 1), 5, "replaced")); - EXPECT_TRUE((bool)Err); + EXPECT_TRUE(!Err); llvm::consumeError(std::move(Err)); Err = Replaces.add(Replacement(Context.Sources, Context.getLocation(ID, 2, 1), 5, "replaced")); - EXPECT_TRUE((bool)Err); + EXPECT_TRUE(!Err); llvm::consumeError(std::move(Err)); EXPECT_TRUE(applyAllReplacements(Replaces, Context.Rewrite)); EXPECT_EQ("line1\nreplaced\nline3\nline4", Context.getRewrittenText(ID)); } +TEST_F(ReplacementTest, FailOrderDependentReplacements) { + FileID ID = Context.createInMemoryFile("input.cpp", + "line1\nline2\nline3\nline4"); + auto Replaces = toReplacements({Replacement( + Context.Sources, Context.getLocation(ID, 2, 1), 5, "other")}); + + auto Err = Replaces.add(Replacement( + Context.Sources, Context.getLocation(ID, 2, 1), 5, "rehto")); + EXPECT_TRUE((bool)Err); + llvm::consumeError(std::move(Err)); + + EXPECT_TRUE(applyAllReplacements(Replaces, Context.Rewrite)); + EXPECT_EQ("line1\nother\nline3\nline4", Context.getRewrittenText(ID)); +} + TEST_F(ReplacementTest, InvalidSourceLocationFailsApplyAll) { Replacements Replaces = toReplacements({Replacement(Context.Sources, SourceLocation(), 5, "2")}); |