Search in sources :

Example 1 with ReplaceEdit

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);
}
Also used : ArrayList(java.util.ArrayList) ReplaceEdit(com.google.gerrit.jgit.diff.ReplaceEdit) Edit(org.eclipse.jgit.diff.Edit) ReplaceEdit(com.google.gerrit.jgit.diff.ReplaceEdit)

Example 2 with ReplaceEdit

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);
        }
    }
}
Also used : ReplaceEdit(com.google.gerrit.jgit.diff.ReplaceEdit) Edit(org.eclipse.jgit.diff.Edit) ReplaceEdit(com.google.gerrit.jgit.diff.ReplaceEdit)

Example 3 with ReplaceEdit

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;
}
Also used : SparseFileContentBuilder(com.google.gerrit.prettify.common.SparseFileContentBuilder) List(java.util.List) DiffPreferencesInfo(com.google.gerrit.extensions.client.DiffPreferencesInfo) ImmutableList(com.google.common.collect.ImmutableList) Whitespace(com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace) Edit(org.eclipse.jgit.diff.Edit) ReplaceEdit(com.google.gerrit.jgit.diff.ReplaceEdit) Optional(java.util.Optional) EditHunk(com.google.gerrit.prettify.common.EditHunk) SparseFileContent(com.google.gerrit.prettify.common.SparseFileContent) Optional(java.util.Optional) ImmutableList(com.google.common.collect.ImmutableList) SparseFileContentBuilder(com.google.gerrit.prettify.common.SparseFileContentBuilder) ReplaceEdit(com.google.gerrit.jgit.diff.ReplaceEdit) Edit(org.eclipse.jgit.diff.Edit) ReplaceEdit(com.google.gerrit.jgit.diff.ReplaceEdit)

Example 4 with ReplaceEdit

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);
}
Also used : ReplaceEdit(com.google.gerrit.jgit.diff.ReplaceEdit) Edit(org.eclipse.jgit.diff.Edit) ReplaceEdit(com.google.gerrit.jgit.diff.ReplaceEdit)

Example 5 with ReplaceEdit

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;
}
Also used : ReplaceEdit(com.google.gerrit.jgit.diff.ReplaceEdit) Edit(org.eclipse.jgit.diff.Edit) ReplaceEdit(com.google.gerrit.jgit.diff.ReplaceEdit)

Aggregations

ReplaceEdit (com.google.gerrit.jgit.diff.ReplaceEdit)6 Edit (org.eclipse.jgit.diff.Edit)6 ImmutableList (com.google.common.collect.ImmutableList)1 DiffPreferencesInfo (com.google.gerrit.extensions.client.DiffPreferencesInfo)1 Whitespace (com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace)1 EditHunk (com.google.gerrit.prettify.common.EditHunk)1 SparseFileContent (com.google.gerrit.prettify.common.SparseFileContent)1 SparseFileContentBuilder (com.google.gerrit.prettify.common.SparseFileContentBuilder)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Optional (java.util.Optional)1