mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 19:02:13 +07:00
merge: fix "MagicResolve" with ignored whitespaces
* Do not ignore differences in "unchanged" fragments.
This commit is contained in:
@@ -113,23 +113,60 @@ private class SimpleHelper(val leftText: CharSequence, val baseText: CharSequenc
|
||||
}
|
||||
|
||||
private fun appendBase(range: MergeRange) {
|
||||
newContent.append(baseText, range.start2, range.end2)
|
||||
if (range.isEmpty) return
|
||||
|
||||
val policy = ComparisonPolicy.DEFAULT
|
||||
|
||||
if (isUnchangedRange(range, policy)) {
|
||||
append(range, ThreeSide.BASE)
|
||||
}
|
||||
else {
|
||||
val type = getConflictType(range, policy)
|
||||
if (type.isChange(Side.LEFT)) {
|
||||
append(range, ThreeSide.LEFT)
|
||||
}
|
||||
else if (type.isChange(Side.RIGHT)) {
|
||||
append(range, ThreeSide.RIGHT)
|
||||
}
|
||||
else {
|
||||
append(range, ThreeSide.BASE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun appendConflict(range: MergeRange, policy: ComparisonPolicy): Boolean {
|
||||
val type = DiffUtil.getWordMergeType(MergeWordFragmentImpl(range), texts, policy)
|
||||
if (type.diffType == TextDiffType.CONFLICT) return false;
|
||||
val type = getConflictType(range, policy)
|
||||
if (type.diffType == TextDiffType.CONFLICT) return false
|
||||
|
||||
if (type.isChange(Side.LEFT)) {
|
||||
newContent.append(leftText, range.start1, range.end1)
|
||||
append(range, ThreeSide.LEFT)
|
||||
}
|
||||
else {
|
||||
newContent.append(rightText, range.start3, range.end3)
|
||||
append(range, ThreeSide.RIGHT)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun append(range: MergeRange, side: ThreeSide) {
|
||||
when (side) {
|
||||
ThreeSide.LEFT -> newContent.append(leftText, range.start1, range.end1)
|
||||
ThreeSide.BASE -> newContent.append(baseText, range.start2, range.end2)
|
||||
ThreeSide.RIGHT -> newContent.append(rightText, range.start3, range.end3)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConflictType(range: MergeRange, policy: ComparisonPolicy): MergeConflictType {
|
||||
return DiffUtil.getWordMergeType(MergeWordFragmentImpl(range), texts, policy)
|
||||
}
|
||||
|
||||
private fun isUnchangedRange(range: MergeRange, policy: ComparisonPolicy): Boolean {
|
||||
return DiffUtil.compareWordMergeContents(MergeWordFragmentImpl(range), texts, policy, ThreeSide.BASE, ThreeSide.LEFT) &&
|
||||
DiffUtil.compareWordMergeContents(MergeWordFragmentImpl(range), texts, policy, ThreeSide.BASE, ThreeSide.RIGHT)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class GreedyHelper(val leftText: CharSequence, val baseText: CharSequence, val rightText: CharSequence) {
|
||||
private val newContent = StringBuilder()
|
||||
|
||||
|
||||
@@ -1293,11 +1293,11 @@ public class DiffUtil {
|
||||
BooleanGetter.FALSE);
|
||||
}
|
||||
|
||||
private static boolean compareWordMergeContents(@NotNull MergeWordFragment fragment,
|
||||
@NotNull List<? extends CharSequence> texts,
|
||||
@NotNull ComparisonPolicy policy,
|
||||
@NotNull ThreeSide side1,
|
||||
@NotNull ThreeSide side2) {
|
||||
public static boolean compareWordMergeContents(@NotNull MergeWordFragment fragment,
|
||||
@NotNull List<? extends CharSequence> texts,
|
||||
@NotNull ComparisonPolicy policy,
|
||||
@NotNull ThreeSide side1,
|
||||
@NotNull ThreeSide side2) {
|
||||
int start1 = fragment.getStartOffset(side1);
|
||||
int end1 = fragment.getEndOffset(side1);
|
||||
int start2 = fragment.getStartOffset(side2);
|
||||
|
||||
@@ -192,26 +192,98 @@ class MergeResolveUtilTest : DiffTestCase() {
|
||||
"i\n",
|
||||
"i",
|
||||
"\ni",
|
||||
"i\n",
|
||||
"i",
|
||||
"i"
|
||||
)
|
||||
|
||||
testSimple(
|
||||
"Y X Y",
|
||||
"Y C\nX\nC Y",
|
||||
"Y \nX\n Y",
|
||||
"Y \nC\nX\nC Y"
|
||||
)
|
||||
|
||||
test(
|
||||
"""
|
||||
public static class ChangeData {
|
||||
@NotNull public final ChangeKind kind;
|
||||
public final int otherPath;
|
||||
|
||||
public ChangeData(@NotNull ChangeKind kind, int otherPath) {
|
||||
this.kind = kind;
|
||||
this.otherPath = otherPath;
|
||||
}
|
||||
|
||||
public boolean isRename() {
|
||||
return kind.equals(ChangeKind.RENAMED_FROM) || kind.equals(ChangeKind.RENAMED_TO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(kind, otherPath);
|
||||
}
|
||||
}
|
||||
|
||||
private enum ChangeKind {
|
||||
MODIFIED((byte)0),
|
||||
RENAMED_FROM((byte)1),
|
||||
RENAMED_TO((byte)2);""",
|
||||
"""
|
||||
public enum ChangeKind {
|
||||
NOT_CHANGED((byte)-1),
|
||||
MODIFIED((byte)0),
|
||||
ADDED((byte)1),
|
||||
REMOVED((byte)2);""",
|
||||
"""
|
||||
public static class ChangeData {
|
||||
@NotNull public final ChangeKind kind;
|
||||
public final int otherPath;
|
||||
|
||||
public ChangeData(@NotNull ChangeKind kind, int otherPath) {
|
||||
this.kind = kind;
|
||||
this.otherPath = otherPath;
|
||||
}
|
||||
|
||||
public boolean isRename() {
|
||||
return kind.equals(ChangeKind.RENAMED_FROM) || kind.equals(ChangeKind.RENAMED_TO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(kind, otherPath);
|
||||
}
|
||||
}
|
||||
|
||||
private enum ChangeKind {
|
||||
MODIFIED((byte)0),
|
||||
RENAMED_FROM((byte)1),
|
||||
RENAMED_TO((byte)2);""",
|
||||
"""
|
||||
public enum ChangeKind {
|
||||
NOT_CHANGED((byte)-1),
|
||||
MODIFIED((byte)0),
|
||||
ADDED((byte)1),
|
||||
REMOVED((byte)2);"""
|
||||
)
|
||||
}
|
||||
|
||||
private fun testGreedy(base: String, left: String, right: String, expected: String?) {
|
||||
test(base, left, right, expected, true)
|
||||
private fun testSimple(base: String, left: String, right: String, expected: String?) {
|
||||
val simpleResult = MergeResolveUtil.tryResolve(left, base, right)
|
||||
assertEquals(expected, simpleResult)
|
||||
}
|
||||
|
||||
private fun test(base: String, left: String, right: String, expected: String?, isGreedy: Boolean = false) {
|
||||
val expectedSimple = if (isGreedy) null else expected
|
||||
val expectedGreedy = expected
|
||||
test(base, left, right, expectedSimple, expectedGreedy)
|
||||
private fun testGreedy(base: String, left: String, right: String, expected: String?) {
|
||||
val greedyResult = MergeResolveUtil.tryGreedyResolve(left, base, right)
|
||||
assertEquals(expected, greedyResult)
|
||||
}
|
||||
|
||||
private fun test(base: String, left: String, right: String, expected: String?) {
|
||||
testSimple(base, left, right, expected)
|
||||
testGreedy(base, left, right, expected)
|
||||
}
|
||||
|
||||
private fun test(base: String, left: String, right: String, expectedSimple: String?, expectedGreedy: String?) {
|
||||
val simpleResult = MergeResolveUtil.tryResolve(left, base, right)
|
||||
val greedyResult = MergeResolveUtil.tryGreedyResolve(left, base, right)
|
||||
|
||||
assertEquals(expectedSimple, simpleResult, "Simple")
|
||||
assertEquals(expectedGreedy, greedyResult, "Greedy")
|
||||
testSimple(base, left, right, expectedSimple)
|
||||
testGreedy(base, left, right, expectedGreedy)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user