diff: remove FineLineFragment

* move inner fragments into LineFragment
* remove duplicated logic
This commit is contained in:
Aleksey Pivovarov
2015-02-03 20:17:22 +03:00
parent cd8e3d74b3
commit d910869bd8
17 changed files with 241 additions and 422 deletions
@@ -18,7 +18,10 @@ package com.intellij.openapi.util.diff.comparison;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.diff.comparison.iterables.DiffIterableUtil.Range;
import com.intellij.openapi.util.diff.fragments.*;
import com.intellij.openapi.util.diff.fragments.DiffFragment;
import com.intellij.openapi.util.diff.fragments.DiffFragmentImpl;
import com.intellij.openapi.util.diff.fragments.LineFragment;
import com.intellij.openapi.util.diff.fragments.LineFragmentImpl;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
@@ -54,21 +57,21 @@ public class ComparisonUtil {
}
@NotNull
public static List<FineLineFragment> compareFineLines(@NotNull CharSequence text1,
@NotNull CharSequence text2,
@NotNull ComparisonPolicy policy,
@NotNull ProgressIndicator indicator) {
public static List<LineFragment> compareLinesInner(@NotNull CharSequence text1,
@NotNull CharSequence text2,
@NotNull ComparisonPolicy policy,
@NotNull ProgressIndicator indicator) {
List<LineFragment> fragments = compareLines(text1, text2, policy, indicator);
return compareFineLines(text1, text2, fragments, policy, indicator);
return compareLinesInner(text1, text2, fragments, policy, indicator);
}
@NotNull
public static List<FineLineFragment> compareFineLines(@NotNull CharSequence text1,
@NotNull CharSequence text2,
@NotNull List<? extends LineFragment> lineFragments,
@NotNull ComparisonPolicy policy,
@NotNull ProgressIndicator indicator) {
List<FineLineFragment> fineFragments = new ArrayList<FineLineFragment>(lineFragments.size());
public static List<LineFragment> compareLinesInner(@NotNull CharSequence text1,
@NotNull CharSequence text2,
@NotNull List<LineFragment> lineFragments,
@NotNull ComparisonPolicy policy,
@NotNull ProgressIndicator indicator) {
List<LineFragment> fineFragments = new ArrayList<LineFragment>(lineFragments.size());
int tooBigChunksCount = 0;
for (LineFragment fragment : lineFragments) {
@@ -78,16 +81,16 @@ public class ComparisonUtil {
if (fragment.getStartLine1() == fragment.getEndLine1() ||
fragment.getStartLine2() == fragment.getEndLine2()) { // Do not try to build fine blocks after few fails)
if (isEquals(subSequence1, subSequence2, policy)) {
fineFragments.add(new FineLineFragmentImpl(fragment, Collections.<DiffFragment>emptyList()));
fineFragments.add(new LineFragmentImpl(fragment, Collections.<DiffFragment>emptyList()));
}
else {
fineFragments.add(new FineLineFragmentImpl(fragment, null));
fineFragments.add(new LineFragmentImpl(fragment, null));
}
continue;
}
if (tooBigChunksCount >= 3) { // Do not try to build fine blocks after few fails)
fineFragments.add(new FineLineFragmentImpl(fragment, null));
fineFragments.add(new LineFragmentImpl(fragment, null));
continue;
}
@@ -109,17 +112,17 @@ public class ComparisonUtil {
int currentEndLine1 = i != lineBlocks.size() - 1 ? currentStartLine1 + block.newlines1 : fragment.getEndLine1();
int currentEndLine2 = i != lineBlocks.size() - 1 ? currentStartLine2 + block.newlines2 : fragment.getEndLine2();
fineFragments.add(new FineLineFragmentImpl(currentStartLine1, currentEndLine1, currentStartLine2, currentEndLine2,
offsets.start1 + startOffset1, offsets.end1 + startOffset1,
offsets.start2 + startOffset2, offsets.end2 + startOffset2,
block.fragments));
fineFragments.add(new LineFragmentImpl(currentStartLine1, currentEndLine1, currentStartLine2, currentEndLine2,
offsets.start1 + startOffset1, offsets.end1 + startOffset1,
offsets.start2 + startOffset2, offsets.end2 + startOffset2,
block.fragments));
currentStartLine1 = currentEndLine1;
currentStartLine2 = currentEndLine2;
}
}
catch (DiffTooBigException e) {
fineFragments.add(new FineLineFragmentImpl(fragment, null));
fineFragments.add(new LineFragmentImpl(fragment, null));
tooBigChunksCount++;
}
}
@@ -168,13 +171,13 @@ public class ComparisonUtil {
//
@NotNull
public static List<? extends LineFragment> squash(@NotNull final List<? extends LineFragment> oldFragments) {
public static List<LineFragment> squash(@NotNull List<LineFragment> oldFragments) {
if (oldFragments.isEmpty()) return oldFragments;
final List<LineFragment> newFragments = new ArrayList<LineFragment>();
processAdjoining(oldFragments, new Consumer<List<? extends LineFragment>>() {
processAdjoining(oldFragments, new Consumer<List<LineFragment>>() {
@Override
public void consume(List<? extends LineFragment> fragments) {
public void consume(List<LineFragment> fragments) {
newFragments.add(doSquash(fragments));
}
});
@@ -182,57 +185,25 @@ public class ComparisonUtil {
}
@NotNull
public static List<? extends FineLineFragment> squashFine(@NotNull List<? extends FineLineFragment> oldFragments) {
if (oldFragments.isEmpty()) return oldFragments;
final List<FineLineFragment> newFragments = new ArrayList<FineLineFragment>();
processAdjoining(oldFragments, new Consumer<List<? extends FineLineFragment>>() {
@Override
public void consume(List<? extends FineLineFragment> fragments) {
newFragments.add(doSquashFine(fragments));
}
});
return newFragments;
}
@NotNull
public static List<? extends LineFragment> processBlocks(@NotNull List<? extends LineFragment> oldFragments,
@NotNull final CharSequence text1, @NotNull final CharSequence text2,
@NotNull final ComparisonPolicy policy,
final boolean squash, final boolean trim) {
public static List<LineFragment> processBlocks(@NotNull List<LineFragment> oldFragments,
@NotNull final CharSequence text1, @NotNull final CharSequence text2,
@NotNull final ComparisonPolicy policy,
final boolean squash, final boolean trim) {
if (!squash && !trim) return oldFragments;
if (oldFragments.isEmpty()) return oldFragments;
final List<LineFragment> newFragments = new ArrayList<LineFragment>();
processAdjoining(oldFragments, new Consumer<List<? extends LineFragment>>() {
processAdjoining(oldFragments, new Consumer<List<LineFragment>>() {
@Override
public void consume(List<? extends LineFragment> fragments) {
public void consume(List<LineFragment> fragments) {
newFragments.addAll(processAdjoining(fragments, text1, text2, policy, squash, trim));
}
});
return newFragments;
}
@NotNull
public static List<? extends FineLineFragment> processBlocksFine(@NotNull List<? extends FineLineFragment> oldFragments,
@NotNull final CharSequence text1, @NotNull final CharSequence text2,
@NotNull final ComparisonPolicy policy,
final boolean squash, final boolean trim) {
if (!squash && !trim) return oldFragments;
if (oldFragments.isEmpty()) return oldFragments;
final List<FineLineFragment> newFragments = new ArrayList<FineLineFragment>();
processAdjoining(oldFragments, new Consumer<List<? extends FineLineFragment>>() {
@Override
public void consume(List<? extends FineLineFragment> fragments) {
newFragments.addAll(processAdjoiningFine(fragments, text1, text2, policy, squash, trim));
}
});
return newFragments;
}
private static <T extends LineFragment> void processAdjoining(@NotNull List<? extends T> oldFragments,
@NotNull Consumer<List<? extends T>> consumer) {
private static void processAdjoining(@NotNull List<LineFragment> oldFragments,
@NotNull Consumer<List<LineFragment>> consumer) {
int startIndex = 0;
for (int i = 1; i < oldFragments.size(); i++) {
if (!isAdjoining(oldFragments.get(i - 1), oldFragments.get(i))) {
@@ -246,9 +217,9 @@ public class ComparisonUtil {
}
@NotNull
private static List<? extends LineFragment> processAdjoining(@NotNull List<? extends LineFragment> fragments,
@NotNull CharSequence text1, @NotNull CharSequence text2,
@NotNull ComparisonPolicy policy, boolean squash, boolean trim) {
private static List<LineFragment> processAdjoining(@NotNull List<LineFragment> fragments,
@NotNull CharSequence text1, @NotNull CharSequence text2,
@NotNull ComparisonPolicy policy, boolean squash, boolean trim) {
int start = 0;
int end = fragments.size();
@@ -259,7 +230,10 @@ public class ComparisonUtil {
CharSequenceSubSequence sequence1 = new CharSequenceSubSequence(text1, fragment.getStartOffset1(), fragment.getEndOffset1());
CharSequenceSubSequence sequence2 = new CharSequenceSubSequence(text2, fragment.getStartOffset2(), fragment.getEndOffset2());
if (!StringUtil.equalsIgnoreWhitespaces(sequence1, sequence2)) break;
if ((fragment.getInnerFragments() == null || !fragment.getInnerFragments().isEmpty()) &&
!StringUtil.equalsIgnoreWhitespaces(sequence1, sequence2)) {
break;
}
start++;
}
while (start < end) {
@@ -267,7 +241,10 @@ public class ComparisonUtil {
CharSequenceSubSequence sequence1 = new CharSequenceSubSequence(text1, fragment.getStartOffset1(), fragment.getEndOffset1());
CharSequenceSubSequence sequence2 = new CharSequenceSubSequence(text2, fragment.getStartOffset2(), fragment.getEndOffset2());
if (!StringUtil.equalsIgnoreWhitespaces(sequence1, sequence2)) break;
if ((fragment.getInnerFragments() == null || !fragment.getInnerFragments().isEmpty()) &&
!StringUtil.equalsIgnoreWhitespaces(sequence1, sequence2)) {
break;
}
end--;
}
}
@@ -280,60 +257,7 @@ public class ComparisonUtil {
}
@NotNull
private static List<? extends FineLineFragment> processAdjoiningFine(@NotNull List<? extends FineLineFragment> fragments,
@NotNull CharSequence text1, @NotNull CharSequence text2,
@NotNull ComparisonPolicy policy, boolean squash, boolean trim) {
int start = 0;
int end = fragments.size();
if (trim && policy == ComparisonPolicy.IGNORE_WHITESPACES) {
while (start < end) {
FineLineFragment fragment = fragments.get(start);
CharSequenceSubSequence sequence1 = new CharSequenceSubSequence(text1, fragment.getStartOffset1(), fragment.getEndOffset1());
CharSequenceSubSequence sequence2 = new CharSequenceSubSequence(text2, fragment.getStartOffset2(), fragment.getEndOffset2());
if ((fragment.getFineFragments() == null || !fragment.getFineFragments().isEmpty()) &&
!StringUtil.equalsIgnoreWhitespaces(sequence1, sequence2)) {
break;
}
start++;
}
while (start < end) {
FineLineFragment fragment = fragments.get(end - 1);
CharSequenceSubSequence sequence1 = new CharSequenceSubSequence(text1, fragment.getStartOffset1(), fragment.getEndOffset1());
CharSequenceSubSequence sequence2 = new CharSequenceSubSequence(text2, fragment.getStartOffset2(), fragment.getEndOffset2());
if ((fragment.getFineFragments() == null || !fragment.getFineFragments().isEmpty()) &&
!StringUtil.equalsIgnoreWhitespaces(sequence1, sequence2)) {
break;
}
end--;
}
}
if (start == end) return Collections.emptyList();
if (squash) {
return Collections.singletonList(doSquashFine(fragments.subList(start, end)));
}
return fragments.subList(start, end);
}
@NotNull
private static LineFragment doSquash(@NotNull List<? extends LineFragment> oldFragments) {
assert !oldFragments.isEmpty();
if (oldFragments.size() == 1) return oldFragments.get(0);
LineFragment firstFragment = oldFragments.get(0);
LineFragment lastFragment = oldFragments.get(oldFragments.size() - 1);
return new LineFragmentImpl(firstFragment.getStartLine1(), lastFragment.getEndLine1(),
firstFragment.getStartLine2(), lastFragment.getEndLine2(),
firstFragment.getStartOffset1(), lastFragment.getEndOffset1(),
firstFragment.getStartOffset2(), lastFragment.getEndOffset2());
}
@NotNull
private static FineLineFragment doSquashFine(@NotNull List<? extends FineLineFragment> oldFragments) {
private static LineFragment doSquash(@NotNull List<LineFragment> oldFragments) {
assert !oldFragments.isEmpty();
if (oldFragments.size() == 1) return oldFragments.get(0);
@@ -341,7 +265,7 @@ public class ComparisonUtil {
LineFragment lastFragment = oldFragments.get(oldFragments.size() - 1);
List<DiffFragment> newInnerFragments = new ArrayList<DiffFragment>();
for (FineLineFragment fragment : oldFragments) {
for (LineFragment fragment : oldFragments) {
for (DiffFragment innerFragment : extractInnerFragments(fragment)) {
int shift1 = fragment.getStartOffset1() - firstFragment.getStartOffset1();
int shift2 = fragment.getStartOffset2() - firstFragment.getStartOffset2();
@@ -359,11 +283,11 @@ public class ComparisonUtil {
}
}
return new FineLineFragmentImpl(firstFragment.getStartLine1(), lastFragment.getEndLine1(),
firstFragment.getStartLine2(), lastFragment.getEndLine2(),
firstFragment.getStartOffset1(), lastFragment.getEndOffset1(),
firstFragment.getStartOffset2(), lastFragment.getEndOffset2(),
newInnerFragments);
return new LineFragmentImpl(firstFragment.getStartLine1(), lastFragment.getEndLine1(),
firstFragment.getStartLine2(), lastFragment.getEndLine2(),
firstFragment.getStartOffset1(), lastFragment.getEndOffset1(),
firstFragment.getStartOffset2(), lastFragment.getEndOffset2(),
newInnerFragments);
}
private static boolean isAdjoining(@NotNull LineFragment beforeFragment, @NotNull LineFragment afterFragment) {
@@ -388,8 +312,8 @@ public class ComparisonUtil {
}
@NotNull
private static List<? extends DiffFragment> extractInnerFragments(@NotNull FineLineFragment lineFragment) {
if (lineFragment.getFineFragments() != null) return lineFragment.getFineFragments();
private static List<? extends DiffFragment> extractInnerFragments(@NotNull LineFragment lineFragment) {
if (lineFragment.getInnerFragments() != null) return lineFragment.getInnerFragments();
int length1 = lineFragment.getEndOffset1() - lineFragment.getStartOffset1();
int length2 = lineFragment.getEndOffset2() - lineFragment.getStartOffset2();
@@ -1,25 +0,0 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.util.diff.fragments;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface FineLineFragment extends LineFragment {
@Nullable
List<DiffFragment> getFineFragments();
}
@@ -1,59 +0,0 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.util.diff.fragments;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class FineLineFragmentImpl extends LineFragmentImpl implements FineLineFragment {
@Nullable protected final List<DiffFragment> myFragments;
public FineLineFragmentImpl(@NotNull LineFragment fragment, @Nullable List<DiffFragment> fragments) {
super(fragment);
myFragments = dropWholeChangedFragments(fragments, myEndOffset1 - myStartOffset1, myEndOffset2 - myStartOffset2);
}
public FineLineFragmentImpl(int startLine1, int endLine1, int startLine2, int endLine2,
int startOffset1, int endOffset1, int startOffset2, int endOffset2,
@Nullable List<DiffFragment> fragments) {
super(startLine1, endLine1, startLine2, endLine2, startOffset1, endOffset1, startOffset2, endOffset2);
myFragments = dropWholeChangedFragments(fragments, endOffset1 - startOffset1, endOffset2 - startOffset2);
}
@Override
@Nullable
public List<DiffFragment> getFineFragments() {
return myFragments;
}
@Nullable
private static List<DiffFragment> dropWholeChangedFragments(@Nullable List<DiffFragment> fragments, int length1, int length2) {
if (fragments != null && fragments.size() == 1) {
DiffFragment diffFragment = fragments.get(0);
if (diffFragment.getStartOffset1() == 0 &&
diffFragment.getStartOffset2() == 0 &&
diffFragment.getEndOffset1() == length1 &&
diffFragment.getEndOffset2() == length2) {
return null;
}
}
return fragments;
}
}
@@ -15,6 +15,10 @@
*/
package com.intellij.openapi.util.diff.fragments;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface LineFragment extends DiffFragment {
int getStartLine1();
@@ -23,4 +27,10 @@ public interface LineFragment extends DiffFragment {
int getStartLine2();
int getEndLine2();
/*
* null - no inner similarities was found
*/
@Nullable
List<DiffFragment> getInnerFragments();
}
@@ -16,33 +16,39 @@
package com.intellij.openapi.util.diff.fragments;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class LineFragmentImpl implements LineFragment {
protected final int myStartLine1;
protected final int myEndLine1;
protected final int myStartLine2;
protected final int myEndLine2;
private final int myStartLine1;
private final int myEndLine1;
private final int myStartLine2;
private final int myEndLine2;
protected final int myStartOffset1;
protected final int myEndOffset1;
protected final int myStartOffset2;
protected final int myEndOffset2;
private final int myStartOffset1;
private final int myEndOffset1;
private final int myStartOffset2;
private final int myEndOffset2;
public LineFragmentImpl(@NotNull LineFragment fragment) {
this(
fragment.getStartLine1(),
fragment.getEndLine1(),
fragment.getStartLine2(),
fragment.getEndLine2(),
fragment.getStartOffset1(),
fragment.getEndOffset1(),
fragment.getStartOffset2(),
fragment.getEndOffset2()
);
}
@Nullable private final List<DiffFragment> myInnerFragments;
public LineFragmentImpl(int startLine1, int endLine1, int startLine2, int endLine2,
int startOffset1, int endOffset1, int startOffset2, int endOffset2) {
this(startLine1, endLine1, startLine2, endLine2,
startOffset1, endOffset1, startOffset2, endOffset2,
null);
}
public LineFragmentImpl(@NotNull LineFragment fragment, @Nullable List<DiffFragment> fragments) {
this(fragment.getStartLine1(), fragment.getEndLine1(), fragment.getStartLine2(), fragment.getEndLine2(),
fragment.getStartOffset1(), fragment.getEndOffset1(), fragment.getStartOffset2(), fragment.getEndOffset2(),
fragments);
}
public LineFragmentImpl(int startLine1, int endLine1, int startLine2, int endLine2,
int startOffset1, int endOffset1, int startOffset2, int endOffset2,
@Nullable List<DiffFragment> innerFragments) {
myStartLine1 = startLine1;
myEndLine1 = endLine1;
myStartLine2 = startLine2;
@@ -51,6 +57,8 @@ public class LineFragmentImpl implements LineFragment {
myEndOffset1 = endOffset1;
myStartOffset2 = startOffset2;
myEndOffset2 = endOffset2;
myInnerFragments = dropWholeChangedFragments(innerFragments, endOffset1 - startOffset1, endOffset2 - startOffset2);
}
@Override
@@ -92,4 +100,23 @@ public class LineFragmentImpl implements LineFragment {
public int getEndOffset2() {
return myEndOffset2;
}
@Nullable
public List<DiffFragment> getInnerFragments() {
return myInnerFragments;
}
@Nullable
private static List<DiffFragment> dropWholeChangedFragments(@Nullable List<DiffFragment> fragments, int length1, int length2) {
if (fragments != null && fragments.size() == 1) {
DiffFragment diffFragment = fragments.get(0);
if (diffFragment.getStartOffset1() == 0 &&
diffFragment.getStartOffset2() == 0 &&
diffFragment.getEndOffset1() == length1 &&
diffFragment.getEndOffset2() == length2) {
return null;
}
}
return fragments;
}
}
@@ -1,58 +0,0 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.util.diff.fragments;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class LineFragments {
@NotNull private final List<? extends LineFragment> myFragments;
private final boolean myFine;
public LineFragments(@NotNull List<? extends LineFragment> fragments, boolean isFine) {
myFragments = fragments;
myFine = isFine;
}
@NotNull
public List<? extends LineFragment> getFragments() {
return myFragments;
}
public List<? extends FineLineFragment> getFineFragments() {
//noinspection unchecked
return myFine ? (List<? extends FineLineFragment>)myFragments : null;
}
public boolean isFine() {
return myFine;
}
//
// Constructors
//
@NotNull
public static LineFragments create(@NotNull List<? extends LineFragment> fragments) {
return new LineFragments(fragments, false);
}
@NotNull
public static LineFragments createFine(@NotNull List<? extends FineLineFragment> fragments) {
return new LineFragments(fragments, true);
}
}
@@ -43,7 +43,7 @@ import com.intellij.openapi.util.diff.comparison.DiffTooBigException;
import com.intellij.openapi.util.diff.comparison.iterables.DiffIterableUtil.IntPair;
import com.intellij.openapi.util.diff.contents.DiffContent;
import com.intellij.openapi.util.diff.contents.DocumentContent;
import com.intellij.openapi.util.diff.fragments.LineFragments;
import com.intellij.openapi.util.diff.fragments.LineFragment;
import com.intellij.openapi.util.diff.requests.ContentDiffRequest;
import com.intellij.openapi.util.diff.requests.DiffRequest;
import com.intellij.openapi.util.diff.tools.util.DiffDataKeys;
@@ -54,9 +54,12 @@ import com.intellij.openapi.util.diff.tools.util.base.HighlightPolicy;
import com.intellij.openapi.util.diff.tools.util.base.IgnorePolicy;
import com.intellij.openapi.util.diff.tools.util.base.TextDiffViewerBase;
import com.intellij.openapi.util.diff.tools.util.twoside.TwosideTextDiffViewer;
import com.intellij.openapi.util.diff.util.*;
import com.intellij.openapi.util.diff.util.DiffUserDataKeys;
import com.intellij.openapi.util.diff.util.DiffUserDataKeys.ScrollToPolicy;
import com.intellij.openapi.util.diff.util.DiffUserDataKeysEx;
import com.intellij.openapi.util.diff.util.DiffUtil;
import com.intellij.openapi.util.diff.util.DiffUtil.DocumentData;
import com.intellij.openapi.util.diff.util.Side;
import com.intellij.ui.LightweightHint;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.MergingCharSequence;
@@ -258,7 +261,7 @@ class OnesideDiffViewer extends TextDiffViewerBase {
}
});
final LineFragments fragments = DiffUtil.compareWithCache(myRequest, documentData, getDiffConfig(), indicator);
final List<LineFragment> fragments = DiffUtil.compareWithCache(myRequest, documentData, getDiffConfig(), indicator);
indicator.checkCanceled();
TwosideDocumentData data = ApplicationManager.getApplication().runReadAction(new Computable<TwosideDocumentData>() {
@@ -19,9 +19,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.diff.comparison.iterables.DiffIterableUtil.IntPair;
import com.intellij.openapi.util.diff.fragments.DiffFragment;
import com.intellij.openapi.util.diff.fragments.FineLineFragment;
import com.intellij.openapi.util.diff.fragments.LineFragment;
import com.intellij.openapi.util.diff.fragments.LineFragments;
import com.intellij.openapi.util.diff.util.Side;
import org.jetbrains.annotations.NotNull;
@@ -30,7 +28,7 @@ import java.util.List;
// This class works incorrectly with non-fair differences (when chunk of matched lines has different length in left/right files)
class OnesideFragmentBuilder {
@NotNull private final LineFragments myFragments;
@NotNull private final List<LineFragment> myFragments;
@NotNull private final Document myDocument1;
@NotNull private final Document myDocument2;
private final boolean myInlineFragments;
@@ -42,7 +40,7 @@ class OnesideFragmentBuilder {
@NotNull private final LineNumberConvertor.Builder myConvertor = new LineNumberConvertor.Builder();
@NotNull private final List<IntPair> myChangedLines = new ArrayList<IntPair>();
public OnesideFragmentBuilder(@NotNull LineFragments fragments,
public OnesideFragmentBuilder(@NotNull List<LineFragment> fragments,
@NotNull Document document1,
@NotNull Document document2,
boolean inlineFragments,
@@ -61,13 +59,13 @@ class OnesideFragmentBuilder {
private int totalLines = 0;
public void exec() {
if (myFragments.getFragments().isEmpty()) {
if (myFragments.isEmpty()) {
myEqual = true;
appendTextMaster(0, 0, getLineCount(myDocument1) - 1, getLineCount(myDocument2) - 1);
return;
}
for (LineFragment fragment : myFragments.getFragments()) {
for (LineFragment fragment : myFragments) {
processEquals(fragment.getStartLine1() - 1, fragment.getStartLine2() - 1);
processChanged(fragment);
}
@@ -118,10 +116,7 @@ class OnesideFragmentBuilder {
linesAfter = totalLines;
List<DiffFragment> innerFragments = null;
if (myInlineFragments && fragment instanceof FineLineFragment) {
innerFragments = ((FineLineFragment)fragment).getFineFragments();
}
List<DiffFragment> innerFragments = myInlineFragments ? fragment.getInnerFragments() : null;
myBlocks.add(new ChangedBlock(blockStartOffset1, blockEndOffset1,
blockStartOffset2, blockEndOffset2,
linesBefore, linesAfter, innerFragments));
@@ -24,9 +24,11 @@ import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.SeparatorPlacement;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.diff.fragments.DiffFragment;
import com.intellij.openapi.util.diff.fragments.FineLineFragment;
import com.intellij.openapi.util.diff.fragments.LineFragment;
import com.intellij.openapi.util.diff.util.*;
import com.intellij.openapi.util.diff.util.DiffDrawUtil;
import com.intellij.openapi.util.diff.util.DiffUtil;
import com.intellij.openapi.util.diff.util.Side;
import com.intellij.openapi.util.diff.util.TextDiffType;
import org.intellij.lang.annotations.CalledWithWriteLock;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -36,7 +38,7 @@ import java.util.List;
class SimpleDiffChange {
@NotNull private final LineFragment myFragment;
@Nullable private final List<DiffFragment> myFineFragments;
@Nullable private final List<DiffFragment> myInnerFragments;
@Nullable private final EditorEx myEditor1;
@Nullable private final EditorEx myEditor2;
@@ -54,7 +56,7 @@ class SimpleDiffChange {
@Nullable EditorEx editor2,
boolean inlineHighlight) {
myFragment = fragment;
myFineFragments = inlineHighlight && fragment instanceof FineLineFragment ? ((FineLineFragment)fragment).getFineFragments() : null;
myInnerFragments = inlineHighlight ? fragment.getInnerFragments() : null;
myEditor1 = editor1;
myEditor2 = editor2;
@@ -65,7 +67,7 @@ class SimpleDiffChange {
public void installHighlighter() {
assert myHighlighters.isEmpty();
if (myFineFragments != null) {
if (myInnerFragments != null) {
doInstallHighlighterWithInner();
}
else {
@@ -92,12 +94,12 @@ class SimpleDiffChange {
}
private void doInstallHighlighterWithInner() {
assert myFineFragments != null;
assert myInnerFragments != null;
createHighlighter(Side.LEFT, true);
createHighlighter(Side.RIGHT, true);
for (DiffFragment fragment : myFineFragments) {
for (DiffFragment fragment : myInnerFragments) {
createInlineHighlighter(fragment, Side.LEFT);
createInlineHighlighter(fragment, Side.RIGHT);
}
@@ -43,14 +43,12 @@ import com.intellij.openapi.util.diff.comparison.DiffTooBigException;
import com.intellij.openapi.util.diff.contents.DocumentContent;
import com.intellij.openapi.util.diff.fragments.LineFragment;
import com.intellij.openapi.util.diff.fragments.LineFragmentImpl;
import com.intellij.openapi.util.diff.fragments.LineFragments;
import com.intellij.openapi.util.diff.requests.ContentDiffRequest;
import com.intellij.openapi.util.diff.requests.DiffRequest;
import com.intellij.openapi.util.diff.tools.util.*;
import com.intellij.openapi.util.diff.tools.util.FoldingModelSupport.SimpleFoldingModel;
import com.intellij.openapi.util.diff.tools.util.base.HighlightPolicy;
import com.intellij.openapi.util.diff.tools.util.twoside.TwosideTextDiffViewer;
import org.intellij.lang.annotations.CalledInAwt;
import com.intellij.openapi.util.diff.util.DiffDividerDrawUtil;
import com.intellij.openapi.util.diff.util.DiffUserDataKeys.ScrollToPolicy;
import com.intellij.openapi.util.diff.util.DiffUtil;
@@ -58,6 +56,7 @@ import com.intellij.openapi.util.diff.util.DiffUtil.DocumentData;
import com.intellij.openapi.util.diff.util.Side;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.LightweightHint;
import org.intellij.lang.annotations.CalledInAwt;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -178,9 +177,8 @@ class SimpleDiffViewer extends TwosideTextDiffViewer {
CompareData data = ApplicationManager.getApplication().runReadAction(new Computable<CompareData>() {
@Override
public CompareData compute() {
LineFragmentImpl fragment = new LineFragmentImpl(0, 0, 0, getLineCount(document),
0, 0, 0, document.getTextLength());
LineFragments fragments = LineFragments.create(Collections.singletonList(fragment));
List<LineFragment> fragments = Collections.<LineFragment>singletonList(new LineFragmentImpl(0, 0, 0, getLineCount(document),
0, 0, 0, document.getTextLength()));
return new CompareData(fragments, false, 0, document.getModificationStamp());
}
});
@@ -195,9 +193,8 @@ class SimpleDiffViewer extends TwosideTextDiffViewer {
CompareData data = ApplicationManager.getApplication().runReadAction(new Computable<CompareData>() {
@Override
public CompareData compute() {
LineFragmentImpl fragment = new LineFragmentImpl(0, getLineCount(document), 0, 0,
0, document.getTextLength(), 0, 0);
LineFragments fragments = LineFragments.create(Collections.singletonList(fragment));
List<LineFragment> fragments = Collections.<LineFragment>singletonList(new LineFragmentImpl(0, getLineCount(document), 0, 0,
0, document.getTextLength(), 0, 0));
return new CompareData(fragments, false, document.getModificationStamp(), 0);
}
});
@@ -218,12 +215,12 @@ class SimpleDiffViewer extends TwosideTextDiffViewer {
}
});
LineFragments lineFragments = null;
List<LineFragment> lineFragments = null;
if (getHighlightPolicy().isShouldCompare()) {
lineFragments = DiffUtil.compareWithCache(myRequest, data, getDiffConfig(), indicator);
}
boolean isEqualContents = (lineFragments == null || lineFragments.getFragments().isEmpty()) &&
boolean isEqualContents = (lineFragments == null || lineFragments.isEmpty()) &&
StringUtil.equals(document1.getCharsSequence(), document2.getCharsSequence());
return apply(new CompareData(lineFragments, isEqualContents, data.getStamp1(), data.getStamp2()));
@@ -282,7 +279,7 @@ class SimpleDiffViewer extends TwosideTextDiffViewer {
if (data.isEqualContent()) myPanel.addContentsEqualNotification();
if (data.getFragments() != null) {
for (LineFragment fragment : data.getFragments().getFragments()) {
for (LineFragment fragment : data.getFragments()) {
myDiffChanges.add(new SimpleDiffChange(fragment, myEditor1, myEditor2, getHighlightPolicy().isFineFragments()));
}
}
@@ -792,12 +789,12 @@ class SimpleDiffViewer extends TwosideTextDiffViewer {
}
private static class CompareData {
@Nullable private final LineFragments myFragments;
@Nullable private final List<LineFragment> myFragments;
private final boolean myEqualContent;
private final long myStamp1;
private final long myStamp2;
public CompareData(@Nullable LineFragments fragments, boolean equalContent, long stamp1, long stamp2) {
public CompareData(@Nullable List<LineFragment> fragments, boolean equalContent, long stamp1, long stamp2) {
myFragments = fragments;
myEqualContent = equalContent;
myStamp1 = stamp1;
@@ -805,7 +802,7 @@ class SimpleDiffViewer extends TwosideTextDiffViewer {
}
@Nullable
public LineFragments getFragments() {
public List<LineFragment> getFragments() {
return myFragments;
}
@@ -31,9 +31,11 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.util.diff.comparison.iterables.DiffIterableUtil.IntPair;
import com.intellij.openapi.util.diff.fragments.LineFragment;
import com.intellij.openapi.util.diff.fragments.LineFragments;
import com.intellij.openapi.util.diff.fragments.MergeLineFragment;
import com.intellij.openapi.util.diff.util.*;
import com.intellij.openapi.util.diff.util.DiffDividerDrawUtil;
import com.intellij.openapi.util.diff.util.DiffDrawUtil;
import com.intellij.openapi.util.diff.util.Side;
import com.intellij.openapi.util.diff.util.ThreeSide;
import com.intellij.openapi.util.text.StringUtil;
import gnu.trove.TIntFunction;
import org.jetbrains.annotations.NotNull;
@@ -116,10 +118,12 @@ public class FoldingModelSupport {
}
}
public void install(@Nullable LineFragments lineFragments, @NotNull UserDataHolder context, boolean defaultExpanded, final int range) {
if (lineFragments == null) return;
public void install(@Nullable final List<LineFragment> fragments,
@NotNull UserDataHolder context,
boolean defaultExpanded,
final int range) {
if (fragments == null) return;
if (range == -1) return;
final List<? extends LineFragment> fragments = lineFragments.getFragments();
final MyExpandSuggester suggester = new MyExpandSuggester(context.getUserData(CACHE_KEY), defaultExpanded);
invokeBatchOperation(new Runnable() {
@@ -16,25 +16,26 @@
package com.intellij.openapi.util.diff.tools.util;
import com.intellij.openapi.util.diff.comparison.ComparisonPolicy;
import com.intellij.openapi.util.diff.fragments.LineFragments;
import com.intellij.openapi.util.diff.fragments.LineFragment;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LineFragmentCache {
private final long myModificationStamp1;
private final long myModificationStamp2;
@NotNull private final Map<ComparisonPolicy, LineFragments> myFragments;
@NotNull private final Map<ComparisonPolicy, PolicyData> myFragments;
public LineFragmentCache(@NotNull LineFragmentCache cache) {
myModificationStamp1 = cache.myModificationStamp1;
myModificationStamp2 = cache.myModificationStamp2;
myFragments = new HashMap<ComparisonPolicy, LineFragments>(3);
for (Map.Entry<ComparisonPolicy, LineFragments> entry : cache.myFragments.entrySet()) {
myFragments = new HashMap<ComparisonPolicy, PolicyData>(3);
for (Map.Entry<ComparisonPolicy, PolicyData> entry : cache.myFragments.entrySet()) {
myFragments.put(entry.getKey(), entry.getValue());
}
}
@@ -43,7 +44,7 @@ public class LineFragmentCache {
long modificationStamp2) {
myModificationStamp1 = modificationStamp1;
myModificationStamp2 = modificationStamp2;
myFragments = new HashMap<ComparisonPolicy, LineFragments>(3);
myFragments = new HashMap<ComparisonPolicy, PolicyData>(3);
}
public long getStamp1() {
@@ -59,11 +60,30 @@ public class LineFragmentCache {
}
@Nullable
public LineFragments getFragments(@NotNull ComparisonPolicy policy) {
public PolicyData getData(@NotNull ComparisonPolicy policy) {
return myFragments.get(policy);
}
public void putFragments(@NotNull ComparisonPolicy policy, @NotNull LineFragments fragments) {
myFragments.put(policy, fragments);
public void putData(@NotNull ComparisonPolicy policy, @NotNull List<LineFragment> fragments, boolean isInnerFragments) {
myFragments.put(policy, new PolicyData(fragments, isInnerFragments));
}
public static class PolicyData {
@NotNull private final List<LineFragment> myFragments;
private final boolean myInnerFragments;
public PolicyData(@NotNull List<LineFragment> fragments, boolean innerFragments) {
myFragments = fragments;
myInnerFragments = innerFragments;
}
@NotNull
public List<LineFragment> getFragments() {
return myFragments;
}
public boolean isInnerFragments() {
return myInnerFragments;
}
}
}
@@ -49,12 +49,11 @@ import com.intellij.openapi.util.diff.contents.DiffContent;
import com.intellij.openapi.util.diff.contents.DocumentContent;
import com.intellij.openapi.util.diff.contents.EmptyContent;
import com.intellij.openapi.util.diff.fragments.DiffFragment;
import com.intellij.openapi.util.diff.fragments.FineLineFragment;
import com.intellij.openapi.util.diff.fragments.LineFragment;
import com.intellij.openapi.util.diff.fragments.LineFragments;
import com.intellij.openapi.util.diff.requests.ContentDiffRequest;
import com.intellij.openapi.util.diff.requests.DiffRequest;
import com.intellij.openapi.util.diff.tools.util.LineFragmentCache;
import com.intellij.openapi.util.diff.tools.util.LineFragmentCache.PolicyData;
import com.intellij.openapi.util.diff.tools.util.base.HighlightPolicy;
import com.intellij.openapi.util.diff.tools.util.base.IgnorePolicy;
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
@@ -425,83 +424,70 @@ public class DiffUtil {
//
@NotNull
public static LineFragments compareWithCache(@NotNull DiffRequest request,
@NotNull DocumentData data,
@NotNull DiffConfig config,
@NotNull ProgressIndicator indicator) {
public static List<LineFragment> compareWithCache(@NotNull DiffRequest request,
@NotNull DocumentData data,
@NotNull DiffConfig config,
@NotNull ProgressIndicator indicator) {
return compareWithCache(request, data.getText1(), data.getText2(), data.getStamp1(), data.getStamp2(), config, indicator);
}
@NotNull
public static LineFragments compareWithCache(@NotNull DiffRequest request,
@NotNull CharSequence text1,
@NotNull CharSequence text2,
long stamp1,
long stamp2,
@NotNull DiffConfig config,
@NotNull ProgressIndicator indicator) {
// TODO: check instanceOf LineFragments, keep some additional data inside ?
LineFragments lineFragments = doCompareWithCache(request, text1, text2, stamp1, stamp2, config, indicator);
public static List<LineFragment> compareWithCache(@NotNull DiffRequest request,
@NotNull CharSequence text1,
@NotNull CharSequence text2,
long stamp1,
long stamp2,
@NotNull DiffConfig config,
@NotNull ProgressIndicator indicator) {
List<LineFragment> fragments = doCompareWithCache(request, text1, text2, stamp1, stamp2, config, indicator);
indicator.checkCanceled();
if (lineFragments.isFine()) {
List<? extends FineLineFragment> fragments = lineFragments.getFineFragments();
fragments = ComparisonUtil.processBlocksFine(fragments, text1, text2, config.policy, config.squashFragments, config.trimFragments);
return LineFragments.createFine(fragments);
}
else {
List<? extends LineFragment> fragments = lineFragments.getFragments();
fragments = ComparisonUtil.processBlocks(fragments, text1, text2, config.policy, config.squashFragments, config.trimFragments);
return LineFragments.create(fragments);
}
return ComparisonUtil.processBlocks(fragments, text1, text2, config.policy, config.squashFragments, config.trimFragments);
}
@NotNull
private static LineFragments doCompareWithCache(@NotNull DiffRequest request,
@NotNull CharSequence text1,
@NotNull CharSequence text2,
long stamp1,
long stamp2,
@NotNull DiffConfig config,
@NotNull ProgressIndicator indicator) {
private static List<LineFragment> doCompareWithCache(@NotNull DiffRequest request,
@NotNull CharSequence text1,
@NotNull CharSequence text2,
long stamp1,
long stamp2,
@NotNull DiffConfig config,
@NotNull ProgressIndicator indicator) {
indicator.checkCanceled();
LineFragments lineFragments = getFromCache(request, config, stamp1, stamp2);
PolicyData cachedData = getFromCache(request, config, stamp1, stamp2);
LineFragments newLineFragments;
if (lineFragments != null) {
if (lineFragments.getFragments().isEmpty()) return lineFragments;
if (!config.fineFragments) return lineFragments;
if (lineFragments.isFine()) return lineFragments;
List<FineLineFragment> result = ComparisonUtil.compareFineLines(text1, text2, lineFragments.getFragments(), config.policy, indicator);
newLineFragments = LineFragments.createFine(result);
List<LineFragment> newFragments;
if (cachedData != null) {
if (cachedData.getFragments().isEmpty()) return cachedData.getFragments();
if (!config.innerFragments) return cachedData.getFragments();
if (cachedData.isInnerFragments()) return cachedData.getFragments();
newFragments = ComparisonUtil.compareLinesInner(text1, text2, cachedData.getFragments(), config.policy, indicator);
}
else {
if (config.fineFragments) {
List<FineLineFragment> result = ComparisonUtil.compareFineLines(text1, text2, config.policy, indicator);
newLineFragments = LineFragments.createFine(result);
if (config.innerFragments) {
newFragments = ComparisonUtil.compareLinesInner(text1, text2, config.policy, indicator);
}
else {
List<LineFragment> result = ComparisonUtil.compareLines(text1, text2, config.policy, indicator);
newLineFragments = LineFragments.create(result);
newFragments = ComparisonUtil.compareLines(text1, text2, config.policy, indicator);
}
}
indicator.checkCanceled();
putToCache(request, config, stamp1, stamp2, newLineFragments);
return newLineFragments;
putToCache(request, config, stamp1, stamp2, newFragments, config.innerFragments);
return newFragments;
}
@Nullable
public static LineFragments getFromCache(@NotNull DiffRequest request, @NotNull DiffConfig config, long stamp1, long stamp2) {
public static PolicyData getFromCache(@NotNull DiffRequest request, @NotNull DiffConfig config, long stamp1, long stamp2) {
LineFragmentCache cache = request.getUserData(DiffUserDataKeysEx.LINE_FRAGMENT_CACHE);
if (cache != null && cache.checkStamps(stamp1, stamp2)) {
return cache.getFragments(config.policy);
return cache.getData(config.policy);
}
return null;
}
public static void putToCache(@NotNull DiffRequest request, @NotNull DiffConfig config, long stamp1, long stamp2,
@NotNull LineFragments fragments) {
@NotNull List<LineFragment> fragments, boolean isInnerFragments) {
// We can't rely on monotonicity on modificationStamps, so we can't check if we actually compared freshest versions of documents
// Possible data races also could make cache outdated.
// But these cases shouldn't be often and won't break anything.
@@ -515,7 +501,7 @@ public class DiffUtil {
cache = new LineFragmentCache(oldCache);
}
cache.putFragments(config.policy, fragments);
cache.putData(config.policy, fragments, isInnerFragments);
request.putUserData(DiffUserDataKeysEx.LINE_FRAGMENT_CACHE, cache);
}
@@ -854,13 +840,13 @@ public class DiffUtil {
public static class DiffConfig {
@NotNull public final ComparisonPolicy policy;
public final boolean fineFragments;
public final boolean innerFragments;
public final boolean squashFragments;
public final boolean trimFragments;
public DiffConfig(@NotNull ComparisonPolicy policy, boolean fineFragments, boolean squashFragments, boolean trimFragments) {
public DiffConfig(@NotNull ComparisonPolicy policy, boolean innerFragments, boolean squashFragments, boolean trimFragments) {
this.policy = policy;
this.fineFragments = fineFragments;
this.innerFragments = innerFragments;
this.squashFragments = squashFragments;
this.trimFragments = trimFragments;
}
@@ -20,7 +20,6 @@ import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.progress.DumbProgressIndicator;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.diff.fragments.DiffFragment;
import com.intellij.openapi.util.diff.fragments.FineLineFragment;
import com.intellij.openapi.util.diff.fragments.LineFragment;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
@@ -80,7 +79,7 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
CharSequence sequence1 = text1.getCharsSequence();
CharSequence sequence2 = text2.getCharsSequence();
List<FineLineFragment> fragments = ComparisonUtil.compareFineLines(sequence1, sequence2, policy, INDICATOR);
List<LineFragment> fragments = ComparisonUtil.compareLinesInner(sequence1, sequence2, policy, INDICATOR);
debugData.set(fragments);
checkResultLine(text1, text2, fragments, policy, true);
@@ -97,10 +96,10 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
CharSequence sequence1 = text1.getCharsSequence();
CharSequence sequence2 = text2.getCharsSequence();
List<FineLineFragment> fragments = ComparisonUtil.compareFineLines(sequence1, sequence2, policy, INDICATOR);
List<LineFragment> fragments = ComparisonUtil.compareLinesInner(sequence1, sequence2, policy, INDICATOR);
debugData.set(fragments);
List<? extends FineLineFragment> squashedFragments = ComparisonUtil.squashFine(fragments);
List<LineFragment> squashedFragments = ComparisonUtil.squash(fragments);
debugData.set(new Object[]{fragments, squashedFragments});
checkResultLine(text1, text2, squashedFragments, policy, false);
@@ -117,10 +116,10 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
CharSequence sequence1 = text1.getCharsSequence();
CharSequence sequence2 = text2.getCharsSequence();
List<FineLineFragment> fragments = ComparisonUtil.compareFineLines(sequence1, sequence2, policy, INDICATOR);
List<LineFragment> fragments = ComparisonUtil.compareLinesInner(sequence1, sequence2, policy, INDICATOR);
debugData.set(fragments);
List<? extends FineLineFragment> processed = ComparisonUtil.processBlocksFine(fragments, sequence1, sequence2, policy, true, true);
List<LineFragment> processed = ComparisonUtil.processBlocks(fragments, sequence1, sequence2, policy, true, true);
debugData.set(new Object[]{fragments, processed});
checkResultLine(text1, text2, processed, policy, false);
@@ -181,17 +180,17 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
}
private static void checkResultLine(@NotNull Document text1, @NotNull Document text2,
@NotNull List<? extends FineLineFragment> fragments,
@NotNull List<LineFragment> fragments,
@NotNull ComparisonPolicy policy,
boolean allowNonSquashed) {
checkLineConsistency(text1, text2, fragments, allowNonSquashed);
for (FineLineFragment fragment : fragments) {
if (fragment.getFineFragments() != null) {
for (LineFragment fragment : fragments) {
if (fragment.getInnerFragments() != null) {
CharSequence sequence1 = subsequence(text1, fragment.getStartOffset1(), fragment.getEndOffset1());
CharSequence sequence2 = subsequence(text2, fragment.getStartOffset2(), fragment.getEndOffset2());
checkResultWord(sequence1, sequence2, fragment.getFineFragments(), policy);
checkResultWord(sequence1, sequence2, fragment.getInnerFragments(), policy);
}
}
@@ -215,12 +214,12 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
}
private static void checkLineConsistency(@NotNull Document text1, @NotNull Document text2,
@NotNull List<? extends FineLineFragment> fragments,
@NotNull List<LineFragment> fragments,
boolean allowNonSquashed) {
int last1 = -1;
int last2 = -1;
for (FineLineFragment fragment : fragments) {
for (LineFragment fragment : fragments) {
int startOffset1 = fragment.getStartOffset1();
int startOffset2 = fragment.getStartOffset2();
int endOffset1 = fragment.getEndOffset1();
@@ -20,7 +20,6 @@ import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.progress.DumbProgressIndicator;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.diff.fragments.DiffFragment;
import com.intellij.openapi.util.diff.fragments.FineLineFragment;
import com.intellij.openapi.util.diff.fragments.LineFragment;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.testFramework.UsefulTestCase;
@@ -70,12 +69,12 @@ public abstract class ComparisonUtilTestBase extends UsefulTestCase {
@Nullable Couple<BitSet> matchings,
@Nullable List<Change> expected,
@NotNull ComparisonPolicy policy) {
List<FineLineFragment> rawFragments = ComparisonUtil.compareFineLines(before.getCharsSequence(), after.getCharsSequence(), policy, INDICATOR);
List<? extends FineLineFragment> fragments = ComparisonUtil.squashFine(rawFragments);
List<LineFragment> rawFragments = ComparisonUtil.compareLinesInner(before.getCharsSequence(), after.getCharsSequence(), policy, INDICATOR);
List<LineFragment> fragments = ComparisonUtil.squash(rawFragments);
checkConsistencyWord(fragments, before, after, policy);
List<DiffFragment> diffFragments = fragments.get(0).getFineFragments();
List<DiffFragment> diffFragments = fragments.get(0).getInnerFragments();
assert diffFragments != null;
if (matchings != null) checkDiffMatching(diffFragments, before, after, matchings, policy);
@@ -98,19 +97,19 @@ public abstract class ComparisonUtilTestBase extends UsefulTestCase {
@Nullable Couple<BitSet> matchings,
@Nullable List<Change> expected,
@NotNull ComparisonPolicy policy) {
List<FineLineFragment> fragments = ComparisonUtil.compareFineLines(before.getCharsSequence(), after.getCharsSequence(), policy, INDICATOR);
List<LineFragment> fragments = ComparisonUtil.compareLinesInner(before.getCharsSequence(), after.getCharsSequence(), policy, INDICATOR);
checkConsistency(fragments, before, after, policy);
if (matchings != null) checkLineMatching(fragments, before, after, matchings, policy);
if (expected != null) checkLineChanges(fragments, before, after, expected, policy);
}
private static void checkConsistencyWord(@NotNull List<? extends FineLineFragment> fragments,
private static void checkConsistencyWord(@NotNull List<LineFragment> fragments,
@NotNull Document before,
@NotNull Document after,
@NotNull ComparisonPolicy policy) {
assertTrue(fragments.size() == 1);
FineLineFragment fragment = fragments.get(0);
List<DiffFragment> diffFragments = fragment.getFineFragments();
LineFragment fragment = fragments.get(0);
List<DiffFragment> diffFragments = fragment.getInnerFragments();
assertNotNull(diffFragments); // It could be null if there are no common words. We do not test such cases here.
assertTrue(fragment.getStartOffset1() == 0 &&
@@ -142,14 +141,11 @@ public abstract class ComparisonUtilTestBase extends UsefulTestCase {
assertTrue(lineFragment.getEndLine2() <= getLineCount(after));
checkLineOffsets(lineFragment, before, after, policy);
if (lineFragment.getInnerFragments() != null) checkConsistency(lineFragment.getInnerFragments(), before, after, policy);
} else {
assertTrue(fragment.getStartOffset1() != fragment.getEndOffset1() || fragment.getStartOffset2() != fragment.getEndOffset2());
}
if (fragment instanceof FineLineFragment) {
List<DiffFragment> fineFragments = ((FineLineFragment)fragment).getFineFragments();
if (fineFragments != null) checkConsistency(fineFragments, before, after, policy);
}
}
}
@@ -8,7 +8,6 @@ import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.diff.fragments.DiffFragment;
import com.intellij.openapi.util.diff.fragments.FineLineFragment;
import com.intellij.openapi.util.diff.fragments.LineFragment;
import com.intellij.openapi.util.diff.util.DiffDrawUtil;
import com.intellij.openapi.util.diff.util.DiffUtil;
@@ -349,7 +348,7 @@ public class PropertiesTableModel extends ListTableModel<PropertyDiffRecord> {
editor.getDocument().setText(text);
for (LineFragment fragment : record.getFragments()) {
List<DiffFragment> innerFragments = fragment instanceof FineLineFragment ? ((FineLineFragment)fragment).getFineFragments() : null;
List<DiffFragment> innerFragments = fragment.getInnerFragments();
int start = side.getStartOffset(fragment);
int end = side.getEndOffset(fragment);
@@ -358,7 +357,6 @@ public class PropertiesTableModel extends ListTableModel<PropertyDiffRecord> {
DiffDrawUtil.createHighlighter(editor, start, end, type, innerFragments != null);
if (innerFragments != null) {
for (DiffFragment innerFragment : innerFragments) {
int innerStart = side.getStartOffset(innerFragment);
int innerEnd = side.getEndOffset(innerFragment);
@@ -162,7 +162,7 @@ public class SvnPropertiesDiffViewer implements DiffViewer {
try {
if (words1 < MAX_ITEM_COUNT && words2 < MAX_ITEM_COUNT) {
return ComparisonUtil.squashFine(ComparisonUtil.compareFineLines(text1, text2, ComparisonPolicy.DEFAULT, INSTANCE));
return ComparisonUtil.squash(ComparisonUtil.compareLinesInner(text1, text2, ComparisonPolicy.DEFAULT, INSTANCE));
}
if (lines1 < MAX_ITEM_COUNT && lines2 < MAX_ITEM_COUNT) {
return ComparisonUtil.squash(ComparisonUtil.compareLines(text1, text2, ComparisonPolicy.DEFAULT, INSTANCE));