diff --git a/platform/diff-impl/src/com/intellij/diff/comparison/ByLine.java b/platform/diff-impl/src/com/intellij/diff/comparison/ByLine.java index 1b93664453dd..ed57ad02c7b9 100644 --- a/platform/diff-impl/src/com/intellij/diff/comparison/ByLine.java +++ b/platform/diff-impl/src/com/intellij/diff/comparison/ByLine.java @@ -15,7 +15,7 @@ */ package com.intellij.diff.comparison; -import com.intellij.diff.comparison.iterables.DiffIterableUtil.TrimChangeBuilder; +import com.intellij.diff.comparison.iterables.DiffIterableUtil.*; import com.intellij.diff.comparison.iterables.FairDiffIterable; import com.intellij.diff.fragments.LineFragment; import com.intellij.diff.fragments.LineFragmentImpl; @@ -38,8 +38,7 @@ import java.util.List; import static com.intellij.diff.comparison.TrimUtil.trimEnd; import static com.intellij.diff.comparison.TrimUtil.trimStart; -import static com.intellij.diff.comparison.iterables.DiffIterableUtil.diff; -import static com.intellij.diff.comparison.iterables.DiffIterableUtil.fair; +import static com.intellij.diff.comparison.iterables.DiffIterableUtil.*; import static com.intellij.openapi.util.text.StringUtil.isWhiteSpace; public class ByLine { @@ -55,6 +54,7 @@ public class ByLine { FairDiffIterable changes = compareSmart(lines1, lines2, indicator); changes = optimizeLineChunks(lines1, lines2, changes, indicator); + changes = expandRanges(lines1, lines2, changes, indicator); return convertIntoFragments(lines1, lines2, changes); } @@ -141,7 +141,7 @@ public class ByLine { * c. match equal lines using result of the previous step */ - final TrimChangeBuilder builder = new TrimChangeBuilder(lines1, lines2); + final ExpandChangeBuilder builder = new ExpandChangeBuilder(lines1, lines2); new Object() { private CharSequence sample = null; private int last1 = -1; @@ -367,6 +367,21 @@ public class ByLine { return Pair.create(bigLines, indexes); } + @NotNull + private static FairDiffIterable expandRanges(@NotNull List lines1, + @NotNull List lines2, + @NotNull FairDiffIterable iterable, + @NotNull ProgressIndicator indicator) { + List changes = new ArrayList(); + + for (Range ch : iterable.iterateChanges()) { + Range expanded = TrimUtil.expand(lines1, lines2, ch.start1, ch.start2, ch.end1, ch.end2); + if (!expanded.isEmpty()) changes.add(expanded); + } + + return fair(create(changes, lines1.size(), lines2.size())); + } + // // Lines // diff --git a/platform/diff-impl/src/com/intellij/diff/comparison/iterables/DiffIterableUtil.java b/platform/diff-impl/src/com/intellij/diff/comparison/iterables/DiffIterableUtil.java index d97c1dc195de..d7b8f097a92d 100644 --- a/platform/diff-impl/src/com/intellij/diff/comparison/iterables/DiffIterableUtil.java +++ b/platform/diff-impl/src/com/intellij/diff/comparison/iterables/DiffIterableUtil.java @@ -336,11 +336,11 @@ public class DiffIterableUtil { } } - public static class TrimChangeBuilder extends ChangeBuilder { + public static class ExpandChangeBuilder extends ChangeBuilder { @NotNull private final List myObjects1; @NotNull private final List myObjects2; - public TrimChangeBuilder(@NotNull List objects1, @NotNull List objects2) { + public ExpandChangeBuilder(@NotNull List objects1, @NotNull List objects2) { super(objects1.size(), objects2.size()); myObjects1 = objects1; myObjects2 = objects2; diff --git a/platform/diff-impl/tests/com/intellij/diff/comparison/LineComparisonUtilTest.kt b/platform/diff-impl/tests/com/intellij/diff/comparison/LineComparisonUtilTest.kt index c9359c06816e..41cfa05b0dae 100644 --- a/platform/diff-impl/tests/com/intellij/diff/comparison/LineComparisonUtilTest.kt +++ b/platform/diff-impl/tests/com/intellij/diff/comparison/LineComparisonUtilTest.kt @@ -311,6 +311,14 @@ class LineComparisonUtilTest : ComparisonUtilTestBase() { } } + fun `test regression - can trim chunks after 'optimizeLineChunks'`() { + lines { + ("A=====_ B=====_ }_}_B=====_" - "A=====_ }_}_B=====_") + default(del(1, 1, 1)) + testAll() + } + } + fun `test bad cases caused by 'compareTwoStep' logic`() { lines { ("x_!" - "!_x_y") @@ -339,14 +347,6 @@ class LineComparisonUtilTest : ComparisonUtilTestBase() { } fun `test bad cases caused by 'compareSmart' logic`() { - lines { - ("A=====_ B=====_ }_}_B=====_" - "A=====_ }_}_B=====_") - // TODO: ignore(del(1, 1, 1)) - default(del(1, 1, 1)) - ignore(mod(1, 1, 3, 2)) - testAll() - } - lines { ("A=====_ B=====_ }_}_B=====" - "A=====_ }_}_B=====") // TODO trim(del(1, 1, 1))