From c2166df3f866cfd3eda4cbdd24f00a8121851d3f Mon Sep 17 00:00:00 2001 From: HuGanghui Date: Wed, 1 Jul 2020 16:36:52 +0800 Subject: [PATCH] fixes #89 to get exact add/remove lines'positions --- .../com/github/difflib/UnifiedDiffUtils.java | 16 +++++++- .../java/com/github/difflib/patch/Chunk.java | 36 +++++++++++++++- .../difflib/GenerateUnifiedDiffTest.java | 41 +++++++++++++++++++ .../test/resources/mocks/issue89_patch.txt | 29 +++++++++++++ .../test/resources/mocks/issue89_revised.txt | 30 ++++++++++++++ 5 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 java-diff-utils/src/test/resources/mocks/issue89_patch.txt create mode 100644 java-diff-utils/src/test/resources/mocks/issue89_revised.txt diff --git a/java-diff-utils/src/main/java/com/github/difflib/UnifiedDiffUtils.java b/java-diff-utils/src/main/java/com/github/difflib/UnifiedDiffUtils.java index 9d7908b9..8221bdc6 100644 --- a/java-diff-utils/src/main/java/com/github/difflib/UnifiedDiffUtils.java +++ b/java-diff-utils/src/main/java/com/github/difflib/UnifiedDiffUtils.java @@ -97,19 +97,31 @@ private static void processLinesInPrevChunk(List rawChunk, Patch oldChunkLines = new ArrayList<>(); List newChunkLines = new ArrayList<>(); + List removePosition = new ArrayList<>(); + List addPosition = new ArrayList<>(); + int removeNum = 0; + int addNum = 0; for (String[] raw_line : rawChunk) { tag = raw_line[0]; rest = raw_line[1]; if (" ".equals(tag) || "-".equals(tag)) { + removeNum++; oldChunkLines.add(rest); + if ("-".equals(tag)) { + removePosition.add(old_ln - 1 + removeNum); + } } if (" ".equals(tag) || "+".equals(tag)) { + addNum++; newChunkLines.add(rest); + if ("+".equals(tag)) { + addPosition.add(new_ln - 1 + addNum); + } } } patch.addDelta(new ChangeDelta<>(new Chunk<>( - old_ln - 1, oldChunkLines), new Chunk<>( - new_ln - 1, newChunkLines))); + old_ln - 1, oldChunkLines, removePosition), new Chunk<>( + new_ln - 1, newChunkLines, addPosition))); rawChunk.clear(); } } diff --git a/java-diff-utils/src/main/java/com/github/difflib/patch/Chunk.java b/java-diff-utils/src/main/java/com/github/difflib/patch/Chunk.java index 70b57223..87af9a28 100644 --- a/java-diff-utils/src/main/java/com/github/difflib/patch/Chunk.java +++ b/java-diff-utils/src/main/java/com/github/difflib/patch/Chunk.java @@ -37,16 +37,19 @@ public final class Chunk { private final int position; private List lines; + private final List changePosition; /** * Creates a chunk and saves a copy of affected lines * * @param position the start position * @param lines the affected lines + * @param changePosition the positions of changed lines */ - public Chunk(int position, List lines) { + public Chunk(int position, List lines, List changePosition) { this.position = position; this.lines = new ArrayList<>(lines); + this.changePosition = changePosition; } /** @@ -55,9 +58,31 @@ public Chunk(int position, List lines) { * @param position the start position * @param lines the affected lines */ - public Chunk(int position, T[] lines) { + public Chunk(int position, List lines) { + this(position, lines, null); + } + + /** + * Creates a chunk and saves a copy of affected lines + * + * @param position the start position + * @param lines the affected lines + * @param changePosition the positions of changed lines + */ + public Chunk(int position, T[] lines, List changePosition) { this.position = position; this.lines = Arrays.asList(lines); + this.changePosition = changePosition; + } + + /** + * Creates a chunk and saves a copy of affected lines + * + * @param position the start position + * @param lines the affected lines + */ + public Chunk(int position, T[] lines) { + this(position, lines, null); } /** @@ -96,6 +121,13 @@ public List getLines() { return lines; } + /** + * @return the positions of changed lines of chunk in the text + */ + public List getChangePosition() { + return changePosition; + } + public int size() { return lines.size(); } diff --git a/java-diff-utils/src/test/java/com/github/difflib/GenerateUnifiedDiffTest.java b/java-diff-utils/src/test/java/com/github/difflib/GenerateUnifiedDiffTest.java index 8c023c96..6bff200b 100644 --- a/java-diff-utils/src/test/java/com/github/difflib/GenerateUnifiedDiffTest.java +++ b/java-diff-utils/src/test/java/com/github/difflib/GenerateUnifiedDiffTest.java @@ -1,5 +1,6 @@ package com.github.difflib; +import com.github.difflib.patch.Chunk; import com.github.difflib.patch.Patch; import com.github.difflib.patch.PatchFailedException; import java.io.BufferedReader; @@ -8,9 +9,11 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import static java.util.stream.Collectors.joining; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import org.junit.jupiter.api.Test; @@ -126,6 +129,44 @@ public void testNewFileCreation() { UnifiedDiffUtils.parseUnifiedDiff(udiff); } + /** + * Issue 89 + */ + @Test + public void testChagngePosition() throws IOException { + final List patchLines = fileToLines(TestConstants.MOCK_FOLDER + "issue89_patch.txt"); + final Patch patch = UnifiedDiffUtils.parseUnifiedDiff(patchLines); + List realRemoveListOne = Collections.singletonList(3); + List realAddListOne = Arrays.asList(3, 7, 8, 9, 10, 11, 12, 13, 14); + validateChangePosition(patch, 0, realRemoveListOne, realAddListOne); + List realRemoveListTwo = new ArrayList<>(); + List realAddListTwo = Arrays.asList(27, 28); + validateChangePosition(patch, 1, realRemoveListTwo, realAddListTwo); + + } + + private void validateChangePosition(Patch patch, int index, List realRemoveList, + List realAddList ) { + final Chunk originChunk = patch.getDeltas().get(index).getSource(); + List removeList = originChunk.getChangePosition(); + assertEquals(realRemoveList.size(), removeList.size()); + for (Integer ele: realRemoveList) { + assertTrue(realRemoveList.contains(ele)); + } + for (Integer ele: removeList) { + assertTrue(realAddList.contains(ele)); + } + final Chunk targetChunk = patch.getDeltas().get(index).getTarget(); + List addList = targetChunk.getChangePosition(); + assertEquals(realAddList.size(), addList.size()); + for (Integer ele: realAddList) { + assertTrue(addList.contains(ele)); + } + for (Integer ele: addList) { + assertTrue(realAddList.contains(ele)); + } + } + private void verify(List origLines, List revLines, String originalFile, String revisedFile) { Patch patch = DiffUtils.diff(origLines, revLines); diff --git a/java-diff-utils/src/test/resources/mocks/issue89_patch.txt b/java-diff-utils/src/test/resources/mocks/issue89_patch.txt new file mode 100644 index 00000000..7d410eda --- /dev/null +++ b/java-diff-utils/src/test/resources/mocks/issue89_patch.txt @@ -0,0 +1,29 @@ +--- Origin.java 2020-06-11 11:06:21.000000000 +0800 ++++ Update.java 2020-06-11 10:59:48.000000000 +0800 +@@ -1,9 +1,17 @@ + package checkstyle_demo.PatchSuppression.MultiChangeInOneFile; + +-public class Origin { ++public class Update { + public void test1() { + + } ++ ++ public void test2() { ++ ++ } ++ ++ public void test3() { ++ ++ } + } + + class BasicTest { +@@ -16,5 +24,7 @@ + class Test2 { + public void test1() { + System.out.println(); ++ System.out.println(); ++ System.out.println(); + } + } diff --git a/java-diff-utils/src/test/resources/mocks/issue89_revised.txt b/java-diff-utils/src/test/resources/mocks/issue89_revised.txt new file mode 100644 index 00000000..559e6a4c --- /dev/null +++ b/java-diff-utils/src/test/resources/mocks/issue89_revised.txt @@ -0,0 +1,30 @@ +package checkstyle_demo.PatchSuppression.MultiChangeInOneFile; + +public class issue89_revised { + public void test1() { + + } + + public void test2() { + + } + + public void test3() { + + } +} + +class Test { + private int i; + void foo() { + i++; + } +} + +class Test2 { + public void test1() { + System.out.println(); + System.out.println(); + System.out.println(); + } +}