use of com.google.gerrit.jgit.diff.ReplaceEdit in project gerrit by GerritCodeReview.
the class IntraLineLoader method compute.
static IntraLineDiff compute(Text aText, Text bText, ImmutableList<Edit> immutableEdits, ImmutableSet<Edit> immutableEditsDueToRebase) {
List<Edit> edits = new ArrayList<>(immutableEdits);
combineLineEdits(edits, immutableEditsDueToRebase, aText, bText);
for (int i = 0; i < edits.size(); i++) {
Edit e = edits.get(i);
if (e.getType() == Edit.Type.REPLACE) {
CharText a = new CharText(aText, e.getBeginA(), e.getEndA());
CharText b = new CharText(bText, e.getBeginB(), e.getEndB());
CharTextComparator cmp = new CharTextComparator();
List<Edit> wordEdits = MyersDiff.INSTANCE.diff(cmp, a, b);
//
for (int j = 0; j < wordEdits.size() - 1; ) {
Edit c = wordEdits.get(j);
Edit n = wordEdits.get(j + 1);
if (n.getBeginA() - c.getEndA() <= 5 || n.getBeginB() - c.getEndB() <= 5) {
int ab = c.getBeginA();
int ae = n.getEndA();
int bb = c.getBeginB();
int be = n.getEndB();
if (canCoalesce(a, c.getEndA(), n.getBeginA()) && canCoalesce(b, c.getEndB(), n.getBeginB())) {
wordEdits.set(j, new Edit(ab, ae, bb, be));
wordEdits.remove(j + 1);
continue;
}
}
j++;
}
//
for (int j = 0; j < wordEdits.size(); j++) {
Edit c = wordEdits.get(j);
int ab = c.getBeginA();
int ae = c.getEndA();
int bb = c.getBeginB();
int be = c.getEndB();
//
if (1 < j) {
Edit p = wordEdits.get(j - 1);
if (p.getEndA() == ab || p.getEndB() == bb) {
if (p.getEndA() == ab && p.getBeginA() < p.getEndA()) {
ab = p.getBeginA();
}
if (p.getEndB() == bb && p.getBeginB() < p.getEndB()) {
bb = p.getBeginB();
}
wordEdits.remove(--j);
}
}
//
while (ab < ae && bb < be && cmp.equals(a, ab, b, bb)) {
ab++;
bb++;
}
while (ab < ae && bb < be && cmp.equals(a, ae - 1, b, be - 1)) {
ae--;
be--;
}
//
while (0 < ab && ab < ae && a.charAt(ab - 1) != '\n' && cmp.equals(a, ab - 1, a, ae - 1)) {
ab--;
ae--;
}
if (!a.isLineStart(ab) || !a.contains(ab, ae, '\n')) {
while (ab < ae && ae < a.size() && cmp.equals(a, ab, a, ae)) {
ab++;
ae++;
if (a.charAt(ae - 1) == '\n') {
break;
}
}
}
while (0 < bb && bb < be && b.charAt(bb - 1) != '\n' && cmp.equals(b, bb - 1, b, be - 1)) {
bb--;
be--;
}
if (!b.isLineStart(bb) || !b.contains(bb, be, '\n')) {
while (bb < be && be < b.size() && cmp.equals(b, bb, b, be)) {
bb++;
be++;
if (b.charAt(be - 1) == '\n') {
break;
}
}
}
//
if (//
ab < ae && //
(ab == 0 || a.charAt(ab - 1) == '\n') && ae < a.size() && a.charAt(ae - 1) != '\n' && a.charAt(ae) == '\n') {
ae++;
}
if (//
bb < be && //
(bb == 0 || b.charAt(bb - 1) == '\n') && be < b.size() && b.charAt(be - 1) != '\n' && b.charAt(be) == '\n') {
be++;
}
wordEdits.set(j, new Edit(ab, ae, bb, be));
}
// check fails, fallback to a single replace edit that covers the whole area.
if (isValidTransformation(a, b, wordEdits)) {
edits.set(i, new ReplaceEdit(e, wordEdits));
} else {
edits.set(i, new ReplaceEdit(e, Arrays.asList(new Edit(0, a.size(), 0, b.size()))));
}
}
}
return new IntraLineDiff(edits);
}
use of com.google.gerrit.jgit.diff.ReplaceEdit in project gerrit by GerritCodeReview.
the class IntraLineDiff method writeObject.
private void writeObject(ObjectOutputStream out) throws IOException {
writeEnum(out, status);
writeVarInt32(out, edits.size());
for (Edit e : edits) {
writeEdit(out, e);
if (e instanceof ReplaceEdit) {
ReplaceEdit r = (ReplaceEdit) e;
writeVarInt32(out, r.getInternalEdits().size());
for (Edit i : r.getInternalEdits()) {
writeEdit(out, i);
}
} else {
writeVarInt32(out, 0);
}
}
}
use of com.google.gerrit.jgit.diff.ReplaceEdit in project gerrit by GerritCodeReview.
the class DiffContentCalculator method correctForDifferencesInNewlineAtEnd.
private ImmutableList<Edit> correctForDifferencesInNewlineAtEnd(TextSource a, TextSource b, ImmutableList<Edit> edits) {
// a.src.size() is the size ignoring a newline at the end whereas a.size() considers it.
int aSize = a.src.size();
int bSize = b.src.size();
if (edits.isEmpty() && (aSize == 0 || bSize == 0)) {
// renamed file looks like a deletion).
return edits;
}
if (edits.isEmpty() && (aSize != bSize)) {
// code which later assembles the file contents would fail.
return edits;
}
Optional<Edit> lastEdit = getLast(edits);
if (isNewlineAtEndDeleted(a, b)) {
Optional<Edit> lastLineEdit = lastEdit.filter(edit -> edit.getEndA() == aSize);
if (lastLineEdit.isPresent()) {
Edit edit = lastLineEdit.get();
Edit updatedLastLineEdit = edit instanceof ReplaceEdit ? new ReplaceEdit(edit.getBeginA(), edit.getEndA() + 1, edit.getBeginB(), edit.getEndB(), ((ReplaceEdit) edit).getInternalEdits()) : new Edit(edit.getBeginA(), edit.getEndA() + 1, edit.getBeginB(), edit.getEndB());
ImmutableList.Builder<Edit> newEditsBuilder = ImmutableList.builderWithExpectedSize(edits.size());
return newEditsBuilder.addAll(edits.subList(0, edits.size() - 1)).add(updatedLastLineEdit).build();
}
ImmutableList.Builder<Edit> newEditsBuilder = ImmutableList.builderWithExpectedSize(edits.size() + 1);
Edit newlineEdit = new Edit(aSize, aSize + 1, bSize, bSize);
return newEditsBuilder.addAll(edits).add(newlineEdit).build();
} else if (isNewlineAtEndAdded(a, b)) {
Optional<Edit> lastLineEdit = lastEdit.filter(edit -> edit.getEndB() == bSize);
if (lastLineEdit.isPresent()) {
Edit edit = lastLineEdit.get();
Edit updatedLastLineEdit = edit instanceof ReplaceEdit ? new ReplaceEdit(edit.getBeginA(), edit.getEndA(), edit.getBeginB(), edit.getEndB() + 1, ((ReplaceEdit) edit).getInternalEdits()) : new Edit(edit.getBeginA(), edit.getEndA(), edit.getBeginB(), edit.getEndB() + 1);
ImmutableList.Builder<Edit> newEditsBuilder = ImmutableList.builderWithExpectedSize(edits.size());
return newEditsBuilder.addAll(edits.subList(0, edits.size() - 1)).add(updatedLastLineEdit).build();
}
ImmutableList.Builder<Edit> newEditsBuilder = ImmutableList.builderWithExpectedSize(edits.size() + 1);
Edit newlineEdit = new Edit(aSize, aSize, bSize, bSize + 1);
return newEditsBuilder.addAll(edits).add(newlineEdit).build();
}
return edits;
}
use of com.google.gerrit.jgit.diff.ReplaceEdit in project gerrit by GerritCodeReview.
the class IntraLineDiff method readObject.
private void readObject(ObjectInputStream in) throws IOException {
status = readEnum(in, Status.values());
int editCount = readVarInt32(in);
Edit[] editArray = new Edit[editCount];
for (int i = 0; i < editCount; i++) {
editArray[i] = readEdit(in);
int innerCount = readVarInt32(in);
if (0 < innerCount) {
Edit[] inner = new Edit[innerCount];
for (int j = 0; j < innerCount; j++) {
inner[j] = readEdit(in);
}
editArray[i] = new ReplaceEdit(editArray[i], asList(inner));
}
}
edits = ImmutableList.copyOf(editArray);
}
use of com.google.gerrit.jgit.diff.ReplaceEdit in project gerrit by GerritCodeReview.
the class DiffInfoCreator method calculateDiffContentEntries.
private static List<ContentEntry> calculateDiffContentEntries(PatchScript ps) {
ContentCollector contentCollector = new ContentCollector(ps);
Set<Edit> editsDueToRebase = ps.getEditsDueToRebase();
for (Edit edit : ps.getEdits()) {
logger.atFine().log("next edit = %s", edit);
if (edit.getType() == Edit.Type.EMPTY) {
logger.atFine().log("skip empty edit");
continue;
}
contentCollector.addCommon(edit.getBeginA());
checkState(contentCollector.nextA == edit.getBeginA(), "nextA = %s; want %s", contentCollector.nextA, edit.getBeginA());
checkState(contentCollector.nextB == edit.getBeginB(), "nextB = %s; want %s", contentCollector.nextB, edit.getBeginB());
switch(edit.getType()) {
case DELETE:
case INSERT:
case REPLACE:
List<Edit> internalEdit = edit instanceof ReplaceEdit ? ((ReplaceEdit) edit).getInternalEdits() : null;
boolean dueToRebase = editsDueToRebase.contains(edit);
contentCollector.addDiff(edit.getEndA(), edit.getEndB(), internalEdit, dueToRebase);
break;
case EMPTY:
default:
throw new IllegalStateException();
}
}
contentCollector.addCommon(ps.getA().getSize());
return contentCollector.lines;
}
Aggregations