mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
diff: simplify LineNumberConvertor
It used to store "Unified <-> (Left, Right)" line mappings while Left and Right sides can be stored independently.
This commit is contained in:
committed by
Aleksey Pivovarov
parent
e8f26d8edc
commit
dfcf95ecae
+68
-90
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.diff.tools.fragmented;
|
||||
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.util.SmartList;
|
||||
import gnu.trove.TIntFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -27,54 +26,32 @@ import java.util.TreeMap;
|
||||
public class LineNumberConvertor {
|
||||
// Oneside -> Twoside
|
||||
@NotNull private final TreeMap<Integer, Integer> myFragments1;
|
||||
@NotNull private final TreeMap<Integer, Integer> myFragments2;
|
||||
|
||||
// Twoside -> Oneside
|
||||
@NotNull private final TreeMap<Integer, Integer> myInvertedFragments1;
|
||||
@NotNull private final TreeMap<Integer, Integer> myInvertedFragments2;
|
||||
|
||||
@NotNull private final Corrector myCorrector = new Corrector();
|
||||
|
||||
private LineNumberConvertor(@NotNull TreeMap<Integer, Integer> fragments1,
|
||||
@NotNull TreeMap<Integer, Integer> fragments2,
|
||||
@NotNull TreeMap<Integer, Integer> invertedFragments1,
|
||||
@NotNull TreeMap<Integer, Integer> invertedFragments2) {
|
||||
@NotNull TreeMap<Integer, Integer> invertedFragments1) {
|
||||
myFragments1 = fragments1;
|
||||
myFragments2 = fragments2;
|
||||
myInvertedFragments1 = invertedFragments1;
|
||||
myInvertedFragments2 = invertedFragments2;
|
||||
}
|
||||
|
||||
public int convert1(int value) {
|
||||
return convert(value, Side.LEFT, true, false);
|
||||
public int convert(int value) {
|
||||
return convert(value, true, false);
|
||||
}
|
||||
|
||||
public int convert2(int value) {
|
||||
return convert(value, Side.RIGHT, true, false);
|
||||
public int convertInv(int value) {
|
||||
return convert(value, false, false);
|
||||
}
|
||||
|
||||
public int convertInv1(int value) {
|
||||
return convert(value, Side.LEFT, false, false);
|
||||
public int convertApproximate(int value) {
|
||||
return convert(value, true, true);
|
||||
}
|
||||
|
||||
public int convertInv2(int value) {
|
||||
return convert(value, Side.RIGHT, false, false);
|
||||
}
|
||||
|
||||
public int convertApproximate1(int value) {
|
||||
return convert(value, Side.LEFT, true, true);
|
||||
}
|
||||
|
||||
public int convertApproximate2(int value) {
|
||||
return convert(value, Side.RIGHT, true, true);
|
||||
}
|
||||
|
||||
public int convertApproximateInv1(int value) {
|
||||
return convert(value, Side.LEFT, false, true);
|
||||
}
|
||||
|
||||
public int convertApproximateInv2(int value) {
|
||||
return convert(value, Side.RIGHT, false, true);
|
||||
public int convertApproximateInv(int value) {
|
||||
return convert(value, false, true);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -82,24 +59,22 @@ public class LineNumberConvertor {
|
||||
//
|
||||
|
||||
@NotNull
|
||||
public TIntFunction createConvertor1() {
|
||||
return this::convert1;
|
||||
public TIntFunction createConvertor() {
|
||||
return this::convert;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TIntFunction createConvertor2() {
|
||||
return this::convert2;
|
||||
public int convert(int value, boolean fromOneside, boolean approximate) {
|
||||
return myCorrector.convertCorrected(value, fromOneside, approximate);
|
||||
}
|
||||
|
||||
private int convert(int value, @NotNull Side side, boolean fromOneside, boolean approximate) {
|
||||
return myCorrector.convertCorrected(value, side, fromOneside, approximate);
|
||||
}
|
||||
|
||||
/*
|
||||
* Both oneside and one of the sides were changed in a same way. We should update converters, because of changed shift.
|
||||
/**
|
||||
* Oneside was changed. We should update converters, because of changed shift.
|
||||
*
|
||||
* @param synchronous true - twoside were changed in a same way
|
||||
* false - twoside was not changed
|
||||
*/
|
||||
public void handleOnesideChange(int startLine, int endLine, int shift, @NotNull Side masterSide) {
|
||||
myCorrector.handleOnesideChange(startLine, endLine, shift, masterSide);
|
||||
public void handleOnesideChange(int startLine, int endLine, int shift, boolean synchronous) {
|
||||
myCorrector.handleOnesideChange(startLine, endLine, shift, synchronous);
|
||||
}
|
||||
|
||||
|
||||
@@ -107,9 +82,8 @@ public class LineNumberConvertor {
|
||||
* @param approximate false: return exact matching between lines, and -1 if it's impossible
|
||||
* true: return 'good enough' position, even if exact matching is impossible
|
||||
*/
|
||||
private int convertRaw(@NotNull Side side, boolean fromOneside, int value, boolean approximate) {
|
||||
TreeMap<Integer, Integer> fragments = fromOneside ? side.select(myFragments1, myFragments2)
|
||||
: side.select(myInvertedFragments1, myInvertedFragments2);
|
||||
private int convertRaw(boolean fromOneside, int value, boolean approximate) {
|
||||
TreeMap<Integer, Integer> fragments = fromOneside ? myFragments1 : myInvertedFragments1;
|
||||
|
||||
if (approximate) {
|
||||
Map.Entry<Integer, Integer> floor = fragments.floorEntry(value);
|
||||
@@ -130,12 +104,9 @@ public class LineNumberConvertor {
|
||||
|
||||
public static class Builder {
|
||||
@NotNull private final TreeMap<Integer, Integer> myFragments1 = new TreeMap<>();
|
||||
@NotNull private final TreeMap<Integer, Integer> myFragments2 = new TreeMap<>();
|
||||
|
||||
@NotNull private final TreeMap<Integer, Integer> myInvertedFragments1 = new TreeMap<>();
|
||||
@NotNull private final TreeMap<Integer, Integer> myInvertedFragments2 = new TreeMap<>();
|
||||
|
||||
public void put1(int start, int newStart, int length) {
|
||||
public void put(int start, int newStart, int length) {
|
||||
myFragments1.put(start, newStart);
|
||||
myFragments1.put(start + length, -1);
|
||||
|
||||
@@ -143,17 +114,9 @@ public class LineNumberConvertor {
|
||||
myInvertedFragments1.put(newStart + length, -1);
|
||||
}
|
||||
|
||||
public void put2(int start, int newStart, int length) {
|
||||
myFragments2.put(start, newStart);
|
||||
myFragments2.put(start + length, -1);
|
||||
|
||||
myInvertedFragments2.put(newStart, start);
|
||||
myInvertedFragments2.put(newStart + length, -1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LineNumberConvertor build() {
|
||||
return new LineNumberConvertor(myFragments1, myFragments2, myInvertedFragments1, myInvertedFragments2);
|
||||
return new LineNumberConvertor(myFragments1, myInvertedFragments1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,36 +167,40 @@ public class LineNumberConvertor {
|
||||
private final List<CorrectedChange> myChanges = new SmartList<>();
|
||||
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
public void handleOnesideChange(int startLine, int endLine, int shift, @NotNull Side masterSide) {
|
||||
int oldOnesideStart = startLine;
|
||||
int oldTwosideStart = convert(startLine, masterSide, true, false);
|
||||
assert oldTwosideStart != -1;
|
||||
|
||||
public void handleOnesideChange(int startLine, int endLine, int shift, boolean synchronous) {
|
||||
int oldLength = endLine - startLine;
|
||||
int newLength = oldLength + shift;
|
||||
|
||||
myChanges.add(new CorrectedChange(oldOnesideStart, oldTwosideStart, oldLength, newLength, masterSide));
|
||||
}
|
||||
if (synchronous) {
|
||||
int oldTwosideStart = convert(startLine, true, false);
|
||||
assert oldTwosideStart != -1;
|
||||
|
||||
public int convertCorrected(int value, @NotNull Side side, boolean fromOneside, boolean approximate) {
|
||||
if (fromOneside) {
|
||||
return convertFromOneside(value, side, approximate, myChanges.size() - 1);
|
||||
myChanges.add(new CorrectedChange(startLine, oldTwosideStart, oldLength, newLength));
|
||||
}
|
||||
else {
|
||||
return convertFromTwoside(value, side, approximate, myChanges.size() - 1);
|
||||
myChanges.add(new CorrectedChange(startLine, oldLength, newLength));
|
||||
}
|
||||
}
|
||||
|
||||
private int convertFromTwoside(int value, @NotNull Side side, boolean approximate, int index) {
|
||||
public int convertCorrected(int value, boolean fromOneside, boolean approximate) {
|
||||
if (fromOneside) {
|
||||
return convertFromOneside(value, approximate, myChanges.size() - 1);
|
||||
}
|
||||
else {
|
||||
return convertFromTwoside(value, approximate, myChanges.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
private int convertFromTwoside(int value, boolean approximate, int index) {
|
||||
if (index < 0) {
|
||||
return convertRaw(side, false, value, approximate);
|
||||
return convertRaw(false, value, approximate);
|
||||
}
|
||||
|
||||
CorrectedChange change = myChanges.get(index);
|
||||
int shift = change.newLength - change.oldLength;
|
||||
|
||||
if (change.side != side) { // ?u' -> ?o'
|
||||
int converted = convertFromTwoside(value, side, approximate, index - 1);
|
||||
if (!change.synchronous) { // ?u' -> ?o'
|
||||
int converted = convertFromTwoside(value, approximate, index - 1);
|
||||
if (converted < change.startOneside) { // Su' -> So'
|
||||
// Su' == Su; So' == So
|
||||
// value == Su'; converted == So
|
||||
@@ -253,26 +220,26 @@ public class LineNumberConvertor {
|
||||
}
|
||||
else { // ?m '-> ?o'
|
||||
if (value < change.startTwoside) { // Sm' -> So'
|
||||
return convertFromTwoside(value, side, approximate, index - 1);
|
||||
return convertFromTwoside(value, approximate, index - 1);
|
||||
}
|
||||
if (value >= change.startTwoside + change.newLength) { // Em' -> Eo'
|
||||
// Em' == Em + shift; Eo' == Eo + shift
|
||||
// value == Em'; converted == Eo
|
||||
int converted = convertFromTwoside(value - shift, side, approximate, index - 1);
|
||||
int converted = convertFromTwoside(value - shift, approximate, index - 1);
|
||||
return append(converted, shift);
|
||||
}
|
||||
|
||||
// Mm' -> Mo'
|
||||
// Ao == Ao'; Am == Am'; Mo' - Ao' == Mm' - Am'
|
||||
// convertedStart == Ao; value - change.startOneside == Mm' - Am'
|
||||
int convertedStart = convertFromTwoside(change.startTwoside, side, approximate, index - 1);
|
||||
int convertedStart = convertFromTwoside(change.startTwoside, approximate, index - 1);
|
||||
return append(convertedStart, value - change.startTwoside);
|
||||
}
|
||||
}
|
||||
|
||||
private int convertFromOneside(int value, @NotNull Side side, boolean approximate, int index) {
|
||||
private int convertFromOneside(int value, boolean approximate, int index) {
|
||||
if (index < 0) {
|
||||
return convertRaw(side, true, value, approximate);
|
||||
return convertRaw(true, value, approximate);
|
||||
}
|
||||
|
||||
CorrectedChange change = myChanges.get(index);
|
||||
@@ -281,25 +248,25 @@ public class LineNumberConvertor {
|
||||
if (value < change.startOneside) { // So' -> Sm', So' -> Su'
|
||||
// So' == So; Sm' == Sm; Su' == Su
|
||||
// value = So'
|
||||
return convertFromOneside(value, side, approximate, index - 1);
|
||||
return convertFromOneside(value, approximate, index - 1);
|
||||
}
|
||||
if (value >= change.startOneside + change.newLength) { // Eo' -> Em', Eo' -> Eu'
|
||||
// Eo' == Eo + shift; Em' == Em + shift; Eu' == Eu
|
||||
// value = Eo'
|
||||
int converted = convertFromOneside(value - shift, side, approximate, index - 1);
|
||||
return append(converted, side == change.side ? shift : 0);
|
||||
int converted = convertFromOneside(value - shift, approximate, index - 1);
|
||||
return append(converted, change.synchronous ? shift : 0);
|
||||
}
|
||||
|
||||
if (side != change.side) { // Mo' -> Mu'
|
||||
if (!change.synchronous) { // Mo' -> Mu'
|
||||
if (!approximate) return -1;
|
||||
// we can't convert Mo' into Mo. And thus get valid Mu/Mu'.
|
||||
// return: Au'
|
||||
return convertFromOneside(change.startOneside, side, approximate, index - 1);
|
||||
return convertFromOneside(change.startOneside, approximate, index - 1);
|
||||
}
|
||||
else { // Mo' -> Mm'
|
||||
// Ao == Ao'; Am == Am'; Mo' - Ao' == Mm' - Am'
|
||||
// value = Mo'
|
||||
int convertedStart = convertFromOneside(change.startOneside, side, approximate, index - 1);
|
||||
int convertedStart = convertFromOneside(change.startOneside, approximate, index - 1);
|
||||
return append(convertedStart, value - change.startOneside);
|
||||
}
|
||||
}
|
||||
@@ -310,18 +277,29 @@ public class LineNumberConvertor {
|
||||
}
|
||||
|
||||
private static class CorrectedChange {
|
||||
public final boolean synchronous;
|
||||
|
||||
public final int startOneside;
|
||||
public final int startTwoside;
|
||||
public final int oldLength;
|
||||
public final int newLength;
|
||||
@NotNull public final Side side;
|
||||
|
||||
public CorrectedChange(int startOneside, int startTwoside, int oldLength, int newLength, @NotNull Side side) {
|
||||
public CorrectedChange(int startOneside, int oldLength, int newLength) {
|
||||
this.synchronous = false;
|
||||
this.startTwoside = -1;
|
||||
|
||||
this.startOneside = startOneside;
|
||||
this.oldLength = oldLength;
|
||||
this.newLength = newLength;
|
||||
}
|
||||
|
||||
public CorrectedChange(int startOneside, int startTwoside, int oldLength, int newLength) {
|
||||
this.synchronous = true;
|
||||
|
||||
this.startOneside = startOneside;
|
||||
this.startTwoside = startTwoside;
|
||||
this.oldLength = oldLength;
|
||||
this.newLength = newLength;
|
||||
this.side = side;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,14 +286,15 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
|
||||
|
||||
FileType fileType = content2.getContentType() == null ? content1.getContentType() : content2.getContentType();
|
||||
|
||||
LineNumberConvertor convertor = builder.getConvertor();
|
||||
LineNumberConvertor convertor1 = builder.getConvertor1();
|
||||
LineNumberConvertor convertor2 = builder.getConvertor2();
|
||||
List<LineRange> changedLines = builder.getChangedLines();
|
||||
boolean isContentsEqual = builder.isEqual();
|
||||
|
||||
CombinedEditorData editorData = new CombinedEditorData(builder.getText(), data.getHighlighter(), data.getRangeHighlighter(), fileType,
|
||||
convertor.createConvertor1(), convertor.createConvertor2());
|
||||
convertor1.createConvertor(), convertor2.createConvertor());
|
||||
|
||||
return apply(editorData, builder.getBlocks(), convertor, changedLines, isContentsEqual);
|
||||
return apply(editorData, builder.getBlocks(), convertor1, convertor2, changedLines, isContentsEqual);
|
||||
}
|
||||
catch (DiffTooBigException e) {
|
||||
return () -> {
|
||||
@@ -360,7 +361,8 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
|
||||
@NotNull
|
||||
private Runnable apply(@NotNull final CombinedEditorData data,
|
||||
@NotNull final List<ChangedBlock> blocks,
|
||||
@NotNull final LineNumberConvertor convertor,
|
||||
@NotNull final LineNumberConvertor convertor1,
|
||||
@NotNull final LineNumberConvertor convertor2,
|
||||
@NotNull final List<LineRange> changedLines,
|
||||
final boolean isContentsEqual) {
|
||||
return () -> {
|
||||
@@ -417,7 +419,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
|
||||
}
|
||||
|
||||
|
||||
myChangedBlockData = new ChangedBlockData(diffChanges, guarderRangeBlocks, convertor, isContentsEqual);
|
||||
myChangedBlockData = new ChangedBlockData(diffChanges, guarderRangeBlocks, convertor1, convertor2, isContentsEqual);
|
||||
|
||||
|
||||
int newCaretLine = transferLineToOneside(oldCaretLineTwoside.second,
|
||||
@@ -454,9 +456,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
|
||||
@CalledInAwt
|
||||
public int transferLineToOnesideStrict(@NotNull Side side, int line) {
|
||||
if (myChangedBlockData == null) return -1;
|
||||
|
||||
LineNumberConvertor lineConvertor = myChangedBlockData.getLineNumberConvertor();
|
||||
return side.isLeft() ? lineConvertor.convertInv1(line) : lineConvertor.convertInv2(line);
|
||||
return myChangedBlockData.getLineNumberConvertor(side).convertInv(line);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -465,9 +465,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
|
||||
@CalledInAwt
|
||||
public int transferLineFromOnesideStrict(@NotNull Side side, int line) {
|
||||
if (myChangedBlockData == null) return -1;
|
||||
|
||||
LineNumberConvertor lineConvertor = myChangedBlockData.getLineNumberConvertor();
|
||||
return side.isLeft() ? lineConvertor.convert1(line) : lineConvertor.convert2(line);
|
||||
return myChangedBlockData.getLineNumberConvertor(side).convert(line);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -476,9 +474,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
|
||||
@CalledInAwt
|
||||
public int transferLineToOneside(@NotNull Side side, int line) {
|
||||
if (myChangedBlockData == null) return line;
|
||||
|
||||
LineNumberConvertor lineConvertor = myChangedBlockData.getLineNumberConvertor();
|
||||
return side.isLeft() ? lineConvertor.convertApproximateInv1(line) : lineConvertor.convertApproximateInv2(line);
|
||||
return myChangedBlockData.getLineNumberConvertor(side).convertApproximateInv(line);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -495,22 +491,23 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
|
||||
return Pair.create(lines, myMasterSide);
|
||||
}
|
||||
|
||||
LineNumberConvertor lineConvertor = myChangedBlockData.getLineNumberConvertor();
|
||||
LineNumberConvertor lineConvertor1 = myChangedBlockData.getLineNumberConvertor(Side.LEFT);
|
||||
LineNumberConvertor lineConvertor2 = myChangedBlockData.getLineNumberConvertor(Side.RIGHT);
|
||||
|
||||
Side side = myMasterSide;
|
||||
lines[0] = lineConvertor.convert1(line);
|
||||
lines[1] = lineConvertor.convert2(line);
|
||||
lines[0] = lineConvertor1.convert(line);
|
||||
lines[1] = lineConvertor2.convert(line);
|
||||
|
||||
if (lines[0] == -1 && lines[1] == -1) {
|
||||
lines[0] = lineConvertor.convertApproximate1(line);
|
||||
lines[1] = lineConvertor.convertApproximate2(line);
|
||||
lines[0] = lineConvertor1.convertApproximate(line);
|
||||
lines[1] = lineConvertor2.convertApproximate(line);
|
||||
}
|
||||
else if (lines[0] == -1) {
|
||||
lines[0] = lineConvertor.convertApproximate1(line);
|
||||
lines[0] = lineConvertor1.convertApproximate(line);
|
||||
side = Side.RIGHT;
|
||||
}
|
||||
else if (lines[1] == -1) {
|
||||
lines[1] = lineConvertor.convertApproximate2(line);
|
||||
lines[1] = lineConvertor2.convertApproximate(line);
|
||||
side = Side.LEFT;
|
||||
}
|
||||
|
||||
@@ -579,8 +576,10 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
|
||||
change.processChange(line1, line2, shift);
|
||||
}
|
||||
|
||||
LineNumberConvertor lineNumberConvertor = myChangedBlockData.getLineNumberConvertor();
|
||||
lineNumberConvertor.handleOnesideChange(line1, line2, shift, myMasterSide);
|
||||
LineNumberConvertor masterConvertor = myChangedBlockData.getLineNumberConvertor(myMasterSide);
|
||||
LineNumberConvertor slaveConvertor = myChangedBlockData.getLineNumberConvertor(myMasterSide.other());
|
||||
masterConvertor.handleOnesideChange(line1, line2, shift, true);
|
||||
slaveConvertor.handleOnesideChange(line1, line2, shift, false);
|
||||
}
|
||||
finally {
|
||||
// TODO: we can avoid marking state out-of-date in some simple cases (like in SimpleDiffViewer)
|
||||
@@ -1185,16 +1184,19 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
|
||||
private static class ChangedBlockData {
|
||||
@NotNull private final List<UnifiedDiffChange> myDiffChanges;
|
||||
@NotNull private final List<RangeMarker> myGuardedRangeBlocks;
|
||||
@NotNull private final LineNumberConvertor myLineNumberConvertor;
|
||||
@NotNull private final LineNumberConvertor myLineNumberConvertor1;
|
||||
@NotNull private final LineNumberConvertor myLineNumberConvertor2;
|
||||
private final boolean myIsContentsEqual;
|
||||
|
||||
public ChangedBlockData(@NotNull List<UnifiedDiffChange> diffChanges,
|
||||
@NotNull List<RangeMarker> guarderRangeBlocks,
|
||||
@NotNull LineNumberConvertor lineNumberConvertor,
|
||||
@NotNull LineNumberConvertor lineNumberConvertor1,
|
||||
@NotNull LineNumberConvertor lineNumberConvertor2,
|
||||
boolean isContentsEqual) {
|
||||
myDiffChanges = diffChanges;
|
||||
myGuardedRangeBlocks = guarderRangeBlocks;
|
||||
myLineNumberConvertor = lineNumberConvertor;
|
||||
myLineNumberConvertor1 = lineNumberConvertor1;
|
||||
myLineNumberConvertor2 = lineNumberConvertor2;
|
||||
myIsContentsEqual = isContentsEqual;
|
||||
}
|
||||
|
||||
@@ -1209,8 +1211,8 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LineNumberConvertor getLineNumberConvertor() {
|
||||
return myLineNumberConvertor;
|
||||
public LineNumberConvertor getLineNumberConvertor(@NotNull Side side) {
|
||||
return side.select(myLineNumberConvertor1, myLineNumberConvertor2);
|
||||
}
|
||||
|
||||
public boolean isContentsEqual() {
|
||||
|
||||
+11
-5
@@ -35,7 +35,8 @@ class UnifiedFragmentBuilder {
|
||||
@NotNull private final StringBuilder myBuilder = new StringBuilder();
|
||||
@NotNull private final List<ChangedBlock> myBlocks = new ArrayList<>();
|
||||
@NotNull private final List<HighlightRange> myRanges = new ArrayList<>();
|
||||
@NotNull private final LineNumberConvertor.Builder myConvertor = new LineNumberConvertor.Builder();
|
||||
@NotNull private final LineNumberConvertor.Builder myConvertor1 = new LineNumberConvertor.Builder();
|
||||
@NotNull private final LineNumberConvertor.Builder myConvertor2 = new LineNumberConvertor.Builder();
|
||||
@NotNull private final List<LineRange> myChangedLines = new ArrayList<>();
|
||||
|
||||
public UnifiedFragmentBuilder(@NotNull List<LineFragment> fragments,
|
||||
@@ -151,10 +152,10 @@ class UnifiedFragmentBuilder {
|
||||
myBuilder.append('\n');
|
||||
|
||||
if (startLine1 != -1) {
|
||||
myConvertor.put1(totalLines, startLine1, lines + 1);
|
||||
myConvertor1.put(totalLines, startLine1, lines + 1);
|
||||
}
|
||||
if (startLine2 != -1) {
|
||||
myConvertor.put2(totalLines, startLine2, lines + 1);
|
||||
myConvertor2.put(totalLines, startLine2, lines + 1);
|
||||
}
|
||||
|
||||
totalLines += lines + 1;
|
||||
@@ -189,8 +190,13 @@ class UnifiedFragmentBuilder {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LineNumberConvertor getConvertor() {
|
||||
return myConvertor.build();
|
||||
public LineNumberConvertor getConvertor1() {
|
||||
return myConvertor1.build();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LineNumberConvertor getConvertor2() {
|
||||
return myConvertor2.build();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+20
-18
@@ -125,42 +125,44 @@ class LineNumberConvertorCorrectorTest : UsefulTestCase() {
|
||||
}
|
||||
|
||||
private class TestBuilder {
|
||||
private val builder = LineNumberConvertor.Builder()
|
||||
private val builder1 = LineNumberConvertor.Builder()
|
||||
private val builder2 = LineNumberConvertor.Builder()
|
||||
private var maxLength = 0 // search for strict matchings in this boundaries (*2 - just in case)
|
||||
|
||||
fun equal(onesideStart: Int, twosideStart: Int, length: Int, side: Side) {
|
||||
if (side.isLeft) {
|
||||
builder.put1(onesideStart, twosideStart, length)
|
||||
builder1.put(onesideStart, twosideStart, length)
|
||||
}
|
||||
else {
|
||||
builder.put2(onesideStart, twosideStart, length)
|
||||
builder2.put(onesideStart, twosideStart, length)
|
||||
}
|
||||
maxLength = Math.max(maxLength, onesideStart + length)
|
||||
maxLength = Math.max(maxLength, twosideStart + length)
|
||||
}
|
||||
|
||||
fun finish(): Test = Test(builder.build(), maxLength)
|
||||
fun finish(): Test = Test(builder1.build(), builder2.build(), maxLength)
|
||||
}
|
||||
|
||||
private class Test(val convertor: LineNumberConvertor, var length: Int) {
|
||||
private class Test(val convertor1: LineNumberConvertor, val convertor2: LineNumberConvertor, var length: Int) {
|
||||
fun change(onesideLine: Int, oldLength: Int, newLength: Int, side: Side) {
|
||||
convertor.handleOnesideChange(onesideLine, onesideLine + oldLength, newLength - oldLength, side)
|
||||
convertor1.handleOnesideChange(onesideLine, onesideLine + oldLength, newLength - oldLength, side == Side.LEFT)
|
||||
convertor2.handleOnesideChange(onesideLine, onesideLine + oldLength, newLength - oldLength, side == Side.RIGHT)
|
||||
length = Math.max(length, length + newLength - oldLength)
|
||||
}
|
||||
|
||||
fun checkStrictSymmetrical() {
|
||||
for (i in 0..length * 2) {
|
||||
val value1 = convertor.convertInv1(i)
|
||||
if (value1 != -1) assertEquals(i, convertor.convert1(value1))
|
||||
val value1 = convertor1.convertInv(i)
|
||||
if (value1 != -1) assertEquals(i, convertor1.convert(value1))
|
||||
|
||||
val value2 = convertor.convertInv2(i)
|
||||
if (value2 != -1) assertEquals(i, convertor.convert2(value2))
|
||||
val value2 = convertor2.convertInv(i)
|
||||
if (value2 != -1) assertEquals(i, convertor2.convert(value2))
|
||||
|
||||
val value3 = convertor.convert1(i)
|
||||
if (value3 != -1) assertEquals(i, convertor.convertInv1(value3))
|
||||
val value3 = convertor1.convert(i)
|
||||
if (value3 != -1) assertEquals(i, convertor1.convertInv(value3))
|
||||
|
||||
val value4 = convertor.convert2(i)
|
||||
if (value4 != -1) assertEquals(i, convertor.convertInv2(value4))
|
||||
val value4 = convertor2.convert(i)
|
||||
if (value4 != -1) assertEquals(i, convertor2.convertInv(value4))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,8 +170,8 @@ class LineNumberConvertorCorrectorTest : UsefulTestCase() {
|
||||
var counter1 = 0
|
||||
var counter2 = 0
|
||||
for (i in 0..length * 2) {
|
||||
if (convertor.convert1(i) != -1) counter1++
|
||||
if (convertor.convert2(i) != -1) counter2++
|
||||
if (convertor1.convert(i) != -1) counter1++
|
||||
if (convertor2.convert(i) != -1) counter2++
|
||||
}
|
||||
assertEquals(minimumMatched1, counter1)
|
||||
assertEquals(minimumMatched2, counter2)
|
||||
@@ -178,12 +180,12 @@ class LineNumberConvertorCorrectorTest : UsefulTestCase() {
|
||||
@Suppress("unused")
|
||||
fun printMatchings() {
|
||||
for (i in 0..length * 2 - 1) {
|
||||
val value = convertor.convert1(i)
|
||||
val value = convertor1.convert(i)
|
||||
if (value != -1) println("L: $i - $value")
|
||||
}
|
||||
|
||||
for (i in 0..length * 2 - 1) {
|
||||
val value = convertor.convert2(i)
|
||||
val value = convertor2.convert(i)
|
||||
if (value != -1) println("R: $i - $value")
|
||||
}
|
||||
}
|
||||
|
||||
+15
-15
@@ -112,16 +112,16 @@ class LineNumberConvertorTest : UsefulTestCase() {
|
||||
put(6, 5, 2)
|
||||
},
|
||||
{
|
||||
assertEquals(0, convertor.convertApproximate1(0))
|
||||
assertEquals(2, convertor.convertApproximate1(1))
|
||||
assertEquals(3, convertor.convertApproximate1(2))
|
||||
assertEquals(3, convertor.convertApproximate1(3))
|
||||
assertEquals(3, convertor.convertApproximate1(4))
|
||||
assertEquals(3, convertor.convertApproximate1(5))
|
||||
assertEquals(5, convertor.convertApproximate1(6))
|
||||
assertEquals(6, convertor.convertApproximate1(7))
|
||||
assertEquals(7, convertor.convertApproximate1(8))
|
||||
assertEquals(7, convertor.convertApproximate1(9))
|
||||
assertEquals(0, convertor.convertApproximate(0))
|
||||
assertEquals(2, convertor.convertApproximate(1))
|
||||
assertEquals(3, convertor.convertApproximate(2))
|
||||
assertEquals(3, convertor.convertApproximate(3))
|
||||
assertEquals(3, convertor.convertApproximate(4))
|
||||
assertEquals(3, convertor.convertApproximate(5))
|
||||
assertEquals(5, convertor.convertApproximate(6))
|
||||
assertEquals(6, convertor.convertApproximate(7))
|
||||
assertEquals(7, convertor.convertApproximate(8))
|
||||
assertEquals(7, convertor.convertApproximate(9))
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -141,7 +141,7 @@ class LineNumberConvertorTest : UsefulTestCase() {
|
||||
private val builder = LineNumberConvertor.Builder()
|
||||
|
||||
fun put(left: Int, right: Int, length: Int) {
|
||||
builder.put1(left, right, length)
|
||||
builder.put(left, right, length)
|
||||
}
|
||||
|
||||
fun finish(): Test = Test(builder.build())
|
||||
@@ -150,20 +150,20 @@ class LineNumberConvertorTest : UsefulTestCase() {
|
||||
private class Test(val convertor: LineNumberConvertor) {
|
||||
fun checkMatch(left: Int, right: Int, length: Int) {
|
||||
for (i in 0..length - 1) {
|
||||
assertEquals(right + i, convertor.convert1(left + i))
|
||||
assertEquals(left + i, convertor.convertInv1(right + i))
|
||||
assertEquals(right + i, convertor.convert(left + i))
|
||||
assertEquals(left + i, convertor.convertInv(right + i))
|
||||
}
|
||||
}
|
||||
|
||||
fun checkEmpty(start: Int, end: Int) {
|
||||
for (i in start..end) {
|
||||
assertEquals(-1, convertor.convert1(i))
|
||||
assertEquals(-1, convertor.convert(i))
|
||||
}
|
||||
}
|
||||
|
||||
fun checkEmptyInv(start: Int, end: Int) {
|
||||
for (i in start..end) {
|
||||
assertEquals(-1, convertor.convertInv1(i))
|
||||
assertEquals(-1, convertor.convertInv(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -62,7 +62,8 @@ class UnifiedFragmentBuilderAutoTest : DiffTestCase() {
|
||||
val ignoreWhitespaces = policy !== ComparisonPolicy.DEFAULT
|
||||
val text = builder.text
|
||||
val blocks = builder.blocks
|
||||
val convertor = builder.convertor
|
||||
val convertor1 = builder.convertor1
|
||||
val convertor2 = builder.convertor2
|
||||
val changedLines = builder.changedLines
|
||||
val ranges = builder.ranges
|
||||
|
||||
@@ -80,12 +81,12 @@ class UnifiedFragmentBuilderAutoTest : DiffTestCase() {
|
||||
val endLine2 = fragment.endLine2
|
||||
|
||||
for (i in startLine1 until endLine1) {
|
||||
val targetLine = convertor.convertInv1(i)
|
||||
val targetLine = convertor1.convertInv(i)
|
||||
assertTrue(targetLine != -1)
|
||||
assertTrue(isLineChanged(targetLine, changedLines))
|
||||
}
|
||||
for (i in startLine2 until endLine2) {
|
||||
val targetLine = convertor.convertInv2(i)
|
||||
val targetLine = convertor2.convertInv(i)
|
||||
assertTrue(targetLine != -1)
|
||||
assertTrue(isLineChanged(targetLine, changedLines))
|
||||
}
|
||||
|
||||
+3
-2
@@ -303,8 +303,9 @@ class ApplyPatchViewer implements DataProvider, Disposable {
|
||||
Document patchDocument = myPatchEditor.getDocument();
|
||||
patchDocument.setText(builder.getPatchContent());
|
||||
|
||||
LineNumberConvertor convertor = builder.getLineConvertor();
|
||||
myPatchEditor.getGutterComponentEx().setLineNumberConvertor(convertor.createConvertor1(), convertor.createConvertor2());
|
||||
LineNumberConvertor convertor1 = builder.getLineConvertor1();
|
||||
LineNumberConvertor convertor2 = builder.getLineConvertor2();
|
||||
myPatchEditor.getGutterComponentEx().setLineNumberConvertor(convertor1.createConvertor(), convertor2.createConvertor());
|
||||
|
||||
TIntArrayList lines = builder.getSeparatorLines();
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
|
||||
+13
-7
@@ -29,7 +29,8 @@ import java.util.List;
|
||||
class PatchChangeBuilder {
|
||||
@NotNull private final StringBuilder myBuilder = new StringBuilder();
|
||||
@NotNull private final List<Hunk> myHunks = new ArrayList<>();
|
||||
@NotNull private final LineNumberConvertor.Builder myConvertor = new LineNumberConvertor.Builder();
|
||||
@NotNull private final LineNumberConvertor.Builder myConvertor1 = new LineNumberConvertor.Builder();
|
||||
@NotNull private final LineNumberConvertor.Builder myConvertor2 = new LineNumberConvertor.Builder();
|
||||
@NotNull private final TIntArrayList myChangedLines = new TIntArrayList();
|
||||
|
||||
private int totalLines = 0;
|
||||
@@ -63,8 +64,8 @@ class PatchChangeBuilder {
|
||||
appendLines(hunk.getInsertedLines());
|
||||
int hunkEnd = totalLines;
|
||||
|
||||
myConvertor.put1(deletion, beforeRange.start + contextBefore.size(), insertion - deletion);
|
||||
myConvertor.put2(insertion, afterRange.start + contextBefore.size(), hunkEnd - insertion);
|
||||
myConvertor1.put(deletion, beforeRange.start + contextBefore.size(), insertion - deletion);
|
||||
myConvertor2.put(insertion, afterRange.start + contextBefore.size(), hunkEnd - insertion);
|
||||
|
||||
|
||||
addContext(contextAfter, beforeRange.end - contextAfter.size(), afterRange.end - contextAfter.size());
|
||||
@@ -79,8 +80,8 @@ class PatchChangeBuilder {
|
||||
}
|
||||
|
||||
private void addContext(@NotNull List<String> context, int beforeLineNumber, int afterLineNumber) {
|
||||
myConvertor.put1(totalLines, beforeLineNumber, context.size());
|
||||
myConvertor.put2(totalLines, afterLineNumber, context.size());
|
||||
myConvertor1.put(totalLines, beforeLineNumber, context.size());
|
||||
myConvertor2.put(totalLines, afterLineNumber, context.size());
|
||||
appendLines(context);
|
||||
}
|
||||
|
||||
@@ -112,8 +113,13 @@ class PatchChangeBuilder {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LineNumberConvertor getLineConvertor() {
|
||||
return myConvertor.build();
|
||||
public LineNumberConvertor getLineConvertor1() {
|
||||
return myConvertor1.build();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LineNumberConvertor getLineConvertor2() {
|
||||
return myConvertor2.build();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user