mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
diff: do not merge words while ignoring ranges
This commit is contained in:
committed by
Aleksey Pivovarov
parent
3514cf3cdf
commit
059d4d1d41
@@ -16,6 +16,7 @@
|
||||
package com.intellij.diff.comparison;
|
||||
|
||||
import com.intellij.diff.comparison.iterables.DiffIterable;
|
||||
import com.intellij.diff.comparison.iterables.DiffIterableUtil;
|
||||
import com.intellij.diff.comparison.iterables.FairDiffIterable;
|
||||
import com.intellij.diff.fragments.*;
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
@@ -38,6 +39,7 @@ import java.util.BitSet;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.diff.comparison.iterables.DiffIterableUtil.fair;
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
public class ComparisonManagerImpl extends ComparisonManager {
|
||||
@@ -461,9 +463,11 @@ public class ComparisonManagerImpl extends ComparisonManager {
|
||||
|
||||
List<CharSequence> lineTexts1 = ContainerUtil.map(lines1, line -> line.getNotIgnoredContent(ignored1));
|
||||
List<CharSequence> lineTexts2 = ContainerUtil.map(lines2, line -> line.getNotIgnoredContent(ignored2));
|
||||
|
||||
FairDiffIterable iterable = ByLine.compare(lineTexts1, lineTexts2, ComparisonPolicy.DEFAULT, indicator);
|
||||
List<LineFragment> lineFragments = convertIntoLineFragments(lines1, lines2, iterable);
|
||||
|
||||
FairDiffIterable correctedIterable = correctIgnoredRangesSecondStep(iterable, lines1, lines2, ignored1, ignored2);
|
||||
|
||||
List<LineFragment> lineFragments = convertIntoLineFragments(lines1, lines2, correctedIterable);
|
||||
|
||||
if (innerFragments) {
|
||||
lineFragments = createInnerFragments(lineFragments, text1, text2, ComparisonPolicy.DEFAULT, indicator);
|
||||
@@ -483,6 +487,26 @@ public class ComparisonManagerImpl extends ComparisonManager {
|
||||
return set;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static FairDiffIterable correctIgnoredRangesSecondStep(@NotNull FairDiffIterable iterable,
|
||||
@NotNull List<Line> lines1,
|
||||
@NotNull List<Line> lines2,
|
||||
@NotNull BitSet ignored1,
|
||||
@NotNull BitSet ignored2) {
|
||||
DiffIterableUtil.ChangeBuilder builder = new DiffIterableUtil.ChangeBuilder(lines1.size(), lines2.size());
|
||||
for (Range range : iterable.iterateUnchanged()) {
|
||||
int count = range.end1 - range.start1;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int index1 = range.start1 + i;
|
||||
int index2 = range.start2 + i;
|
||||
if (areIgnoredEqualLines(lines1.get(index1), lines2.get(index2), ignored1, ignored2)) {
|
||||
builder.markEqual(index1, index2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return fair(builder.finish());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static LineFragment trimIgnoredChanges(@NotNull LineFragment fragment,
|
||||
@NotNull List<Line> lines1,
|
||||
@@ -542,7 +566,7 @@ public class ComparisonManagerImpl extends ComparisonManager {
|
||||
}
|
||||
|
||||
private static boolean isIgnoredLine(@NotNull Line line, @NotNull BitSet ignored) {
|
||||
return trimIgnoredRange(line.getOffset1(), line.getOffset2(), ignored, 0).isEmpty();
|
||||
return isIgnoredRange(ignored, line.getOffset1(), line.getOffset2());
|
||||
}
|
||||
|
||||
private static boolean areIgnoredEqualLines(@NotNull Line line1, @NotNull Line line2,
|
||||
@@ -551,13 +575,36 @@ public class ComparisonManagerImpl extends ComparisonManager {
|
||||
int end1 = line1.getOffset2();
|
||||
int start2 = line2.getOffset1();
|
||||
int end2 = line2.getOffset2();
|
||||
|
||||
Range range = TrimUtil.trimExpandText(line1.getOriginalText(), line2.getOriginalText(),
|
||||
start1, start2, end1, end2,
|
||||
ignored1, ignored2);
|
||||
return range.isEmpty();
|
||||
if (!range.isEmpty()) return false;
|
||||
|
||||
List<ByWord.InlineChunk> words1 = getNonIgnoredWords(line1, ignored1);
|
||||
List<ByWord.InlineChunk> words2 = getNonIgnoredWords(line2, ignored2);
|
||||
if (words1.size() != words2.size()) return false;
|
||||
|
||||
for (int i = 0; i < words1.size(); i++) {
|
||||
CharSequence word1 = getWordContent(line1, words1.get(i));
|
||||
CharSequence word2 = getWordContent(line2, words2.get(i));
|
||||
if (!StringUtil.equals(word1, word2)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<ByWord.InlineChunk> getNonIgnoredWords(@NotNull Line line, @NotNull BitSet ignored) {
|
||||
int offset = line.getOffset1();
|
||||
List<ByWord.InlineChunk> innerChunks = ByWord.getInlineChunks(line.getContent());
|
||||
return ContainerUtil.filter(innerChunks, it -> it instanceof ByWord.WordChunk &&
|
||||
!isIgnoredRange(ignored, offset + it.getOffset1(), offset + it.getOffset2()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static CharSequence getWordContent(@NotNull Line line, @NotNull ByWord.InlineChunk word) {
|
||||
return line.getContent().subSequence(word.getOffset1(), word.getOffset2());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static TextRange trimIgnoredRange(int start, int end, @NotNull BitSet ignored, int offset) {
|
||||
@@ -565,6 +612,9 @@ public class ComparisonManagerImpl extends ComparisonManager {
|
||||
return new TextRange(intPair.val1 - offset, intPair.val2 - offset);
|
||||
}
|
||||
|
||||
private static boolean isIgnoredRange(@NotNull BitSet ignored, int start, int end) {
|
||||
return ignored.nextClearBit(start) >= end;
|
||||
}
|
||||
|
||||
private static class Line {
|
||||
@NotNull private final CharSequence myChars;
|
||||
|
||||
@@ -309,8 +309,8 @@ class IgnoreComparisonUtilTest : DiffTestCase() {
|
||||
|
||||
Test("X Y", "XY",
|
||||
" + ", " ",
|
||||
" ", " ")
|
||||
.changedLinesNumber(0, 0)
|
||||
"---", "--")
|
||||
.changedLinesNumber(1, 1)
|
||||
.run()
|
||||
}
|
||||
|
||||
@@ -337,17 +337,17 @@ class IgnoreComparisonUtilTest : DiffTestCase() {
|
||||
" - ", " - ")
|
||||
.changedLinesNumber(2, 1)
|
||||
.run()
|
||||
|
||||
Test("int X = 0;", "intX = 0;",
|
||||
" + + + ", " + + ",
|
||||
"----- ", "---- ")
|
||||
.changedLinesNumber(1, 1)
|
||||
.run()
|
||||
}
|
||||
|
||||
fun `test Java bad samples`() {
|
||||
//TODO
|
||||
|
||||
Test("int X = 0;", "intX = 0;",
|
||||
" + + + ", " + + ",
|
||||
" ", " ")
|
||||
.changedLinesNumber(0, 0)
|
||||
.run()
|
||||
|
||||
Test("System.out.println (\"Hello world\");", "System.out.println(\"Hello world\");",
|
||||
" . + . ", " . . ",
|
||||
" - . - . ", " . . ")
|
||||
|
||||
Reference in New Issue
Block a user