From 21b1c57e51997201b8215849a5a9305415683bcc Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 6 Mar 2017 16:43:48 +0300 Subject: [PATCH] merge: simplify - move non-conflict resolution logic into one method --- .../intellij/diff/merge/TextMergeChange.java | 14 +-- .../intellij/diff/merge/TextMergeViewer.java | 113 ++++++++---------- .../com/intellij/diff/merge/MergeAutoTest.kt | 2 +- .../com/intellij/diff/merge/MergeTestBase.kt | 6 +- 4 files changed, 59 insertions(+), 76 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeChange.java b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeChange.java index f6475e0031cd..195bc006b4c0 100644 --- a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeChange.java +++ b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeChange.java @@ -324,20 +324,20 @@ public class TextMergeChange extends ThreesideDiffChangeBase { @Nullable private GutterIconRenderer createResolveRenderer() { - if (!myViewer.canResolveConflictedChange(this)) return null; + if (!this.isConflict() || !myViewer.canApplyNonConflictedChange(this, ThreeSide.BASE)) return null; return createIconRenderer(DiffBundle.message("merge.dialog.resolve.change.action.name"), AllIcons.Diff.MagicResolve, false, () -> { myViewer.executeMergeCommand("Resolve conflict", Collections.singletonList(this), () -> { - myViewer.resolveConflictedChange(this); + myViewer.applyNonConflictedChange(this, ThreeSide.BASE); }); }); } - @Nullable - private GutterIconRenderer createIconRenderer(@NotNull final String text, - @NotNull final Icon icon, - boolean ctrlClickVisible, - @NotNull final Runnable perform) { + @NotNull + private static GutterIconRenderer createIconRenderer(@NotNull final String text, + @NotNull final Icon icon, + boolean ctrlClickVisible, + @NotNull final Runnable perform) { final String tooltipText = DiffUtil.createTooltipText(text, ctrlClickVisible ? CTRL_CLICK_TO_RESOLVE : null); return new DiffGutterRenderer(icon, tooltipText) { @Override diff --git a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeViewer.java b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeViewer.java index 0cf4d7257e42..a6ebdc48cc8a 100644 --- a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeViewer.java @@ -781,47 +781,6 @@ public class TextMergeViewer implements MergeTool.MergeViewer { } } - private boolean isChangeRangeModified(@NotNull TextMergeChange change) { - MergeLineFragment changeFragment = change.getFragment(); - int baseStartLine = changeFragment.getStartLine(ThreeSide.BASE); - int baseEndLine = changeFragment.getEndLine(ThreeSide.BASE); - DiffContent baseDiffContent = ThreeSide.BASE.select(myMergeRequest.getContents()); - Document baseDocument = ((DocumentContent)baseDiffContent).getDocument(); - - int resultStartLine = change.getStartLine(); - int resultEndLine = change.getEndLine(); - Document resultDocument = getEditor().getDocument(); - - CharSequence baseContent = DiffUtil.getLinesContent(baseDocument, baseStartLine, baseEndLine); - CharSequence resultContent = DiffUtil.getLinesContent(resultDocument, resultStartLine, resultEndLine); - return !StringUtil.equals(baseContent, resultContent); - } - - public boolean canResolveConflictedChange(@NotNull TextMergeChange change) { - return change.isConflict() && - change.getType().canBeResolved() && - !change.isResolved(Side.LEFT) && !change.isResolved(Side.RIGHT) && - !isChangeRangeModified(change); - } - - public void resolveConflictedChange(@NotNull TextMergeChange change) { - if (!canResolveConflictedChange(change)) return; - - List texts = ThreeSide.map(side -> { - return DiffUtil.getLinesContent(getEditor(side).getDocument(), change.getStartLine(side), change.getEndLine(side)); - }); - - CharSequence newContent = ComparisonMergeUtil.tryResolveConflict(texts.get(0), texts.get(1), texts.get(2)); - if (newContent == null) { - LOG.warn(String.format("Can't resolve conflicting change:\n'%s'\n'%s'\n'%s'\n", texts.get(0), texts.get(1), texts.get(2))); - return; - } - - String[] newContentLines = LineTokenizer.tokenize(newContent, false); - myModel.replaceChange(change.getIndex(), Arrays.asList(newContentLines)); - markChangeResolved(change); - } - private class MyMergeModel extends MergeModelBase { public MyMergeModel(@Nullable Project project, @NotNull Document document) { super(project, document); @@ -871,17 +830,7 @@ public class TextMergeViewer implements MergeTool.MergeViewer { // private boolean hasNonConflictedChanges(@NotNull ThreeSide side) { - return ContainerUtil.exists(getAllChanges(), change -> { - if (change.isConflict()) { - return side == ThreeSide.BASE && - canResolveConflictedChange(change); - } - else { - return !change.isResolved() && - change.isChange(side) && - !isChangeRangeModified(change); - } - }); + return ContainerUtil.exists(getAllChanges(), change -> canApplyNonConflictedChange(change, side)); } private void applyNonConflictedChanges(@NotNull ThreeSide side) { @@ -896,15 +845,55 @@ public class TextMergeViewer implements MergeTool.MergeViewer { if (firstUnresolved != null) doScrollToChange(firstUnresolved, true); } - private void applyNonConflictedChange(@NotNull TextMergeChange change, @NotNull ThreeSide side) { + public boolean canApplyNonConflictedChange(@NotNull TextMergeChange change, @NotNull ThreeSide side) { if (change.isConflict()) { - if (side != ThreeSide.BASE) return; - resolveConflictedChange(change); + return side == ThreeSide.BASE && + change.getType().canBeResolved() && + !change.isResolved(Side.LEFT) && !change.isResolved(Side.RIGHT) && + !isChangeRangeModified(change); + } + else { + return !change.isResolved() && + change.isChange(side) && + !isChangeRangeModified(change); + } + } + + private boolean isChangeRangeModified(@NotNull TextMergeChange change) { + MergeLineFragment changeFragment = change.getFragment(); + int baseStartLine = changeFragment.getStartLine(ThreeSide.BASE); + int baseEndLine = changeFragment.getEndLine(ThreeSide.BASE); + DiffContent baseDiffContent = ThreeSide.BASE.select(myMergeRequest.getContents()); + Document baseDocument = ((DocumentContent)baseDiffContent).getDocument(); + + int resultStartLine = change.getStartLine(); + int resultEndLine = change.getEndLine(); + Document resultDocument = getEditor().getDocument(); + + CharSequence baseContent = DiffUtil.getLinesContent(baseDocument, baseStartLine, baseEndLine); + CharSequence resultContent = DiffUtil.getLinesContent(resultDocument, resultStartLine, resultEndLine); + return !StringUtil.equals(baseContent, resultContent); + } + + public void applyNonConflictedChange(@NotNull TextMergeChange change, @NotNull ThreeSide side) { + if (!canApplyNonConflictedChange(change, side)) return; + + if (change.isConflict()) { + List texts = ThreeSide.map(it -> { + return DiffUtil.getLinesContent(getEditor(it).getDocument(), change.getStartLine(it), change.getEndLine(it)); + }); + + CharSequence newContent = ComparisonMergeUtil.tryResolveConflict(texts.get(0), texts.get(1), texts.get(2)); + if (newContent == null) { + LOG.warn(String.format("Can't resolve conflicting change:\n'%s'\n'%s'\n'%s'\n", texts.get(0), texts.get(1), texts.get(2))); + return; + } + + String[] newContentLines = LineTokenizer.tokenize(newContent, false); + myModel.replaceChange(change.getIndex(), Arrays.asList(newContentLines)); + markChangeResolved(change); } else { - if (change.isResolved(side)) return; - if (!change.isChange(side)) return; - if (isChangeRangeModified(change)) return; Side masterSide = side.select(Side.LEFT, change.isChange(Side.LEFT) ? Side.LEFT : Side.RIGHT, Side.RIGHT); @@ -1155,13 +1144,7 @@ public class TextMergeViewer implements MergeTool.MergeViewer { @Override protected boolean isEnabled(@NotNull TextMergeChange change) { - if (change.isConflict()) { - return canResolveConflictedChange(change); - } - else { - return !change.isResolved() && - !isChangeRangeModified(change); - } + return canApplyNonConflictedChange(change, ThreeSide.BASE); } @Override diff --git a/platform/diff-impl/tests/com/intellij/diff/merge/MergeAutoTest.kt b/platform/diff-impl/tests/com/intellij/diff/merge/MergeAutoTest.kt index d06c2b9bb7ea..b1742dbdd8bb 100644 --- a/platform/diff-impl/tests/com/intellij/diff/merge/MergeAutoTest.kt +++ b/platform/diff-impl/tests/com/intellij/diff/merge/MergeAutoTest.kt @@ -82,7 +82,7 @@ class MergeAutoTest : MergeTestBase() { val index = RNG.nextInt(changes.size) val change = changes[index] - command(change) { viewer.resolveConflictedChange(change) } + command(change) { viewer.applyNonConflictedChange(change, ThreeSide.BASE) } } private fun TestBuilder.doModifyText(): Unit { diff --git a/platform/diff-impl/tests/com/intellij/diff/merge/MergeTestBase.kt b/platform/diff-impl/tests/com/intellij/diff/merge/MergeTestBase.kt index b3ebeb42f330..3b9275e5283f 100644 --- a/platform/diff-impl/tests/com/intellij/diff/merge/MergeTestBase.kt +++ b/platform/diff-impl/tests/com/intellij/diff/merge/MergeTestBase.kt @@ -164,14 +164,14 @@ abstract class MergeTestBase : DiffTestCase() { fun Int.resolve() { val change = change(this) command(change) { - assertTrue(viewer.canResolveConflictedChange(change)) - viewer.resolveConflictedChange(change) + assertTrue(change.isConflict && viewer.canApplyNonConflictedChange(change, ThreeSide.BASE)) + viewer.applyNonConflictedChange(change, ThreeSide.BASE) } } fun Int.canResolveConflict(): Boolean { val change = change(this) - return viewer.canResolveConflictedChange(change) + return viewer.canApplyNonConflictedChange(change, ThreeSide.BASE) } //