Search in sources :

Example 1 with FairDiffIterable

use of com.intellij.diff.comparison.iterables.FairDiffIterable in project intellij-community by JetBrains.

the class RangesBuilder method createRangesSmart.

@NotNull
private static List<Range> createRangesSmart(@NotNull List<String> current, @NotNull List<String> vcs, int currentShift, int vcsShift) throws FilesTooBigForDiffException {
    FairDiffIterable iwIterable = ByLine.compare(vcs, current, ComparisonPolicy.IGNORE_WHITESPACES, DumbProgressIndicator.INSTANCE);
    RangeBuilder rangeBuilder = new RangeBuilder(current, vcs, currentShift, vcsShift);
    for (com.intellij.diff.util.Range range : iwIterable.iterateUnchanged()) {
        int count = range.end1 - range.start1;
        for (int i = 0; i < count; i++) {
            int vcsIndex = range.start1 + i;
            int currentIndex = range.start2 + i;
            if (vcs.get(vcsIndex).equals(current.get(currentIndex))) {
                rangeBuilder.markEqual(vcsIndex, currentIndex);
            }
        }
    }
    return rangeBuilder.finish();
}
Also used : FairDiffIterable(com.intellij.diff.comparison.iterables.FairDiffIterable) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with FairDiffIterable

use of com.intellij.diff.comparison.iterables.FairDiffIterable in project intellij-community by JetBrains.

the class ComparisonManagerImpl method compareLinesWithIgnoredRanges.

/**
   * Compare two texts by-line and then compare changed fragments by-word
   */
@NotNull
public List<LineFragment> compareLinesWithIgnoredRanges(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull List<TextRange> ignoredRanges1, @NotNull List<TextRange> ignoredRanges2, boolean innerFragments, @NotNull ProgressIndicator indicator) throws DiffTooBigException {
    BitSet ignored1 = collectIgnoredRanges(ignoredRanges1);
    BitSet ignored2 = collectIgnoredRanges(ignoredRanges2);
    List<Line> lines1 = getLines(text1);
    List<Line> lines2 = getLines(text2);
    List<CharSequence> lineTexts1 = ContainerUtil.map(lines1, line -> line.getNotIgnoredContent(ignored1));
    List<CharSequence> lineTexts2 = ContainerUtil.map(lines2, line -> line.getNotIgnoredContent(ignored2));
    FairDiffIterable iterable = ByLine.compare(lineTexts1, lineTexts2, ComparisonPolicy.DEFAULT, indicator);
    FairDiffIterable correctedIterable = correctIgnoredRangesSecondStep(iterable, lines1, lines2, ignored1, ignored2);
    List<LineFragment> lineFragments = convertIntoLineFragments(lines1, lines2, correctedIterable);
    if (innerFragments) {
        lineFragments = createInnerFragments(lineFragments, text1, text2, ComparisonPolicy.DEFAULT, indicator);
    }
    return ContainerUtil.mapNotNull(lineFragments, fragment -> {
        return trimIgnoredChanges(fragment, lines1, lines2, ignored1, ignored2);
    });
}
Also used : BitSet(java.util.BitSet) FairDiffIterable(com.intellij.diff.comparison.iterables.FairDiffIterable) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with FairDiffIterable

use of com.intellij.diff.comparison.iterables.FairDiffIterable in project intellij-community by JetBrains.

the class ByLine method doCompare.

@NotNull
static List<MergeRange> doCompare(@NotNull List<Line> lines1, @NotNull List<Line> lines2, @NotNull List<Line> lines3, @NotNull ComparisonPolicy policy, @NotNull ProgressIndicator indicator) {
    indicator.checkCanceled();
    List<Line> iwLines1 = convertMode(lines1, IGNORE_WHITESPACES);
    List<Line> iwLines2 = convertMode(lines2, IGNORE_WHITESPACES);
    List<Line> iwLines3 = convertMode(lines3, IGNORE_WHITESPACES);
    FairDiffIterable iwChanges1 = compareSmart(iwLines2, iwLines1, indicator);
    iwChanges1 = optimizeLineChunks(lines2, lines1, iwChanges1, indicator);
    FairDiffIterable iterable1 = correctChangesSecondStep(lines2, lines1, iwChanges1);
    FairDiffIterable iwChanges2 = compareSmart(iwLines2, iwLines3, indicator);
    iwChanges2 = optimizeLineChunks(lines2, lines3, iwChanges2, indicator);
    FairDiffIterable iterable2 = correctChangesSecondStep(lines2, lines3, iwChanges2);
    return ComparisonMergeUtil.buildFair(iterable1, iterable2, indicator);
}
Also used : FairDiffIterable(com.intellij.diff.comparison.iterables.FairDiffIterable) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with FairDiffIterable

use of com.intellij.diff.comparison.iterables.FairDiffIterable in project intellij-community by JetBrains.

the class ByLine method compareSmart.

/*
   * Compare lines in two steps:
   *  - compare ignoring "unimportant" lines
   *  - correct changes (compare all lines gaps between matched chunks)
   */
@NotNull
private static FairDiffIterable compareSmart(@NotNull List<Line> lines1, @NotNull List<Line> lines2, @NotNull ProgressIndicator indicator) {
    int threshold = ComparisonUtil.getUnimportantLineCharCount();
    if (threshold == 0)
        return diff(lines1, lines2, indicator);
    Pair<List<Line>, TIntArrayList> bigLines1 = getBigLines(lines1, threshold);
    Pair<List<Line>, TIntArrayList> bigLines2 = getBigLines(lines2, threshold);
    FairDiffIterable changes = diff(bigLines1.first, bigLines2.first, indicator);
    return new ChangeCorrector.SmartLineChangeCorrector(bigLines1.second, bigLines2.second, lines1, lines2, changes, indicator).build();
}
Also used : ArrayList(java.util.ArrayList) List(java.util.List) TIntArrayList(gnu.trove.TIntArrayList) FairDiffIterable(com.intellij.diff.comparison.iterables.FairDiffIterable) TIntArrayList(gnu.trove.TIntArrayList) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with FairDiffIterable

use of com.intellij.diff.comparison.iterables.FairDiffIterable in project intellij-community by JetBrains.

the class ByWord method compareAndSplit.

@NotNull
public static List<LineBlock> compareAndSplit(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull ComparisonPolicy policy, @NotNull ProgressIndicator indicator) {
    indicator.checkCanceled();
    // TODO: figure out, what do we exactly want from 'Split' logic
    // -- it is used for trimming of ignored blocks. So we want whitespace-only leading/trailing lines to be separate block.
    // -- old approach: split by matched '\n's
    // TODO: other approach could lead to better results:
    // * Compare words-only
    // * prefer big chunks
    // -- here we can try to minimize number of matched pairs 'pair[i]' and 'pair[i+1]' such that
    //    containsNewline(pair[i].left .. pair[i+1].left) XOR containsNewline(pair[i].right .. pair[i+1].right) == true
    //    ex: "A X C" - "A Y C \n M C" - do not match with last 'C'
    //    ex: "A \n" - "A B \n \n" - do not match with last '\n'
    //    Try some greedy approach ?
    // * split into blocks
    // -- squash blocks with too small unchanged words count (1 matched word out of 40 - is a bad reason to create new block)
    // * match adjustment punctuation
    // * match adjustment whitespaces ('\n' are matched here)
    List<InlineChunk> words1 = getInlineChunks(text1);
    List<InlineChunk> words2 = getInlineChunks(text2);
    FairDiffIterable wordChanges = diff(words1, words2, indicator);
    wordChanges = optimizeWordChunks(text1, text2, words1, words2, wordChanges, indicator);
    List<WordBlock> wordBlocks = new LineFragmentSplitter(text1, text2, words1, words2, wordChanges, indicator).run();
    List<LineBlock> lineBlocks = new ArrayList<>(wordBlocks.size());
    for (WordBlock block : wordBlocks) {
        Range offsets = block.offsets;
        Range words = block.words;
        CharSequence subtext1 = text1.subSequence(offsets.start1, offsets.end1);
        CharSequence subtext2 = text2.subSequence(offsets.start2, offsets.end2);
        List<InlineChunk> subwords1 = words1.subList(words.start1, words.end1);
        List<InlineChunk> subwords2 = words2.subList(words.start2, words.end2);
        FairDiffIterable subiterable = fair(subiterable(wordChanges, words.start1, words.end1, words.start2, words.end2));
        FairDiffIterable delimitersIterable = matchAdjustmentDelimiters(subtext1, subtext2, subwords1, subwords2, subiterable, offsets.start1, offsets.start2, indicator);
        DiffIterable iterable = matchAdjustmentWhitespaces(subtext1, subtext2, delimitersIterable, policy, indicator);
        List<DiffFragment> fragments = convertIntoDiffFragments(iterable);
        int newlines1 = countNewlines(subwords1);
        int newlines2 = countNewlines(subwords2);
        lineBlocks.add(new LineBlock(fragments, offsets, newlines1, newlines2));
    }
    return lineBlocks;
}
Also used : WordBlock(com.intellij.diff.comparison.LineFragmentSplitter.WordBlock) ArrayList(java.util.ArrayList) MergingCharSequence(com.intellij.util.text.MergingCharSequence) FairDiffIterable(com.intellij.diff.comparison.iterables.FairDiffIterable) MergeRange(com.intellij.diff.util.MergeRange) Range(com.intellij.diff.util.Range) FairDiffIterable(com.intellij.diff.comparison.iterables.FairDiffIterable) DiffIterable(com.intellij.diff.comparison.iterables.DiffIterable) DiffFragment(com.intellij.diff.fragments.DiffFragment) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

FairDiffIterable (com.intellij.diff.comparison.iterables.FairDiffIterable)14 NotNull (org.jetbrains.annotations.NotNull)14 ArrayList (java.util.ArrayList)4 DiffIterable (com.intellij.diff.comparison.iterables.DiffIterable)2 MergeRange (com.intellij.diff.util.MergeRange)2 Range (com.intellij.diff.util.Range)2 MergingCharSequence (com.intellij.util.text.MergingCharSequence)2 List (java.util.List)2 DiffTooBigException (com.intellij.diff.comparison.DiffTooBigException)1 WordBlock (com.intellij.diff.comparison.LineFragmentSplitter.WordBlock)1 DiffFragment (com.intellij.diff.fragments.DiffFragment)1 DiffUtil (com.intellij.diff.util.DiffUtil)1 InnerRange (com.intellij.openapi.vcs.ex.Range.InnerRange)1 TIntArrayList (gnu.trove.TIntArrayList)1 BitSet (java.util.BitSet)1