mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
VCS: remove equal start and end parts on Diff class level - for all calls
This commit is contained in:
@@ -39,11 +39,15 @@ public class Enumerator<T> {
|
||||
}
|
||||
|
||||
public int[] enumerate(T[] objects) {
|
||||
int[] idx = ArrayUtil.newIntArray(objects.length);
|
||||
for (int i = 0; i < objects.length; i++) {
|
||||
return enumerate(objects, 0, 0);
|
||||
}
|
||||
|
||||
public int[] enumerate(T[] objects, final int startShift, final int endCut) {
|
||||
int[] idx = ArrayUtil.newIntArray(objects.length - startShift - endCut);
|
||||
for (int i = startShift; i < (objects.length - endCut); i++) {
|
||||
final T object = objects[i];
|
||||
final int number = enumerate(object);
|
||||
idx[i] = number;
|
||||
idx[i - startShift] = number;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
@@ -32,30 +32,54 @@ public class Diff {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.util.diff.Diff");
|
||||
|
||||
@Nullable
|
||||
public static Change buildChanges(@NotNull CharSequence before, @NotNull CharSequence after) {
|
||||
public static Change buildChanges(@NotNull CharSequence before, @NotNull CharSequence after) throws FilesTooBigForDiffException {
|
||||
final String[] strings1 = LineTokenizer.tokenize(before, false);
|
||||
final String[] strings2 = LineTokenizer.tokenize(after, false);
|
||||
return buildChanges(strings1, strings2);
|
||||
}
|
||||
|
||||
public static <T> Change buildChanges(T[] objects1, T[] objects2) {
|
||||
public static <T> Change buildChanges(T[] objects1, T[] objects2) throws FilesTooBigForDiffException {
|
||||
// Old variant of enumerator worked incorrectly with null values.
|
||||
// This check is to ensure that the corrected version does not introduce bugs.
|
||||
for (T anObjects1 : objects1) LOG.assertTrue(anObjects1 != null);
|
||||
for (T anObjects2 : objects2) LOG.assertTrue(anObjects2 != null);
|
||||
|
||||
final int startShift = getStartShift(objects1, objects2);
|
||||
final int endCut = getEndCut(objects1, objects2, startShift);
|
||||
|
||||
Enumerator<T> enumerator = new Enumerator<T>(objects1.length + objects2.length, TObjectHashingStrategy.CANONICAL);
|
||||
int[] ints1 = enumerator.enumerate(objects1);
|
||||
int[] ints2 = enumerator.enumerate(objects2);
|
||||
int[] ints1 = enumerator.enumerate(objects1, startShift, endCut);
|
||||
int[] ints2 = enumerator.enumerate(objects2, startShift, endCut);
|
||||
Reindexer reindexer = new Reindexer();
|
||||
int[][] discarded = reindexer.discardUnique(ints1, ints2);
|
||||
IntLCS intLCS = new IntLCS(discarded[0], discarded[1]);
|
||||
intLCS.execute();
|
||||
ChangeBuilder builder = new ChangeBuilder();
|
||||
ChangeBuilder builder = new ChangeBuilder(startShift);
|
||||
reindexer.reindex(intLCS.getPaths(), builder);
|
||||
return builder.getFirstChange();
|
||||
}
|
||||
|
||||
private static <T> int getStartShift(final T[] o1, final T[] o2) {
|
||||
final int size = Math.min(o1.length, o2.length);
|
||||
int idx = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (! o1[i].equals(o2[i])) break;
|
||||
++ idx;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
private static <T> int getEndCut(final T[] o1, final T[] o2, final int startShift) {
|
||||
final int size = Math.min(o1.length, o2.length) - startShift;
|
||||
int idx = 0;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (! o1[o1.length - i - 1].equals(o2[o2.length - i - 1])) break;
|
||||
++ idx;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to translate given line that pointed to the text before change to the line that points to the same text after the change.
|
||||
*
|
||||
@@ -64,7 +88,7 @@ public class Diff {
|
||||
* @param line target line before change
|
||||
* @return translated line if the processing is ok; negative value otherwise
|
||||
*/
|
||||
public static int translateLine(@NotNull CharSequence before, @NotNull CharSequence after, int line) {
|
||||
public static int translateLine(@NotNull CharSequence before, @NotNull CharSequence after, int line) throws FilesTooBigForDiffException {
|
||||
Change change = buildChanges(before, after);
|
||||
if (change == null) {
|
||||
return -1;
|
||||
|
||||
@@ -21,8 +21,6 @@ import junit.framework.TestCase;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.intellij.util.containers.Enumerator;
|
||||
|
||||
/**
|
||||
* @author dyoma
|
||||
*/
|
||||
@@ -34,4 +32,10 @@ public class EnumeratorTest extends TestCase {
|
||||
indecies = enumerator.enumerate(new Object[]{"a", "c", "b"});
|
||||
assertTrue(Arrays.equals(new int[]{1, 3, 2}, indecies));
|
||||
}
|
||||
|
||||
public void testWithShift() {
|
||||
Enumerator enumerator = new Enumerator(10, TObjectHashingStrategy.CANONICAL);
|
||||
int[] indecies = enumerator.enumerate(new Object[]{"1","a", "b", "a", "2"}, 1, 1);
|
||||
assertTrue(Arrays.equals(new int[]{1, 2, 1}, indecies));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,34 +27,41 @@ public class DiffTest extends TestCase {
|
||||
private static final Object[] DATA_123 = new Object[]{"1", "2", "3"};
|
||||
private static final Object[] DATA_AB = new Object[]{"a", "b"};
|
||||
private static final Object[] DATA_12AB23 = new Object[]{"1", "2", "a", "b", "2", "3"};
|
||||
private static final Object[] DATA_123_ = new Object[]{"x","y","z","1", "2","3","alpha","beta"};
|
||||
private static final Object[] DATA_12AB23_ = new Object[]{"x","y","z","1", "2", "a", "b", "2", "3","alpha","beta"};
|
||||
|
||||
public void testEqual() {
|
||||
public void testEqual() throws FilesTooBigForDiffException {
|
||||
Diff.Change change = Diff.buildChanges(DATA_123, DATA_123);
|
||||
assertNull(change);
|
||||
}
|
||||
|
||||
public void testCompletelyDifferent() {
|
||||
public void testCompletelyDifferent() throws FilesTooBigForDiffException {
|
||||
Diff.Change change = Diff.buildChanges(DATA_AB, DATA_123);
|
||||
IntLCSTest.checkLastChange(change, 0, 0, 3, 2);
|
||||
}
|
||||
|
||||
public void testSameMiddle() {
|
||||
public void testSameMiddle() throws FilesTooBigForDiffException {
|
||||
Diff.Change change = Diff.buildChanges(DATA_123, new Object[]{"a", "2", "b"});
|
||||
IntLCSTest.checkChange(change, 0, 0, 1, 1);
|
||||
IntLCSTest.checkLastChange(change.link, 2, 2, 1, 1);
|
||||
}
|
||||
|
||||
public void testOverlap() {
|
||||
public void testOverlap() throws FilesTooBigForDiffException {
|
||||
Diff.Change change = Diff.buildChanges(DATA_123, DATA_12AB23);
|
||||
IntLCSTest.checkLastChange(change, 2, 2, 3, 0); // inserted: AB2
|
||||
}
|
||||
|
||||
public void testEqualUpToOneEnd() {
|
||||
public void testTrim() throws FilesTooBigForDiffException {
|
||||
Diff.Change change = Diff.buildChanges(DATA_123_, DATA_12AB23_);
|
||||
IntLCSTest.checkLastChange(change, 5, 5, 3, 0); // inserted: AB2
|
||||
}
|
||||
|
||||
public void testEqualUpToOneEnd() throws FilesTooBigFirDiffException {
|
||||
Diff.Change change = Diff.buildChanges(DATA_AB, new Object[]{"a", "b", "1"});
|
||||
IntLCSTest.checkLastChange(change, 2, 2, 1, 0);
|
||||
}
|
||||
|
||||
public void testEmptyAgainstSmth() {
|
||||
public void testEmptyAgainstSmth() throws FilesTooBigForDiffException {
|
||||
Object[] empty = ArrayUtil.EMPTY_OBJECT_ARRAY;
|
||||
Diff.Change change = Diff.buildChanges(empty, empty);
|
||||
assertNull(change);
|
||||
@@ -64,7 +71,7 @@ public class DiffTest extends TestCase {
|
||||
IntLCSTest.checkLastChange(change, 0, 0, 3, 0);
|
||||
}
|
||||
|
||||
public void testPerfomance() {
|
||||
public void testPerfomance() throws FilesTooBigForDiffException {
|
||||
ArrayList first = new ArrayList();
|
||||
ArrayList second = new ArrayList();
|
||||
int max = 1000;
|
||||
|
||||
@@ -67,7 +67,7 @@ public class IntLCSTest extends TestCase {
|
||||
assertEquals(expectedNonDiags, intLCS.execute());
|
||||
Reindexer reindexer = new Reindexer();
|
||||
reindexer.idInit(first.length, second.length);
|
||||
Diff.ChangeBuilder builder = new Diff.ChangeBuilder();
|
||||
Diff.ChangeBuilder builder = new Diff.ChangeBuilder(0);
|
||||
reindexer.reindex(intLCS.getPaths(), builder);
|
||||
return builder.getFirstChange();
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class LinkedDiffPathsTest extends TestCase {
|
||||
private Diff.Change decode(LinkedDiffPaths paths) {
|
||||
Reindexer reindexer = new Reindexer();
|
||||
reindexer.idInit(paths.getXSize(), paths.getYSize());
|
||||
Diff.ChangeBuilder builder = new Diff.ChangeBuilder();
|
||||
Diff.ChangeBuilder builder = new Diff.ChangeBuilder(0);
|
||||
reindexer.reindex(paths, builder);
|
||||
return builder.getFirstChange();
|
||||
}
|
||||
|
||||
@@ -36,38 +36,11 @@ public class RangesBuilder {
|
||||
public RangesBuilder(List<String> current, List<String> upToDate, int shift, int uShift) {
|
||||
myRanges = new LinkedList<Range>();
|
||||
|
||||
int shiftBefore = 0;
|
||||
|
||||
int minSize = Math.min(upToDate.size(), current.size());
|
||||
|
||||
for (int i = 0; i < minSize; i++) {
|
||||
if (upToDate.get(0).equals(current.get(0))) {
|
||||
upToDate.remove(0);
|
||||
current.remove(0);
|
||||
shiftBefore += 1;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
minSize = Math.min(upToDate.size(), current.size());
|
||||
|
||||
for (int i = 0; i < minSize; i++) {
|
||||
if (upToDate.get(upToDate.size() - 1).equals(current.get(current.size() - 1))) {
|
||||
upToDate.remove(upToDate.size() - 1);
|
||||
current.remove(current.size() - 1);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Diff.Change ch = Diff.buildChanges(ArrayUtil.toStringArray(upToDate), ArrayUtil.toStringArray(current));
|
||||
|
||||
|
||||
while (ch != null) {
|
||||
Range range = Range.createOn(ch, shift + shiftBefore, uShift + shiftBefore);
|
||||
Range range = Range.createOn(ch, shift, uShift);
|
||||
myRanges.add(range);
|
||||
ch = ch.link;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user