blob: aecc0294d4e753f8c1b3e22b8999da6038faa6e1 [file] [log] [blame]
package com.intellij.openapi.diff.impl.incrementalMerge;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.util.TextRange;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class TwoSideChange<T extends TwoSideChange.SideChange> extends ChangeSide implements DiffRangeMarker.RangeInvalidListener {
@NotNull protected final MergeList myMergeList;
@NotNull protected DiffRangeMarker myBaseRangeMarker;
protected T myLeftChange;
protected T myRightChange;
@NotNull protected final ChangeHighlighterHolder myCommonHighlighterHolder;
protected TwoSideChange(@NotNull TextRange baseRange,
@NotNull MergeList mergeList,
@NotNull ChangeHighlighterHolder highlighterHolder) {
myBaseRangeMarker = new DiffRangeMarker((DocumentEx)mergeList.getBaseDocument(), baseRange, this);
myMergeList = mergeList;
myCommonHighlighterHolder = highlighterHolder;
}
@NotNull
public ChangeHighlighterHolder getHighlighterHolder() {
return myCommonHighlighterHolder;
}
@NotNull
public DiffRangeMarker getRange() {
return myBaseRangeMarker;
}
@Nullable
public Change getLeftChange() {
return myLeftChange;
}
@Nullable
public Change getRightChange() {
return myRightChange;
}
public void setRange(@NotNull DiffRangeMarker range) {
myBaseRangeMarker = range;
}
@Nullable
T getOtherChange(@NotNull T change) {
if (change == myLeftChange) {
return myRightChange;
}
else if (change == myRightChange) {
return myLeftChange;
}
else {
throw new IllegalStateException("Unexpected change: " + change);
}
}
public void removeOtherChange(@NotNull T change) {
if (change == myLeftChange) {
myRightChange = null;
}
else if (change == myRightChange) {
myLeftChange = null;
}
else {
throw new IllegalStateException("Unexpected change: " + change);
}
}
public void conflictRemoved() {
removeHighlighters(myLeftChange);
removeHighlighters(myRightChange);
myCommonHighlighterHolder.removeHighlighters();
myMergeList.removeChanges(myLeftChange, myRightChange);
myBaseRangeMarker.removeListener(this);
}
private static <T extends SideChange> void removeHighlighters(@Nullable T change) {
if (change != null) {
change.getOriginalSide().getHighlighterHolder().removeHighlighters();
}
}
@NotNull
public Document getOriginalDocument(FragmentSide mergeSide) {
return myMergeList.getChanges(mergeSide).getDocument(MergeList.BRANCH_SIDE);
}
public void onRangeInvalidated() {
conflictRemoved();
}
@NotNull
public MergeList getMergeList() {
return myMergeList;
}
protected static abstract class SideChange<V extends TwoSideChange> extends Change implements DiffRangeMarker.RangeInvalidListener {
protected V myTwoSideChange;
@NotNull protected final ChangeList myChangeList;
protected SimpleChangeSide myOriginalSide;
@NotNull protected ChangeType myType;
protected SideChange(@NotNull V twoSideChange,
@NotNull ChangeList changeList,
@NotNull ChangeType type,
@NotNull FragmentSide mergeSide,
@NotNull TextRange versionRange) {
myTwoSideChange = twoSideChange;
myChangeList = changeList;
myOriginalSide =
new SimpleChangeSide(mergeSide, new DiffRangeMarker((DocumentEx)twoSideChange.getOriginalDocument(mergeSide), versionRange, this));
myType = type;
}
@NotNull
public ChangeType getType() {
return myType;
}
public SimpleChangeSide getOriginalSide() {
return myOriginalSide;
}
protected void markApplied() {
myType = ChangeType.deriveApplied(myType);
myChangeList.apply(this);
myOriginalSide.getHighlighterHolder().updateHighlighter(myOriginalSide, myType);
myOriginalSide.getHighlighterHolder().setActions(new AnAction[0]);
// display, what one side of the conflict was resolved to
myTwoSideChange.getHighlighterHolder().updateHighlighter(myTwoSideChange, myType);
}
public ChangeList getChangeList() {
return myTwoSideChange.getMergeList().getChanges(myOriginalSide.getFragmentSide());
}
@Override
protected void changeSide(ChangeSide sideToChange, DiffRangeMarker newRange) {
myTwoSideChange.setRange(newRange);
}
@NotNull
@Override
public ChangeSide getChangeSide(@NotNull FragmentSide side) {
return isBranch(side) ? myOriginalSide : myTwoSideChange;
}
protected static boolean isBranch(@NotNull FragmentSide side) {
return MergeList.BRANCH_SIDE == side;
}
protected void removeFromList() {
myTwoSideChange.conflictRemoved();
myTwoSideChange = null;
}
public boolean isValid() {
return myTwoSideChange != null;
}
public void onRemovedFromList() {
myOriginalSide.getRange().removeListener(this);
myTwoSideChange = null;
myOriginalSide = null;
}
public void onRangeInvalidated() {
removeFromList();
}
}
}