mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
diff: remove FineLineFragment
* move inner fragments into LineFragment * remove duplicated logic
This commit is contained in:
+54
-130
@@ -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();
|
||||
}
|
||||
-59
@@ -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();
|
||||
}
|
||||
|
||||
+47
-20
@@ -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);
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -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>() {
|
||||
|
||||
+5
-10
@@ -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));
|
||||
|
||||
+9
-7
@@ -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);
|
||||
}
|
||||
|
||||
+11
-14
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+9
-5
@@ -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() {
|
||||
|
||||
+28
-8
@@ -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;
|
||||
}
|
||||
|
||||
+11
-12
@@ -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();
|
||||
|
||||
+9
-13
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -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);
|
||||
|
||||
+1
-1
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user