mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
merge: simplify - move non-conflict resolution logic into one method
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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<CharSequence> 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<TextMergeChange.State> {
|
||||
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<CharSequence> 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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user