Search in sources :

Example 1 with Edit

use of org.eclipse.jgit.diff.Edit in project gerrit by GerritCodeReview.

the class IntraLineLoader method combineLineEdits.

private static void combineLineEdits(List<Edit> edits, Text a, Text b) {
    for (int j = 0; j < edits.size() - 1; ) {
        Edit c = edits.get(j);
        Edit n = edits.get(j + 1);
        // Combine edits that are really close together. Right now our rule
        // is, coalesce two line edits which are only one line apart if that
        // common context line is either a "pointless line", or is identical
        // on both sides and starts a new block of code. These are mostly
        // block reindents to add or remove control flow operators.
        //
        final int ad = n.getBeginA() - c.getEndA();
        final int bd = n.getBeginB() - c.getEndB();
        if ((1 <= ad && isBlankLineGap(a, c.getEndA(), n.getBeginA())) || (1 <= bd && isBlankLineGap(b, c.getEndB(), n.getBeginB())) || (ad == 1 && bd == 1 && isControlBlockStart(a, c.getEndA()))) {
            int ab = c.getBeginA();
            int ae = n.getEndA();
            int bb = c.getBeginB();
            int be = n.getEndB();
            edits.set(j, new Edit(ab, ae, bb, be));
            edits.remove(j + 1);
            continue;
        }
        j++;
    }
}
Also used : ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) Edit(org.eclipse.jgit.diff.Edit)

Example 2 with Edit

use of org.eclipse.jgit.diff.Edit in project gerrit by GerritCodeReview.

the class IntraLineLoader method compute.

static IntraLineDiff compute(Text aText, Text bText, ImmutableList<Edit> immutableEdits) throws Exception {
    List<Edit> edits = new ArrayList<>(immutableEdits);
    combineLineEdits(edits, 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));
            }
            edits.set(i, new ReplaceEdit(e, wordEdits));
        }
    }
    return new IntraLineDiff(edits);
}
Also used : ArrayList(java.util.ArrayList) ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) Edit(org.eclipse.jgit.diff.Edit)

Example 3 with Edit

use of org.eclipse.jgit.diff.Edit in project gerrit by GerritCodeReview.

the class PatchScriptBuilder method build.

private PatchScript build(final PatchListEntry content, final CommentDetail comments, final List<Patch> history) throws IOException {
    boolean intralineDifferenceIsPossible = true;
    boolean intralineFailure = false;
    boolean intralineTimeout = false;
    a.path = oldName(content);
    b.path = newName(content);
    a.resolve(null, aId);
    b.resolve(a, bId);
    edits = new ArrayList<>(content.getEdits());
    if (!isModify(content)) {
        intralineDifferenceIsPossible = false;
    } else if (diffPrefs.intralineDifference) {
        IntraLineDiff d = patchListCache.getIntraLineDiff(IntraLineDiffKey.create(a.id, b.id, diffPrefs.ignoreWhitespace), IntraLineDiffArgs.create(a.src, b.src, edits, projectKey, bId, b.path));
        if (d != null) {
            switch(d.getStatus()) {
                case EDIT_LIST:
                    edits = new ArrayList<>(d.getEdits());
                    break;
                case DISABLED:
                    intralineDifferenceIsPossible = false;
                    break;
                case ERROR:
                    intralineDifferenceIsPossible = false;
                    intralineFailure = true;
                    break;
                case TIMEOUT:
                    intralineDifferenceIsPossible = false;
                    intralineTimeout = true;
                    break;
            }
        } else {
            intralineDifferenceIsPossible = false;
            intralineFailure = true;
        }
    }
    if (comments != null) {
        ensureCommentsVisible(comments);
    }
    boolean hugeFile = false;
    if (a.src == b.src && a.size() <= context && content.getEdits().isEmpty()) {
        //
        for (int i = 0; i < a.size(); i++) {
            a.addLine(i);
        }
        edits = new ArrayList<>(1);
        edits.add(new Edit(a.size(), a.size()));
    } else {
        if (BIG_FILE < Math.max(a.size(), b.size())) {
            // IF the file is really large, we disable things to avoid choking
            // the browser client.
            //
            hugeFile = true;
        }
        // In order to expand the skipped common lines or syntax highlight the
        // file properly we need to give the client the complete file contents.
        // So force our context temporarily to the complete file size.
        //
        context = MAX_CONTEXT;
        packContent(diffPrefs.ignoreWhitespace != Whitespace.IGNORE_NONE);
    }
    return new PatchScript(change.getKey(), content.getChangeType(), content.getOldName(), content.getNewName(), a.fileMode, b.fileMode, content.getHeaderLines(), diffPrefs, a.dst, b.dst, edits, a.displayMethod, b.displayMethod, a.mimeType.toString(), b.mimeType.toString(), comments, history, hugeFile, intralineDifferenceIsPossible, intralineFailure, intralineTimeout, content.getPatchType() == Patch.PatchType.BINARY, aId == null ? null : aId.getName(), bId == null ? null : bId.getName());
}
Also used : PatchScript(com.google.gerrit.common.data.PatchScript) ArrayList(java.util.ArrayList) Edit(org.eclipse.jgit.diff.Edit)

Example 4 with Edit

use of org.eclipse.jgit.diff.Edit in project gerrit by GerritCodeReview.

the class PatchListEntry method writeTo.

void writeTo(OutputStream out) throws IOException {
    writeEnum(out, changeType);
    writeEnum(out, patchType);
    writeString(out, oldName);
    writeString(out, newName);
    writeBytes(out, header);
    writeVarInt32(out, insertions);
    writeVarInt32(out, deletions);
    writeFixInt64(out, size);
    writeFixInt64(out, sizeDelta);
    writeVarInt32(out, edits.size());
    for (final Edit e : edits) {
        writeVarInt32(out, e.getBeginA());
        writeVarInt32(out, e.getEndA());
        writeVarInt32(out, e.getBeginB());
        writeVarInt32(out, e.getEndB());
    }
}
Also used : Edit(org.eclipse.jgit.diff.Edit)

Example 5 with Edit

use of org.eclipse.jgit.diff.Edit in project gerrit by GerritCodeReview.

the class EditList method combineA.

private boolean combineA(final int i) {
    final Edit s = edits.get(i);
    final Edit e = edits.get(i - 1);
    // + 1 to prevent '... skipping 1 common line ...' messages.
    return s.getBeginA() - e.getEndA() <= 2 * context + 1;
}
Also used : Edit(org.eclipse.jgit.diff.Edit)

Aggregations

Edit (org.eclipse.jgit.diff.Edit)142 Test (org.junit.Test)117 FixResult (com.google.gerrit.server.fixes.FixCalculator.FixResult)112 ReplaceEdit (com.google.gerrit.jgit.diff.ReplaceEdit)9 ArrayList (java.util.ArrayList)5 RawText (org.eclipse.jgit.diff.RawText)5 Range (com.google.gerrit.entities.Comment.Range)4 FixReplacement (com.google.gerrit.entities.FixReplacement)4 Text (com.google.gerrit.server.patch.Text)4 EditList (org.eclipse.jgit.diff.EditList)4 PatchScript (com.google.gerrit.common.data.PatchScript)3 TaggedEdit (com.google.gerrit.server.patch.filediff.TaggedEdit)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 DiffFormatter (org.eclipse.jgit.diff.DiffFormatter)3 ReplaceEdit (org.eclipse.jgit.diff.ReplaceEdit)3 AbbreviatedObjectId (org.eclipse.jgit.lib.AbbreviatedObjectId)3 ObjectReader (org.eclipse.jgit.lib.ObjectReader)3 RevWalk (org.eclipse.jgit.revwalk.RevWalk)3 DiffPreferencesInfo (com.google.gerrit.extensions.client.DiffPreferencesInfo)2 SparseFileContent (com.google.gerrit.prettify.common.SparseFileContent)2