mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
VCS: diff for big files - throw exception if algorithm tries to allocate array bigger than 10000000 line status tracker and diff/merge shows notifications
This commit is contained in:
+22
-13
@@ -23,6 +23,7 @@ import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.impl.settings.DiffOptionsPanel;
|
||||
import com.intellij.openapi.diff.impl.settings.DiffPreviewPanel;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
@@ -59,6 +60,7 @@ import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
|
||||
import com.intellij.psi.search.scope.packageSet.PackageSet;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
@@ -90,6 +92,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
|
||||
private boolean myApplyCompleted = false;
|
||||
private boolean myDisposeCompleted = false;
|
||||
private final Disposable myDisposable = Disposer.newDisposable();
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.application.options.colors.ColorAndFontOptions");
|
||||
|
||||
public static ColorAndFontOptions getColorAndFontsInstance() {
|
||||
ColorAndFontOptions colorAndFontOptions = null;
|
||||
@@ -371,22 +374,28 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
|
||||
|
||||
private class DiffColorsPageFactory implements ColorAndFontPanelFactory {
|
||||
public NewColorAndFontPanel createPanel(ColorAndFontOptions options) {
|
||||
final DiffPreviewPanel diffPreviewPanel = new DiffPreviewPanel(myDisposable);
|
||||
diffPreviewPanel.setMergeRequest(null);
|
||||
final DiffOptionsPanel optionsPanel = new DiffOptionsPanel(options);
|
||||
|
||||
SchemesPanel schemesPanel = new SchemesPanel(options);
|
||||
PreviewPanel previewPanel;
|
||||
try {
|
||||
final DiffPreviewPanel diffPreviewPanel = new DiffPreviewPanel(myDisposable);
|
||||
diffPreviewPanel.setMergeRequest(null);
|
||||
schemesPanel.addListener(new ColorAndFontSettingsListener.Abstract(){
|
||||
@Override
|
||||
public void schemeChanged(final Object source) {
|
||||
diffPreviewPanel.setColorScheme(getSelectedScheme());
|
||||
optionsPanel.updateOptionsList();
|
||||
diffPreviewPanel.updateView();
|
||||
}
|
||||
} );
|
||||
previewPanel = diffPreviewPanel;
|
||||
}
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
LOG.info(e);
|
||||
previewPanel = new PreviewPanel.Empty();
|
||||
}
|
||||
|
||||
schemesPanel.addListener(new ColorAndFontSettingsListener.Abstract(){
|
||||
@Override
|
||||
public void schemeChanged(final Object source) {
|
||||
diffPreviewPanel.setColorScheme(getSelectedScheme());
|
||||
optionsPanel.updateOptionsList();
|
||||
diffPreviewPanel.updateView();
|
||||
}
|
||||
} );
|
||||
|
||||
return new NewColorAndFontPanel(schemesPanel, optionsPanel, diffPreviewPanel, DIFF_GROUP, null, null);
|
||||
return new NewColorAndFontPanel(schemesPanel, optionsPanel, previewPanel, DIFF_GROUP, null, null);
|
||||
}
|
||||
|
||||
public String getPanelDisplayName() {
|
||||
|
||||
@@ -59,6 +59,7 @@ import com.intellij.util.Function;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.diff.Diff;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import com.intellij.util.text.Matcher;
|
||||
import com.intellij.util.text.MatcherHolder;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
@@ -850,7 +851,13 @@ public abstract class ChooseByNameBase {
|
||||
|
||||
Object[] oldElements = myListModel.toArray();
|
||||
Object[] newElements = elements.toArray();
|
||||
Diff.Change change = Diff.buildChanges(oldElements, newElements);
|
||||
Diff.Change change = null;
|
||||
try {
|
||||
change = Diff.buildChanges(oldElements, newElements);
|
||||
}
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
// should not occur
|
||||
}
|
||||
|
||||
if (change == null) return; // Nothing changed
|
||||
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@ import com.intellij.openapi.editor.event.*;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.EventDispatcher;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -89,7 +90,7 @@ public class DiffPreviewPanel implements PreviewPanel {
|
||||
|
||||
}
|
||||
|
||||
public void setMergeRequest(Project project) {
|
||||
public void setMergeRequest(Project project) throws FilesTooBigForDiffException {
|
||||
getMergePanel().setDiffRequest(new SampleMerge(project));
|
||||
}
|
||||
|
||||
|
||||
+11
-6
@@ -48,6 +48,7 @@ import com.intellij.psi.search.searches.IndexPatternSearch;
|
||||
import com.intellij.util.PairConsumer;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -186,7 +187,7 @@ public class TodoCheckinHandlerWorker {
|
||||
myAcceptor.skipped(new Pair<FilePath, String>(myAfterFile, ourCannotLoadPreviousRevision));
|
||||
return;
|
||||
}
|
||||
ArrayList<LineFragment> lineFragments = getLineFragments(myBeforeContent, myAfterContent);
|
||||
ArrayList<LineFragment> lineFragments = getLineFragments(myAfterFile.getPath(), myBeforeContent, myAfterContent);
|
||||
for (Iterator<LineFragment> iterator = lineFragments.iterator(); iterator.hasNext(); ) {
|
||||
ProgressManager.checkCanceled();
|
||||
final LineFragment next = iterator.next();
|
||||
@@ -287,11 +288,15 @@ public class TodoCheckinHandlerWorker {
|
||||
return StringUtil.join(fragment.split("\\s"), " ");
|
||||
}
|
||||
|
||||
private static ArrayList<LineFragment> getLineFragments(String beforeContent, String afterContent) {
|
||||
DiffFragment[] woFormattingBlocks = DiffPolicy.LINES_WO_FORMATTING.buildFragments(beforeContent, afterContent);
|
||||
DiffFragment[] step1lineFragments =
|
||||
new DiffCorrection.TrueLineBlocks(ComparisonPolicy.IGNORE_SPACE).correctAndNormalize(woFormattingBlocks);
|
||||
return new DiffFragmentsProcessor().process(step1lineFragments);
|
||||
private static ArrayList<LineFragment> getLineFragments(final String fileName, String beforeContent, String afterContent) throws VcsException {
|
||||
try {
|
||||
DiffFragment[] woFormattingBlocks = DiffPolicy.LINES_WO_FORMATTING.buildFragments(beforeContent, afterContent);
|
||||
DiffFragment[] step1lineFragments =
|
||||
new DiffCorrection.TrueLineBlocks(ComparisonPolicy.IGNORE_SPACE).correctAndNormalize(woFormattingBlocks);
|
||||
return new DiffFragmentsProcessor().process(step1lineFragments);
|
||||
} catch (FilesTooBigForDiffException e) {
|
||||
throw new VcsException("File " + fileName + " is too big and there are too many changes to build a diff", e);
|
||||
}
|
||||
}
|
||||
|
||||
private final static String ourInvalidFile = "Invalid file (s)";
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import com.intellij.util.text.DateFormatUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -108,5 +109,5 @@ public abstract class Reverter {
|
||||
|
||||
protected abstract Revision getTargetRevision();
|
||||
|
||||
protected abstract void doRevert() throws IOException;
|
||||
protected abstract void doRevert() throws IOException, FilesTooBigForDiffException;
|
||||
}
|
||||
|
||||
+2
-1
@@ -26,6 +26,7 @@ import com.intellij.history.integration.ui.models.SelectionCalculator;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
@@ -65,7 +66,7 @@ public class SelectionReverter extends Reverter {
|
||||
return Collections.singletonList(file);
|
||||
}
|
||||
|
||||
protected void doRevert() throws IOException {
|
||||
protected void doRevert() throws IOException, FilesTooBigForDiffException {
|
||||
Block b = myCalculator.getSelectionFor(myLeftRevision, new Progress() {
|
||||
public void processed(int percentage) {
|
||||
// should be already processed.
|
||||
|
||||
+5
-4
@@ -22,6 +22,7 @@ import com.intellij.history.core.Content;
|
||||
import com.intellij.history.core.revisions.Revision;
|
||||
import com.intellij.history.core.tree.Entry;
|
||||
import com.intellij.history.integration.IdeaGateway;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -44,7 +45,7 @@ public class SelectionCalculator {
|
||||
myToLine = toLine;
|
||||
}
|
||||
|
||||
public boolean canCalculateFor(Revision r, Progress p) {
|
||||
public boolean canCalculateFor(Revision r, Progress p) throws FilesTooBigForDiffException {
|
||||
try {
|
||||
doGetSelectionFor(r, p);
|
||||
}
|
||||
@@ -54,16 +55,16 @@ public class SelectionCalculator {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Block getSelectionFor(Revision r, Progress p) {
|
||||
public Block getSelectionFor(Revision r, Progress p) throws FilesTooBigForDiffException {
|
||||
return doGetSelectionFor(r, p);
|
||||
}
|
||||
|
||||
private Block doGetSelectionFor(Revision r, Progress p) {
|
||||
private Block doGetSelectionFor(Revision r, Progress p) throws FilesTooBigForDiffException {
|
||||
int target = myRevisions.indexOf(r);
|
||||
return getSelectionFor(target, target + 1, p);
|
||||
}
|
||||
|
||||
private Block getSelectionFor(int revisionIndex, int totalRevisions, Progress p) {
|
||||
private Block getSelectionFor(int revisionIndex, int totalRevisions, Progress p) throws FilesTooBigForDiffException {
|
||||
Block cached = myCache.get(revisionIndex);
|
||||
if (cached != null) return cached;
|
||||
|
||||
|
||||
+19
-3
@@ -24,6 +24,7 @@ import com.intellij.openapi.diff.FragmentContent;
|
||||
import com.intellij.openapi.diff.SimpleContent;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
public class SelectionDifferenceModel extends FileDifferenceModel {
|
||||
private final SelectionCalculator myCalculator;
|
||||
@@ -60,12 +61,22 @@ public class SelectionDifferenceModel extends FileDifferenceModel {
|
||||
|
||||
@Override
|
||||
protected boolean isLeftContentAvailable(RevisionProcessingProgress p) {
|
||||
return myCalculator.canCalculateFor(myLeftRevision, p);
|
||||
try {
|
||||
return myCalculator.canCalculateFor(myLeftRevision, p);
|
||||
}
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRightContentAvailable(RevisionProcessingProgress p) {
|
||||
return myCalculator.canCalculateFor(myRightRevision, p);
|
||||
try {
|
||||
return myCalculator.canCalculateFor(myRightRevision, p);
|
||||
}
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -93,6 +104,11 @@ public class SelectionDifferenceModel extends FileDifferenceModel {
|
||||
}
|
||||
|
||||
private String getContentOf(Revision r, RevisionProcessingProgress p) {
|
||||
return myCalculator.getSelectionFor(r, p).getBlockContent();
|
||||
try {
|
||||
return myCalculator.getSelectionFor(r, p).getBlockContent();
|
||||
}
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-12
@@ -20,25 +20,22 @@ import com.intellij.diff.Block;
|
||||
import com.intellij.history.core.InMemoryLocalHistoryFacade;
|
||||
import com.intellij.history.core.LocalHistoryFacade;
|
||||
import com.intellij.history.core.LocalHistoryTestCase;
|
||||
import com.intellij.history.core.revisions.CurrentRevision;
|
||||
import com.intellij.history.core.revisions.Revision;
|
||||
import com.intellij.history.core.tree.RootEntry;
|
||||
import com.intellij.history.integration.IdeaGateway;
|
||||
|
||||
import static org.easymock.classextension.EasyMock.*;
|
||||
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.easymock.classextension.EasyMock.*;
|
||||
|
||||
public class SelectionCalculatorTest extends LocalHistoryTestCase {
|
||||
IdeaGateway gw = new MyIdeaGateway();
|
||||
LocalHistoryFacade vcs = new InMemoryLocalHistoryFacade();
|
||||
|
||||
@Test
|
||||
public void testSelectionWasNotChanged() {
|
||||
public void testSelectionWasNotChanged() throws FilesTooBigForDiffException {
|
||||
List<Revision> rr = createRevisions("abc\ndef\nghi", "abc1\ndef1\nghi1");
|
||||
SelectionCalculator c = new SelectionCalculator(gw, rr, 0, 2);
|
||||
|
||||
@@ -50,7 +47,7 @@ public class SelectionCalculatorTest extends LocalHistoryTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectionWasMoved() {
|
||||
public void testSelectionWasMoved() throws FilesTooBigForDiffException {
|
||||
List<Revision> rr = createRevisions("abc\ndef\nghi", "def\nghi");
|
||||
SelectionCalculator c = new SelectionCalculator(gw, rr, 0, 1);
|
||||
|
||||
@@ -62,7 +59,7 @@ public class SelectionCalculatorTest extends LocalHistoryTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectionForVeryOldRevisionTakenBackward() {
|
||||
public void testSelectionForVeryOldRevisionTakenBackward() throws FilesTooBigForDiffException {
|
||||
List<Revision> rr = createRevisions("ghi\nabc\ndef", "abc\nghi\ndef", "abc\ndef\nghi");
|
||||
SelectionCalculator c = new SelectionCalculator(gw, rr, 0, 1);
|
||||
|
||||
@@ -76,7 +73,7 @@ public class SelectionCalculatorTest extends LocalHistoryTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizingLineEnds() {
|
||||
public void testNormalizingLineEnds() throws FilesTooBigForDiffException {
|
||||
List<Revision> rr = createRevisions("abc\ndef\nghi", "abc\r\ndef\r\nghi");
|
||||
SelectionCalculator c = new SelectionCalculator(gw, rr, 0, 1);
|
||||
|
||||
@@ -88,7 +85,7 @@ public class SelectionCalculatorTest extends LocalHistoryTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgressOnGetSelection() {
|
||||
public void testProgressOnGetSelection() throws FilesTooBigForDiffException {
|
||||
List<Revision> rr = createRevisions("one", "two", "three", "four");
|
||||
SelectionCalculator c = new SelectionCalculator(gw, rr, 0, 0);
|
||||
|
||||
@@ -105,7 +102,7 @@ public class SelectionCalculatorTest extends LocalHistoryTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgressOnCanCalculate() {
|
||||
public void testProgressOnCanCalculate() throws FilesTooBigForDiffException {
|
||||
List<Revision> rr = createRevisions("one", "two");
|
||||
SelectionCalculator c = new SelectionCalculator(gw, rr, 0, 0);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingManager;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -115,7 +116,7 @@ public abstract class DiffElement<T> implements Disposable {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JComponent getDiffComponent(DiffElement element, Project project, Window parentWindow) {
|
||||
public JComponent getDiffComponent(DiffElement element, Project project, Window parentWindow) throws FilesTooBigForDiffException {
|
||||
disposeDiffComponent();
|
||||
|
||||
DiffRequest request;
|
||||
|
||||
@@ -26,4 +26,5 @@ public interface DiffPanel extends DiffViewer, Disposable {
|
||||
void setContents(DiffContent content1, DiffContent content2);
|
||||
void setRequestFocus(boolean requestFocus);
|
||||
boolean hasDifferences();
|
||||
void setTooBigFileErrorContents();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.ui.PopupHandler;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.diff.Diff;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -196,7 +197,13 @@ public class CustomizationUtil {
|
||||
private static void computeDiff(final ActionUrl[] defaultUserObjects,
|
||||
final ActionUrl[] currentUserObjects,
|
||||
final ArrayList<ActionUrl> actions) {
|
||||
Diff.Change change = Diff.buildChanges(defaultUserObjects, currentUserObjects);
|
||||
Diff.Change change = null;
|
||||
try {
|
||||
change = Diff.buildChanges(defaultUserObjects, currentUserObjects);
|
||||
}
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
while (change != null) {
|
||||
for (int i = 0; i < change.deleted; i++) {
|
||||
final int idx = change.line0 + i;
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
package com.intellij.openapi.diff.ex;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.impl.DiffSideView;
|
||||
import com.intellij.openapi.diff.impl.DiffPanelImpl;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.diff.impl.DiffSideView;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.ui.DialogWrapperDialog;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.DialogWrapperDialog;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
|
||||
@@ -46,13 +46,16 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.EditorNotificationPanel;
|
||||
import com.intellij.ui.PopupHandler;
|
||||
import com.intellij.util.containers.CacheOneStepIterator;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -92,6 +95,8 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
|
||||
private boolean myDisposed = false;
|
||||
private final GenericDataProvider myDataProvider;
|
||||
private Project myProject;
|
||||
private static final Key<CanNotCalculateDiffPanel> PANEL_KEY = new Key<CanNotCalculateDiffPanel>("DiffPanelImpl.CanNotCalculateDiffPanel");
|
||||
private CanNotCalculateDiffPanel myNotCalculateDiffPanel;
|
||||
|
||||
public DiffPanelImpl(final Window owner, Project project, boolean enableToolbar) {
|
||||
myProject = project;
|
||||
@@ -159,7 +164,21 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
|
||||
}
|
||||
|
||||
void rediff() {
|
||||
setLineBlocks(myData.updateEditors());
|
||||
try {
|
||||
if (myNotCalculateDiffPanel != null) {
|
||||
myPanel.removeTopComponent(myNotCalculateDiffPanel);
|
||||
}
|
||||
setLineBlocks(myData.updateEditors());
|
||||
}
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
setTooBigFileErrorContents();
|
||||
}
|
||||
}
|
||||
|
||||
public void setTooBigFileErrorContents() {
|
||||
setLineBlocks(LineBlocks.EMPTY);
|
||||
myNotCalculateDiffPanel = new CanNotCalculateDiffPanel();
|
||||
myPanel.insertTopComponent(myNotCalculateDiffPanel);
|
||||
}
|
||||
|
||||
public void setTitle1(String title) {
|
||||
@@ -588,4 +607,10 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
|
||||
return super.getData(dataId);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CanNotCalculateDiffPanel extends EditorNotificationPanel {
|
||||
public CanNotCalculateDiffPanel() {
|
||||
myLabel.setText("Can not calculate diff. File is too big and there are too many changes.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -25,6 +25,7 @@ import com.intellij.openapi.diff.impl.fragments.LineFragment;
|
||||
import com.intellij.openapi.diff.impl.processing.TextCompareProcessor;
|
||||
import com.intellij.openapi.diff.impl.splitter.LineBlocks;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
@@ -56,7 +57,6 @@ public class SimpleDiffPanelState<DiffMarkupType extends DiffMarkup> implements
|
||||
}
|
||||
|
||||
private LineBlocks addMarkup(final ArrayList<LineFragment> lines) {
|
||||
resetMarkup();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
for (Iterator<LineFragment> iterator = lines.iterator(); iterator.hasNext();) {
|
||||
@@ -80,9 +80,9 @@ public class SimpleDiffPanelState<DiffMarkupType extends DiffMarkup> implements
|
||||
ApplicationManager.getApplication().runWriteAction(new ResetMarkupRunnable(this));
|
||||
}
|
||||
|
||||
public LineBlocks updateEditors() {
|
||||
public LineBlocks updateEditors() throws FilesTooBigForDiffException {
|
||||
resetMarkup();
|
||||
if (myAppender1.getEditor() == null || myAppender2.getEditor() == null) {
|
||||
resetMarkup();
|
||||
return LineBlocks.EMPTY;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -77,7 +78,7 @@ public class ChangeList {
|
||||
return Collections.unmodifiableList(myChanges);
|
||||
}
|
||||
|
||||
public static ChangeList build(Document base, Document version, Parent parent) {
|
||||
public static ChangeList build(Document base, Document version, Parent parent) throws FilesTooBigForDiffException {
|
||||
ChangeList result = new ChangeList(base, version, parent);
|
||||
ArrayList<Change> changes = result.buildChanges();
|
||||
Collections.sort(changes, CHANGE_ORDER);
|
||||
@@ -102,7 +103,7 @@ public class ChangeList {
|
||||
return myDocuments[side.getIndex()];
|
||||
}
|
||||
|
||||
private ArrayList<Change> buildChanges() {
|
||||
private ArrayList<Change> buildChanges() throws FilesTooBigForDiffException {
|
||||
Document base = getDocument(FragmentSide.SIDE1);
|
||||
String[] baseLines = DiffUtil.convertToLines(base.getText());
|
||||
Document version = getDocument(FragmentSide.SIDE2);
|
||||
|
||||
+7
-7
@@ -35,6 +35,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.util.containers.FilteringIterator;
|
||||
import com.intellij.util.containers.SequenceIterator;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -60,16 +61,15 @@ public class MergeList implements ChangeList.Parent, UserDataHolder {
|
||||
myChanges[1] = new ChangeList(base, right, this);
|
||||
}
|
||||
|
||||
public static MergeList create(Project project, Document left, Document base, Document right) {
|
||||
public static MergeList create(Project project, Document left, Document base, Document right) throws FilesTooBigForDiffException {
|
||||
MergeList mergeList = new MergeList(project, left, base, right);
|
||||
String leftText = left.getText();
|
||||
String baseText = base.getText();
|
||||
String rightText = right.getText();
|
||||
// todo do not copy
|
||||
@NonNls final Object[] data = {
|
||||
"Left\n" + leftText,
|
||||
"\nBase\n" + baseText,
|
||||
"\nRight\n" + rightText
|
||||
"Left\n", leftText,
|
||||
"\nBase\n", baseText,
|
||||
"\nRight\n", rightText
|
||||
};
|
||||
ContextLogger logger = new ContextLogger(LOG, new ContextLogger.SimpleContext(data));
|
||||
List<MergeBuilder.MergeFragment> fragmentList = processText(leftText, baseText, rightText, logger);
|
||||
@@ -116,7 +116,7 @@ public class MergeList implements ChangeList.Parent, UserDataHolder {
|
||||
private static List<MergeBuilder.MergeFragment> processText(String leftText,
|
||||
String baseText,
|
||||
String rightText,
|
||||
ContextLogger logger) {
|
||||
ContextLogger logger) throws FilesTooBigForDiffException {
|
||||
DiffFragment[] leftFragments = DiffPolicy.DEFAULT_LINES.buildFragments(baseText, leftText);
|
||||
DiffFragment[] rightFragments = DiffPolicy.DEFAULT_LINES.buildFragments(baseText, rightText);
|
||||
int[] leftOffsets = {0, 0};
|
||||
@@ -160,7 +160,7 @@ public class MergeList implements ChangeList.Parent, UserDataHolder {
|
||||
return text1 != null ? text1.length() : 0;
|
||||
}
|
||||
|
||||
public static MergeList create(DiffRequest data) {
|
||||
public static MergeList create(DiffRequest data) throws FilesTooBigForDiffException {
|
||||
DiffContent[] contents = data.getContents();
|
||||
return create(data.getProject(), contents[0].getDocument(), contents[1].getDocument(), contents[2].getDocument());
|
||||
}
|
||||
|
||||
+1
@@ -50,6 +50,7 @@ public class MergeSearchHelper {
|
||||
}
|
||||
|
||||
public static Change findChangeAt(EditorMouseEvent e, MergePanel2 mergePanel, int index) {
|
||||
if (mergePanel.getMergeList() == null) return null;
|
||||
Editor editor = e.getEditor();
|
||||
LOG.assertTrue(editor == mergePanel.getEditor(index));
|
||||
LogicalPosition logicalPosition = editor.xyToLogicalPosition(e.getMouseEvent().getPoint());
|
||||
|
||||
+29
-16
@@ -50,8 +50,10 @@ import com.intellij.openapi.ui.DialogBuilder;
|
||||
import com.intellij.openapi.ui.LabeledComponent;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.ui.EditorNotificationPanel;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -200,20 +202,29 @@ public class MergePanel2 implements DiffViewer {
|
||||
private void tryInitView() {
|
||||
if (!hasAllEditors()) return;
|
||||
if (myMergeList != null) return;
|
||||
myMergeList = MergeList.create(myData);
|
||||
myMergeList.addListener(myDividersRepainter);
|
||||
myStatusUpdater = StatusUpdater.install(myMergeList, myPanel);
|
||||
Editor left = getEditor(0);
|
||||
Editor base = getEditor(1);
|
||||
Editor right = getEditor(2);
|
||||
myMergeList.setMarkups(left, base, right);
|
||||
EditingSides[] sides = {new MyEditingSides(FragmentSide.SIDE1), new MyEditingSides(FragmentSide.SIDE2)};
|
||||
myScrollSupport.install(sides);
|
||||
for (int i = 0; i < myDividers.length; i++) {
|
||||
myDividers[i].listenEditors(sides[i]);
|
||||
try {
|
||||
myMergeList = MergeList.create(myData);
|
||||
myMergeList.addListener(myDividersRepainter);
|
||||
myStatusUpdater = StatusUpdater.install(myMergeList, myPanel);
|
||||
Editor left = getEditor(0);
|
||||
Editor base = getEditor(1);
|
||||
Editor right = getEditor(2);
|
||||
myMergeList.setMarkups(left, base, right);
|
||||
EditingSides[] sides = {new MyEditingSides(FragmentSide.SIDE1), new MyEditingSides(FragmentSide.SIDE2)};
|
||||
myScrollSupport.install(sides);
|
||||
for (int i = 0; i < myDividers.length; i++) {
|
||||
myDividers[i].listenEditors(sides[i]);
|
||||
}
|
||||
if (myScrollToFirstDiff) {
|
||||
myPanel.requestScrollEditors();
|
||||
}
|
||||
}
|
||||
if (myScrollToFirstDiff) {
|
||||
myPanel.requestScrollEditors();
|
||||
catch (final FilesTooBigForDiffException e) {
|
||||
myPanel.insertTopComponent(new EditorNotificationPanel() {
|
||||
{
|
||||
myLabel.setText(e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,9 +463,11 @@ public class MergePanel2 implements DiffViewer {
|
||||
|
||||
public int[] getFragmentStartingLines() {
|
||||
TIntHashSet beginnings = new TIntHashSet();
|
||||
for (int i = 0; i < 2; i++) {
|
||||
FragmentSide branchSide = FragmentSide.fromIndex(i);
|
||||
beginnings.addAll(myMergeList.getChanges(branchSide).getLineBlocks().getBegginings(MergeList.BASE_SIDE));
|
||||
if (myMergeList != null) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
FragmentSide branchSide = FragmentSide.fromIndex(i);
|
||||
beginnings.addAll(myMergeList.getChanges(branchSide).getLineBlocks().getBegginings(MergeList.BASE_SIDE));
|
||||
}
|
||||
}
|
||||
int[] result = beginnings.toArray();
|
||||
Arrays.sort(result);
|
||||
|
||||
+1
-1
@@ -179,7 +179,7 @@ public class MergeRequestImpl extends MergeRequest {
|
||||
});
|
||||
}
|
||||
|
||||
if (getMergeContent() != null) {
|
||||
if (getMergeContent() != null && mergePanel.getMergeList() != null) {
|
||||
new AllResolvedListener(mergePanel, builder.getDialogWrapper());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
|
||||
import com.intellij.openapi.diff.impl.highlighting.Util;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.util.diff.Diff;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -34,7 +35,7 @@ class ByWord implements DiffPolicy{
|
||||
myComparisonPolicy = comparisonPolicy;
|
||||
}
|
||||
|
||||
public DiffFragment[] buildFragments(String text1, String text2) {
|
||||
public DiffFragment[] buildFragments(String text1, String text2) throws FilesTooBigForDiffException {
|
||||
Word[] words1 = buildWords(text1, myComparisonPolicy);
|
||||
Word[] words2 = buildWords(text2, myComparisonPolicy);
|
||||
Diff.Change change = Diff.buildChanges(words1, words2);
|
||||
@@ -115,7 +116,7 @@ class ByWord implements DiffPolicy{
|
||||
version.addOneSide(prefix, wordCount);
|
||||
}
|
||||
|
||||
private void processEquals(int changed1, int changed2, FragmentBuilder result) {
|
||||
private void processEquals(int changed1, int changed2, FragmentBuilder result) throws FilesTooBigForDiffException {
|
||||
while (result.getVersion1().getCurrentWordIndex() < changed1) {
|
||||
result.processEqual();
|
||||
}
|
||||
@@ -206,11 +207,11 @@ class ByWord implements DiffPolicy{
|
||||
myFragments.add(fragment);
|
||||
}
|
||||
|
||||
private void addEqual(Word word1, Word word2) {
|
||||
private void addEqual(Word word1, Word word2) throws FilesTooBigForDiffException {
|
||||
addAll(CORRECTION.correct(new DiffFragment[]{myComparisonPolicy.createFragment(word1, word2)}));
|
||||
}
|
||||
|
||||
public void processEqual() {
|
||||
public void processEqual() throws FilesTooBigForDiffException {
|
||||
Word word1 = myVersion1.getCurrentWord();
|
||||
Word word2 = myVersion2.getCurrentWord();
|
||||
addAll(fragmentsByChar(myVersion1.getCurrentWordPrefix(), myVersion2.getCurrentWordPrefix()));
|
||||
@@ -220,7 +221,7 @@ class ByWord implements DiffPolicy{
|
||||
myVersion2.incCurrentWord();
|
||||
}
|
||||
|
||||
private DiffFragment[] fragmentsByChar(String text1, String text2) {
|
||||
private DiffFragment[] fragmentsByChar(String text1, String text2) throws FilesTooBigForDiffException {
|
||||
if (text1.length() == 0 && text2.length() == 0) {
|
||||
return DiffFragment.EMPTY_ARRAY;
|
||||
}
|
||||
@@ -230,7 +231,7 @@ class ByWord implements DiffPolicy{
|
||||
return Util.cutFirst(fragments);
|
||||
}
|
||||
|
||||
private void addPostfixes() {
|
||||
private void addPostfixes() throws FilesTooBigForDiffException {
|
||||
String postfix1 = myVersion1.getCurrentWordPostfixAndOneMore();
|
||||
String postfix2 = myVersion2.getCurrentWordPostfixAndOneMore();
|
||||
int length1 = postfix1.length();
|
||||
@@ -268,7 +269,7 @@ class ByWord implements DiffPolicy{
|
||||
myVersion2.incCurrentWord(wordCount2);
|
||||
}
|
||||
|
||||
public void addTails() {
|
||||
public void addTails() throws FilesTooBigForDiffException {
|
||||
String tail1 = myVersion1.getNotProcessedTail();
|
||||
String tail2 = myVersion2.getNotProcessedTail();
|
||||
if (tail1.length() == 0 && tail2.length() == 0) return;
|
||||
|
||||
+3
-2
@@ -23,6 +23,7 @@ import com.intellij.openapi.diff.impl.fragments.LineFragment;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
|
||||
import com.intellij.openapi.diff.impl.highlighting.LineBlockDivider;
|
||||
import com.intellij.openapi.diff.impl.highlighting.Util;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -34,7 +35,7 @@ public class TextCompareProcessor {
|
||||
myComparisonPolicy = comparisonPolicy;
|
||||
}
|
||||
|
||||
public ArrayList<LineFragment> process(String text1, String text2) {
|
||||
public ArrayList<LineFragment> process(String text1, String text2) throws FilesTooBigForDiffException {
|
||||
DiffFragment[] woFormattingBlocks = DiffPolicy.LINES_WO_FORMATTING.buildFragments(text1, text2);
|
||||
DiffFragment[] step1lineFragments = new DiffCorrection.TrueLineBlocks(myComparisonPolicy).
|
||||
correctAndNormalize(woFormattingBlocks);
|
||||
@@ -49,7 +50,7 @@ public class TextCompareProcessor {
|
||||
return lineBlocks;
|
||||
}
|
||||
|
||||
private ArrayList<LineFragment> findSubFragments(String text1, String text2) {
|
||||
private ArrayList<LineFragment> findSubFragments(String text1, String text2) throws FilesTooBigForDiffException {
|
||||
DiffFragment[] fragments = new ByWord(myComparisonPolicy).buildFragments(text1, text2);
|
||||
fragments = DiffCorrection.ConnectSingleSideToChange.INSTANCE.correct(fragments);
|
||||
fragments = UniteSameType.INSTANCE.correct(fragments);
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.ex.DiffFragment;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
|
||||
import com.intellij.openapi.diff.impl.highlighting.Util;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
class UniteSameType implements DiffCorrection {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.UniteSameType");
|
||||
@@ -70,7 +71,7 @@ class UniteSameType implements DiffCorrection {
|
||||
return collector.toArray();
|
||||
}
|
||||
|
||||
public static DiffFragment uniteAll(DiffFragment[] fragments) {
|
||||
public static DiffFragment uniteAll(DiffFragment[] fragments) throws FilesTooBigForDiffException {
|
||||
fragments = INSTANCE.correct(fragments);
|
||||
LOG.assertTrue(fragments.length == 1);
|
||||
return fragments[0];
|
||||
|
||||
+17
-1
@@ -37,6 +37,7 @@ public class DiffPanelOutterComponent extends JPanel implements DataProvider {
|
||||
private ScrollingPanel myScrollingPanel = null;
|
||||
private final JPanel myBottomContainer;
|
||||
private JComponent myBottomComponent;
|
||||
private JPanel myWrapper;
|
||||
|
||||
public DiffPanelOutterComponent(List<TextDiffType> diffTypes, DiffRequest.ToolbarAddons defaultActions) {
|
||||
super(new BorderLayout());
|
||||
@@ -47,6 +48,8 @@ public class DiffPanelOutterComponent extends JPanel implements DataProvider {
|
||||
myDefaultActions = defaultActions;
|
||||
myToolbar = new DiffToolbarComponent(this);
|
||||
disableToolbar(false);
|
||||
myWrapper = new JPanel(new BorderLayout());
|
||||
add(myWrapper, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public DiffToolbar resetToolbar() {
|
||||
@@ -54,11 +57,20 @@ public class DiffPanelOutterComponent extends JPanel implements DataProvider {
|
||||
return myToolbar.getToolbar();
|
||||
}
|
||||
|
||||
public void resetDiffComponent(JComponent component, ScrollingPanel scrollingPanel) {
|
||||
myWrapper.removeAll();
|
||||
insertDiffComponent(component, scrollingPanel);
|
||||
}
|
||||
|
||||
public void insertDiffComponent(JComponent component, ScrollingPanel scrollingPanel) {
|
||||
add(component, BorderLayout.CENTER);
|
||||
myWrapper.add(component, BorderLayout.CENTER);
|
||||
setScrollingPanel(scrollingPanel);
|
||||
}
|
||||
|
||||
public void insertTopComponent(JComponent component) {
|
||||
myWrapper.add(component, BorderLayout.NORTH);
|
||||
}
|
||||
|
||||
public JComponent getBottomComponent() {
|
||||
return myBottomComponent;
|
||||
}
|
||||
@@ -152,6 +164,10 @@ public class DiffPanelOutterComponent extends JPanel implements DataProvider {
|
||||
myScrollState = NO_SCROLL_NEEDED;
|
||||
}
|
||||
|
||||
public void removeTopComponent(final JComponent jComponent) {
|
||||
myWrapper.remove(jComponent);
|
||||
}
|
||||
|
||||
private interface DeferScrollToFirstDiff {
|
||||
DeferScrollToFirstDiff scrollNow(ScrollingPanel panel, JComponent component);
|
||||
|
||||
|
||||
+25
-11
@@ -22,6 +22,7 @@ import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
|
||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
|
||||
import com.intellij.openapi.editor.markup.MarkupModel;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -41,19 +42,14 @@ class PersistentRangeHighlighterImpl extends RangeHighlighterImpl implements Ran
|
||||
|
||||
@Override
|
||||
protected void changedUpdateImpl(DocumentEvent e) {
|
||||
// todo Denis Zhdanov
|
||||
DocumentEventImpl event = (DocumentEventImpl)e;
|
||||
if (PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, this)) {
|
||||
setLine(event.translateLineViaDiff(getLine()));
|
||||
if (getLine() < 0 || getLine() >= getDocument().getLineCount()) {
|
||||
invalidate(e);
|
||||
}
|
||||
else {
|
||||
DocumentEx document = getDocument();
|
||||
setIntervalStart(document.getLineStartOffset(getLine()));
|
||||
setIntervalEnd(document.getLineEndOffset(getLine()));
|
||||
}
|
||||
final boolean shouldTranslateViaDiff = PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, this);
|
||||
boolean wasTranslatedViaDiff = shouldTranslateViaDiff;
|
||||
if (shouldTranslateViaDiff) {
|
||||
wasTranslatedViaDiff = translatedViaDiff(e, event);
|
||||
}
|
||||
else {
|
||||
if (! wasTranslatedViaDiff) {
|
||||
super.changedUpdateImpl(e);
|
||||
if (isValid()) {
|
||||
setLine(getDocument().getLineNumber(getStartOffset()));
|
||||
@@ -65,6 +61,24 @@ class PersistentRangeHighlighterImpl extends RangeHighlighterImpl implements Ran
|
||||
}
|
||||
}
|
||||
|
||||
private boolean translatedViaDiff(DocumentEvent e, DocumentEventImpl event) {
|
||||
try {
|
||||
setLine(event.translateLineViaDiff(getLine()));
|
||||
}
|
||||
catch (FilesTooBigForDiffException e1) {
|
||||
return false;
|
||||
}
|
||||
if (getLine() < 0 || getLine() >= getDocument().getLineCount()) {
|
||||
invalidate(e);
|
||||
}
|
||||
else {
|
||||
DocumentEx document = getDocument();
|
||||
setIntervalStart(document.getLineStartOffset(getLine()));
|
||||
setIntervalEnd(document.getLineEndOffset(getLine()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PersistentRangeHighlighter" +
|
||||
|
||||
+4
-3
@@ -19,6 +19,7 @@ import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.diff.Diff;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class DocumentEventImpl extends DocumentEvent {
|
||||
@@ -139,7 +140,7 @@ public class DocumentEventImpl extends DocumentEvent {
|
||||
return myIsWholeDocReplaced;
|
||||
}
|
||||
|
||||
public int translateLineViaDiff(int line) {
|
||||
public int translateLineViaDiff(int line) throws FilesTooBigForDiffException {
|
||||
if (myChange == null) buildDiff();
|
||||
if (myChange == null) return line;
|
||||
|
||||
@@ -163,14 +164,14 @@ public class DocumentEventImpl extends DocumentEvent {
|
||||
return newLine;
|
||||
}
|
||||
|
||||
public int translateLineViaDiffStrict(int line) {
|
||||
public int translateLineViaDiffStrict(int line) throws FilesTooBigForDiffException {
|
||||
if (myChange == null) buildDiff();
|
||||
Diff.Change change = myChange;
|
||||
if (change == null) return line;
|
||||
return Diff.translateLine(change, line);
|
||||
}
|
||||
|
||||
private void buildDiff() {
|
||||
private void buildDiff() throws FilesTooBigForDiffException {
|
||||
//Diff diff = new Diff(strings1, strings2);
|
||||
//myChange = diff.diff_2(false);
|
||||
myChange = Diff.buildChanges(myOldString, myNewString);
|
||||
|
||||
+3
-2
@@ -4,6 +4,7 @@ import com.intellij.openapi.diff.ex.DiffFragment;
|
||||
import com.intellij.openapi.diff.impl.MultiCheck;
|
||||
import com.intellij.util.Assertion;
|
||||
import com.intellij.util.diff.Diff;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class UtilTest extends TestCase {
|
||||
@@ -80,7 +81,7 @@ public class UtilTest extends TestCase {
|
||||
assertTrue(line[0].isEqual());
|
||||
}
|
||||
|
||||
public void testConcatEquals() {
|
||||
public void testConcatEquals() throws FilesTooBigForDiffException {
|
||||
Object[] left = new String[]{"a", "x", "a", "b"};
|
||||
Object[] right = new String[]{"a", "b"};
|
||||
Diff.Change change = Diff.buildChanges(left, right);
|
||||
@@ -133,7 +134,7 @@ public class UtilTest extends TestCase {
|
||||
multiCheck.flush();
|
||||
}
|
||||
|
||||
public void testConcatEqualsConcatenatesChanged() {
|
||||
public void testConcatEqualsConcatenatesChanged() throws FilesTooBigForDiffException {
|
||||
String[] left = new String[]{"i1", "a", "i2", "a", "b"};
|
||||
String[] right = new String[]{"a", "b"};
|
||||
Diff.Change change = Diff.buildChanges(left, right);
|
||||
|
||||
+12
-11
@@ -7,6 +7,7 @@ import com.intellij.openapi.diff.impl.highlighting.FragmentStringConvertion;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.util.Assertion;
|
||||
import com.intellij.util.StringConvertion;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import gnu.trove.Equality;
|
||||
import junit.framework.AssertionFailedError;
|
||||
import junit.framework.TestCase;
|
||||
@@ -20,7 +21,7 @@ public class ByWordTest extends TestCase {
|
||||
CHECK.setEquality(new FragmentEquality());
|
||||
}
|
||||
|
||||
public void test1() {
|
||||
public void test1() throws FilesTooBigForDiffException {
|
||||
DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
|
||||
DiffFragment[] fragments = byWord.buildFragments("abc def, 123", "ab def, 12");
|
||||
CHECK.compareAll(new DiffFragment[]{new DiffFragment("abc", "ab"),
|
||||
@@ -28,7 +29,7 @@ public class ByWordTest extends TestCase {
|
||||
new DiffFragment("123", "12")}, fragments);
|
||||
}
|
||||
|
||||
public void test2() {
|
||||
public void test2() throws FilesTooBigForDiffException {
|
||||
DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
|
||||
DiffFragment[] fragments = byWord.buildFragments(" a[xy]+1", ",a[]+1");
|
||||
CHECK.compareAll(new DiffFragment[]{new DiffFragment(" ", null),
|
||||
@@ -38,13 +39,13 @@ public class ByWordTest extends TestCase {
|
||||
new DiffFragment("]+1", "]+1")}, fragments);
|
||||
}
|
||||
|
||||
public void test3() {
|
||||
public void test3() throws FilesTooBigForDiffException {
|
||||
DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
|
||||
DiffFragment[] fragments = byWord.buildFragments("0987\n a.g();\n", "yyyy\n");
|
||||
CHECK.compareAll(new DiffFragment[]{new DiffFragment("0987\n a.g();\n", "yyyy\n")}, fragments);
|
||||
}
|
||||
|
||||
public void test4() {
|
||||
public void test4() throws FilesTooBigForDiffException {
|
||||
DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
|
||||
DiffFragment[] fragments = byWord.buildFragments(" abc\n2222\n", " x = abc\nzzzz\n");
|
||||
CHECK.compareAll(new DiffFragment[]{
|
||||
@@ -55,7 +56,7 @@ public class ByWordTest extends TestCase {
|
||||
new DiffFragment("\n", "\n")}, fragments);
|
||||
}
|
||||
|
||||
public void testIdea58505() {
|
||||
public void testIdea58505() throws FilesTooBigForDiffException {
|
||||
DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
|
||||
DiffFragment[] fragments = byWord.buildFragments(" if (eventMerger!=null && !dataSelection.getValueIsAdjusting()) {",
|
||||
" if (eventMerger!=null && (dataSelection==null || !dataSelection.getValueIsAdjusting())) {");
|
||||
@@ -71,7 +72,7 @@ public class ByWordTest extends TestCase {
|
||||
}, fragments);
|
||||
}
|
||||
|
||||
public void testIdea58505Trim() {
|
||||
public void testIdea58505Trim() throws FilesTooBigForDiffException {
|
||||
DiffPolicy byWord = new ByWord(ComparisonPolicy.TRIM_SPACE);
|
||||
DiffFragment[] fragments = byWord.buildFragments(" if (eventMerger!=null && !dataSelection.getValueIsAdjusting()) {",
|
||||
" if (eventMerger!=null && (dataSelection==null || !dataSelection.getValueIsAdjusting())) {");
|
||||
@@ -87,7 +88,7 @@ public class ByWordTest extends TestCase {
|
||||
}, fragments);
|
||||
}
|
||||
|
||||
public void testIdea56428() {
|
||||
public void testIdea56428() throws FilesTooBigForDiffException {
|
||||
DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
|
||||
DiffFragment[] fragments = byWord.buildFragments("messageInsertStatement = connection.prepareStatement(\"INSERT INTO AUDIT (AUDIT_TYPE_ID, STATUS, SERVER_ID, INSTANCE_ID, REQUEST_ID) VALUES (?, ?, ?, ?, ?)\");\n",
|
||||
"messageInsertStatement = connection.prepareStatement(\"INSERT INTO AUDIT (AUDIT_TYPE_ID, CREATION_TIMESTAMP, STATUS, SERVER_ID, INSTANCE_ID, REQUEST_ID) VALUES (?, ?, ?, ?, ?, ?)\");\n");
|
||||
@@ -130,7 +131,7 @@ public class ByWordTest extends TestCase {
|
||||
new Word(text, new TextRange(3, 4))}, words);
|
||||
}
|
||||
|
||||
public void testLeadingFormatting() {
|
||||
public void testLeadingFormatting() throws FilesTooBigForDiffException {
|
||||
DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
|
||||
DiffFragment[] fragments = byWord.buildFragments(" abc\n 123", " 123");
|
||||
CHECK.compareAll(new DiffFragment[]{new DiffFragment(" abc\n", null),
|
||||
@@ -138,7 +139,7 @@ public class ByWordTest extends TestCase {
|
||||
UniteSameType.INSTANCE.correct(fragments));
|
||||
}
|
||||
|
||||
public void testRestyleNewLines() {
|
||||
public void testRestyleNewLines() throws FilesTooBigForDiffException {
|
||||
DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
|
||||
DiffFragment[] fragments = byWord.buildFragments("f(a, b);", "f(a,\n b);");
|
||||
CHECK.compareAll(new DiffFragment[]{new DiffFragment("f(a,", "f(a,"),
|
||||
@@ -147,7 +148,7 @@ public class ByWordTest extends TestCase {
|
||||
UniteSameType.INSTANCE.correct(fragments));
|
||||
}
|
||||
|
||||
public void testIgnoreSpaces() {
|
||||
public void testIgnoreSpaces() throws FilesTooBigForDiffException {
|
||||
ByWord byWord = new ByWord(ComparisonPolicy.IGNORE_SPACE);
|
||||
DiffFragment[] fragments = byWord.buildFragments(" o.f(a)", "o. f( b)");
|
||||
CHECK.compareAll(new DiffFragment[]{DiffFragment.unchanged(" o.f(", "o. f( "),
|
||||
@@ -156,7 +157,7 @@ public class ByWordTest extends TestCase {
|
||||
UniteSameType.INSTANCE.correct(fragments));
|
||||
}
|
||||
|
||||
public void testIgnoreLeadingAndTrailing() {
|
||||
public void testIgnoreLeadingAndTrailing() throws FilesTooBigForDiffException {
|
||||
ByWord byWord = new ByWord(ComparisonPolicy.TRIM_SPACE);
|
||||
checkEqual(byWord.buildFragments(" text", "text"));
|
||||
checkEqual(byWord.buildFragments("text ", "text"));
|
||||
|
||||
+6
-5
@@ -5,6 +5,7 @@ import com.intellij.openapi.diff.impl.ComparisonPolicy;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentEquality;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentStringConvertion;
|
||||
import com.intellij.util.Assertion;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class CorrectionTest extends TestCase {
|
||||
@@ -16,7 +17,7 @@ public class CorrectionTest extends TestCase {
|
||||
CHECK.setEquality(new FragmentEquality());
|
||||
}
|
||||
|
||||
public void testTrueLineBlock() {
|
||||
public void testTrueLineBlock() throws FilesTooBigForDiffException {
|
||||
DiffCorrection.TrueLineBlocks correction = new DiffCorrection.TrueLineBlocks(ComparisonPolicy.DEFAULT);
|
||||
DiffFragment[] fragments = correction.correctAndNormalize(new DiffFragment[]{
|
||||
DiffFragment.unchanged(" 1\n ab\n x\n", " 2\n ab\n x\n"),
|
||||
@@ -30,7 +31,7 @@ public class CorrectionTest extends TestCase {
|
||||
fragments);
|
||||
}
|
||||
|
||||
public void testTrueLineBlocksWithSameLines() {
|
||||
public void testTrueLineBlocksWithSameLines() throws FilesTooBigForDiffException {
|
||||
DiffCorrection.TrueLineBlocks correction = new DiffCorrection.TrueLineBlocks(ComparisonPolicy.DEFAULT);
|
||||
DiffFragment[] fragments = correction.correctAndNormalize(new DiffFragment[]{
|
||||
DiffFragment.unchanged(" X\n X\n X", " X\n X\n X")});
|
||||
@@ -39,7 +40,7 @@ public class CorrectionTest extends TestCase {
|
||||
fragments);
|
||||
}
|
||||
|
||||
public void testChangedSpaceCorrection() {
|
||||
public void testChangedSpaceCorrection() throws FilesTooBigForDiffException {
|
||||
DiffCorrection correction = new DiffCorrection.ChangedSpace(ComparisonPolicy.DEFAULT);
|
||||
DiffFragment[] fragments = correction.correct(new DiffFragment[]{
|
||||
new DiffFragment("x", "y"),
|
||||
@@ -63,7 +64,7 @@ public class CorrectionTest extends TestCase {
|
||||
CHECK.compareAll(new DiffFragment[]{new DiffFragment("\n", "\n"), new DiffFragment(null, "\n")}, fragments);
|
||||
}
|
||||
|
||||
public void testConcatinateSingleSide() {
|
||||
public void testConcatinateSingleSide() throws FilesTooBigForDiffException {
|
||||
DiffCorrection correction = new DiffCorrection.ConcatenateSingleSide();
|
||||
DiffFragment[] corrected = correction.correct(
|
||||
new DiffFragment[]{new DiffFragment(null, "a"),
|
||||
@@ -81,7 +82,7 @@ public class CorrectionTest extends TestCase {
|
||||
corrected);
|
||||
}
|
||||
|
||||
public void testConnectSingleSideToChange() {
|
||||
public void testConnectSingleSideToChange() throws FilesTooBigForDiffException {
|
||||
DiffFragment first = DiffFragment.unchanged("a", "A");
|
||||
DiffFragment oneSide = new DiffFragment(null, "b");
|
||||
DiffFragment equal = new DiffFragment("c", "c");
|
||||
|
||||
+3
-2
@@ -4,18 +4,19 @@ import com.intellij.openapi.diff.ex.DiffFragment;
|
||||
import com.intellij.openapi.diff.impl.ComparisonPolicy;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
|
||||
import com.intellij.openapi.diff.impl.highlighting.Util;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class LineBlocksDiffPolicyTest extends TestCase{
|
||||
public void test() {
|
||||
public void test() throws FilesTooBigForDiffException {
|
||||
DiffPolicy.LineBlocks diffPolicy = new DiffPolicy.LineBlocks(ComparisonPolicy.DEFAULT);
|
||||
checkPolicy(diffPolicy, "abc\n123\n", "ABC\nXYZ\n");
|
||||
checkPolicy(diffPolicy, "abc\n123", "ABC\nXYZ");
|
||||
checkPolicy(diffPolicy, "abc\n123\n", "ABC\nXYZ");
|
||||
}
|
||||
|
||||
private void checkPolicy(DiffPolicy.LineBlocks diffPolicy, String text1, String text2) {
|
||||
private void checkPolicy(DiffPolicy.LineBlocks diffPolicy, String text1, String text2) throws FilesTooBigForDiffException {
|
||||
DiffFragment[] fragments = diffPolicy.buildFragments(text1, text2);
|
||||
Assert.assertEquals(text1, Util.getText(fragments, FragmentSide.SIDE1));
|
||||
assertEquals(text2, Util.getText(fragments, FragmentSide.SIDE2));
|
||||
|
||||
+3
-2
@@ -4,6 +4,7 @@ import com.intellij.openapi.diff.ex.DiffFragment;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentEquality;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentStringConvertion;
|
||||
import com.intellij.util.Assertion;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class NormalizationTest extends TestCase {
|
||||
@@ -15,7 +16,7 @@ public class NormalizationTest extends TestCase {
|
||||
CHECK.setEquality(new FragmentEquality());
|
||||
}
|
||||
|
||||
public void testSingleSide() {
|
||||
public void testSingleSide() throws FilesTooBigForDiffException {
|
||||
DiffCorrection correction = DiffCorrection.Normalize.INSTANCE;
|
||||
DiffFragment[] corrected = correction.correct(
|
||||
new DiffFragment[]{new DiffFragment(null, "a"),
|
||||
@@ -33,7 +34,7 @@ public class NormalizationTest extends TestCase {
|
||||
corrected);
|
||||
}
|
||||
|
||||
public void testUnitesEquals() {
|
||||
public void testUnitesEquals() throws FilesTooBigForDiffException {
|
||||
DiffCorrection correction = DiffCorrection.Normalize.INSTANCE;
|
||||
DiffFragment[] fragments = correction.correct(new DiffFragment[]{new DiffFragment(null, "a"),
|
||||
new DiffFragment("x", "x"),
|
||||
|
||||
+2
-1
@@ -2,12 +2,13 @@ package com.intellij.openapi.diff.impl.processing;
|
||||
|
||||
import com.intellij.openapi.diff.impl.ComparisonPolicy;
|
||||
import com.intellij.openapi.diff.impl.fragments.LineFragment;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TextCompareProcessorTest extends TestCase {
|
||||
public void testIgnoreWrappingEqualText() {
|
||||
public void testIgnoreWrappingEqualText() throws FilesTooBigForDiffException {
|
||||
TextCompareProcessor processor = new TextCompareProcessor(ComparisonPolicy.IGNORE_SPACE);
|
||||
ArrayList<LineFragment> lineFragments = processor.process("f(a, b)\n", "f(a,\nb)\n");
|
||||
assertTrue(lineFragments.size() == 1);
|
||||
|
||||
+3
-2
@@ -4,6 +4,7 @@ import com.intellij.openapi.diff.ex.DiffFragment;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentEquality;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentStringConvertion;
|
||||
import com.intellij.util.Assertion;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class UniteSameTypeTest extends TestCase {
|
||||
@@ -15,7 +16,7 @@ public class UniteSameTypeTest extends TestCase {
|
||||
CHECK.setEquality(new FragmentEquality());
|
||||
}
|
||||
|
||||
public void testUnitDifferentOnesides() {
|
||||
public void testUnitDifferentOnesides() throws FilesTooBigForDiffException {
|
||||
DiffFragment[] fragments = UniteSameType.INSTANCE.correct(new DiffFragment[]{new DiffFragment("a", "b"),
|
||||
new DiffFragment(null, " "),
|
||||
new DiffFragment("\n ", null),
|
||||
@@ -23,7 +24,7 @@ public class UniteSameTypeTest extends TestCase {
|
||||
CHECK.compareAll(new DiffFragment[]{new DiffFragment("a\n ", "b "), new DiffFragment("x", "x")}, fragments);
|
||||
}
|
||||
|
||||
public void testUniteEqualsUnitesFormattingOnly() {
|
||||
public void testUniteEqualsUnitesFormattingOnly() throws FilesTooBigForDiffException {
|
||||
DiffFragment changed = new DiffFragment("abc", "123");
|
||||
DiffFragment equal = new DiffFragment("qqq", "qqq");
|
||||
DiffFragment[] fragments = DiffCorrection.UnitEquals.INSTANCE.correct(new DiffFragment[]{
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.diff.Diff;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
public abstract class ComparisonPolicy {
|
||||
private final String myName;
|
||||
@@ -34,7 +35,7 @@ public abstract class ComparisonPolicy {
|
||||
myName = name;
|
||||
}
|
||||
|
||||
public DiffFragment[] buildFragments(String[] strings1, String[] strings2) {
|
||||
public DiffFragment[] buildFragments(String[] strings1, String[] strings2) throws FilesTooBigForDiffException {
|
||||
DiffFragmentBuilder builder = new DiffFragmentBuilder(strings1, strings2);
|
||||
Object[] wrappers1 = getWrappers(strings1);
|
||||
Object[] wrappers2 = getWrappers(strings2);
|
||||
@@ -42,7 +43,7 @@ public abstract class ComparisonPolicy {
|
||||
return builder.buildFragments(Util.concatEquals(change, wrappers1, wrappers2));
|
||||
}
|
||||
|
||||
public DiffFragment[] buildDiffFragmentsFromLines(String[] lines1, String[] lines2) {
|
||||
public DiffFragment[] buildDiffFragmentsFromLines(String[] lines1, String[] lines2) throws FilesTooBigForDiffException {
|
||||
DiffFragmentBuilder builder = new DiffFragmentBuilder(lines1, lines2);
|
||||
Object[] wrappers1 = getLineWrappers(lines1);
|
||||
Object[] wrappers2 = getLineWrappers(lines2);
|
||||
@@ -194,7 +195,7 @@ public abstract class ComparisonPolicy {
|
||||
return result;
|
||||
}
|
||||
|
||||
public DiffFragment[] buildFragments(String[] strings1, String[] strings2) {
|
||||
public DiffFragment[] buildFragments(String[] strings1, String[] strings2) throws FilesTooBigForDiffException {
|
||||
DiffFragment[] fragments = super.buildFragments(strings1, strings2);
|
||||
DiffCorrection.FragmentsCollector collector = new DiffCorrection.FragmentsCollector();
|
||||
collector.processAll(fragments, this);
|
||||
|
||||
@@ -22,11 +22,12 @@ import com.intellij.openapi.diff.impl.ComparisonPolicy;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
|
||||
import com.intellij.openapi.diff.impl.highlighting.Util;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public interface DiffCorrection {
|
||||
DiffFragment[] correct(DiffFragment[] fragments);
|
||||
DiffFragment[] correct(DiffFragment[] fragments) throws FilesTooBigForDiffException;
|
||||
|
||||
class TrueLineBlocks implements DiffCorrection, FragmentProcessor<FragmentsCollector> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.DiffCorrection.TrueLineBlocks");
|
||||
@@ -38,13 +39,13 @@ public interface DiffCorrection {
|
||||
myComparisonPolicy = comparisonPolicy;
|
||||
}
|
||||
|
||||
public DiffFragment[] correct(DiffFragment[] fragments) {
|
||||
public DiffFragment[] correct(DiffFragment[] fragments) throws FilesTooBigForDiffException {
|
||||
FragmentsCollector collector = new FragmentsCollector();
|
||||
collector.processAll(fragments, this);
|
||||
return collector.toArray();
|
||||
}
|
||||
|
||||
public void process(DiffFragment fragment, FragmentsCollector collector) {
|
||||
public void process(DiffFragment fragment, FragmentsCollector collector) throws FilesTooBigForDiffException {
|
||||
if (!fragment.isEqual()) {
|
||||
if (myComparisonPolicy.isEqual(fragment))
|
||||
fragment = myComparisonPolicy.createFragment(fragment.getText1(), fragment.getText2());
|
||||
@@ -58,7 +59,7 @@ public interface DiffCorrection {
|
||||
}
|
||||
}
|
||||
|
||||
public DiffFragment[] correctAndNormalize(DiffFragment[] fragments) {
|
||||
public DiffFragment[] correctAndNormalize(DiffFragment[] fragments) throws FilesTooBigForDiffException {
|
||||
return Normalize.INSTANCE.correct(correct(fragments));
|
||||
}
|
||||
}
|
||||
@@ -72,7 +73,7 @@ public interface DiffCorrection {
|
||||
myDiffPolicy = new DiffPolicy.ByChar(myComparisonPolicy);
|
||||
}
|
||||
|
||||
public void process(DiffFragment fragment, FragmentsCollector collector) {
|
||||
public void process(DiffFragment fragment, FragmentsCollector collector) throws FilesTooBigForDiffException {
|
||||
if (!fragment.isChange()) {
|
||||
collector.add(fragment);
|
||||
return;
|
||||
@@ -111,7 +112,7 @@ public interface DiffCorrection {
|
||||
return text.substring(0, i);
|
||||
}
|
||||
|
||||
public DiffFragment[] correct(DiffFragment[] fragments) {
|
||||
public DiffFragment[] correct(DiffFragment[] fragments) throws FilesTooBigForDiffException {
|
||||
FragmentsCollector collector = new FragmentsCollector();
|
||||
collector.processAll(fragments, this);
|
||||
return collector.toArray();
|
||||
@@ -119,7 +120,7 @@ public interface DiffCorrection {
|
||||
}
|
||||
|
||||
interface FragmentProcessor<Collector> {
|
||||
void process(DiffFragment fragment, Collector collector);
|
||||
void process(DiffFragment fragment, Collector collector) throws FilesTooBigForDiffException;
|
||||
}
|
||||
|
||||
class BaseFragmentRunner<ActualRunner extends BaseFragmentRunner> {
|
||||
@@ -144,7 +145,7 @@ public interface DiffCorrection {
|
||||
|
||||
public DiffFragment[] getFragments() { return myFragments; }
|
||||
|
||||
public void processAll(DiffFragment[] fragments, FragmentProcessor<ActualRunner> processor) {
|
||||
public void processAll(DiffFragment[] fragments, FragmentProcessor<ActualRunner> processor) throws FilesTooBigForDiffException {
|
||||
myFragments = fragments;
|
||||
for (;myIndex < myFragments.length; myIndex++) {
|
||||
DiffFragment fragment = myFragments[myIndex];
|
||||
@@ -198,7 +199,7 @@ public interface DiffCorrection {
|
||||
}
|
||||
}
|
||||
|
||||
public void processAll(DiffFragment[] fragments, FragmentProcessor<FragmentBuffer> processor) {
|
||||
public void processAll(DiffFragment[] fragments, FragmentProcessor<FragmentBuffer> processor) throws FilesTooBigForDiffException {
|
||||
super.processAll(fragments, processor);
|
||||
flushMarked();
|
||||
}
|
||||
@@ -208,7 +209,7 @@ public interface DiffCorrection {
|
||||
public static final DiffCorrection INSTANCE = new ConcatenateSingleSide();
|
||||
private static final int DEFAULT_MODE = 1;
|
||||
|
||||
public DiffFragment[] correct(DiffFragment[] fragments) {
|
||||
public DiffFragment[] correct(DiffFragment[] fragments) throws FilesTooBigForDiffException {
|
||||
FragmentBuffer buffer = new FragmentBuffer();
|
||||
buffer.processAll(fragments, this);
|
||||
return buffer.toArray();
|
||||
@@ -225,7 +226,7 @@ public interface DiffCorrection {
|
||||
private static final int EQUAL_MODE = 1;
|
||||
private static final int FORMATTING_MODE = 2;
|
||||
|
||||
public DiffFragment[] correct(DiffFragment[] fragments) {
|
||||
public DiffFragment[] correct(DiffFragment[] fragments) throws FilesTooBigForDiffException {
|
||||
FragmentBuffer buffer = new FragmentBuffer();
|
||||
buffer.processAll(fragments, this);
|
||||
return buffer.toArray();
|
||||
@@ -243,7 +244,7 @@ public interface DiffCorrection {
|
||||
|
||||
private Normalize() {}
|
||||
|
||||
public DiffFragment[] correct(DiffFragment[] fragments) {
|
||||
public DiffFragment[] correct(DiffFragment[] fragments) throws FilesTooBigForDiffException {
|
||||
return UnitEquals.INSTANCE.correct(ConcatenateSingleSide.INSTANCE.correct(fragments));
|
||||
}
|
||||
}
|
||||
@@ -252,7 +253,7 @@ public interface DiffCorrection {
|
||||
public static final ConnectSingleSideToChange INSTANCE = new ConnectSingleSideToChange();
|
||||
private static final int CHANGE = 1;
|
||||
|
||||
public DiffFragment[] correct(DiffFragment[] fragments) {
|
||||
public DiffFragment[] correct(DiffFragment[] fragments) throws FilesTooBigForDiffException {
|
||||
FragmentBuffer buffer = new FragmentBuffer();
|
||||
buffer.processAll(fragments, this);
|
||||
return buffer.toArray();
|
||||
|
||||
@@ -18,9 +18,10 @@ package com.intellij.openapi.diff.impl.processing;
|
||||
import com.intellij.openapi.diff.LineTokenizer;
|
||||
import com.intellij.openapi.diff.ex.DiffFragment;
|
||||
import com.intellij.openapi.diff.impl.ComparisonPolicy;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
public interface DiffPolicy {
|
||||
DiffFragment[] buildFragments(String text1, String text2);
|
||||
DiffFragment[] buildFragments(String text1, String text2) throws FilesTooBigForDiffException;
|
||||
|
||||
DiffPolicy LINES_WO_FORMATTING = new LineBlocks(ComparisonPolicy.IGNORE_SPACE);
|
||||
DiffPolicy DEFAULT_LINES = new LineBlocks(ComparisonPolicy.DEFAULT);
|
||||
@@ -32,7 +33,7 @@ public interface DiffPolicy {
|
||||
myComparisonPolicy = comparisonPolicy;
|
||||
}
|
||||
|
||||
public DiffFragment[] buildFragments(String text1, String text2) {
|
||||
public DiffFragment[] buildFragments(String text1, String text2) throws FilesTooBigForDiffException {
|
||||
String[] strings1 = new LineTokenizer(text1).execute();
|
||||
String[] strings2 = new LineTokenizer(text2).execute();
|
||||
return myComparisonPolicy.buildDiffFragmentsFromLines(strings1, strings2);
|
||||
@@ -47,7 +48,7 @@ public interface DiffPolicy {
|
||||
myComparisonPolicy = comparisonPolicy;
|
||||
}
|
||||
|
||||
public DiffFragment[] buildFragments(String text1, String text2) {
|
||||
public DiffFragment[] buildFragments(String text1, String text2) throws FilesTooBigForDiffException {
|
||||
return myComparisonPolicy.buildFragments(splitByChar(text1), splitByChar(text2));
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ public class Diff {
|
||||
}
|
||||
|
||||
public static <T> Change buildChanges(T[] objects1, T[] objects2) throws FilesTooBigForDiffException {
|
||||
|
||||
// Old variant of enumerator worked incorrectly with null values.
|
||||
// This check is to ensure that the corrected version does not introduce bugs.
|
||||
for (T anObjects1 : objects1) LOG.assertTrue(anObjects1 != null);
|
||||
@@ -175,6 +176,10 @@ public class Diff {
|
||||
private Change myFirstChange;
|
||||
private Change myLastChange;
|
||||
|
||||
public ChangeBuilder(final int startShift) {
|
||||
skip(startShift, startShift);
|
||||
}
|
||||
|
||||
public void addChange(int first, int second) {
|
||||
Change change = new Change(myIndex1, myIndex2, first, second, null);
|
||||
if (myLastChange != null) myLastChange.link = change;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.intellij.util.diff;
|
||||
|
||||
/**
|
||||
* @author irengrig
|
||||
* Date: 5/28/11
|
||||
* Time: 10:30 PM
|
||||
*/
|
||||
public class FilesTooBigForDiffException extends Exception {
|
||||
private final int myNumLines;
|
||||
|
||||
public FilesTooBigForDiffException(int numLines) {
|
||||
super("Can not calculate diff. File is too big and there are too many changes.");
|
||||
myNumLines = numLines;
|
||||
}
|
||||
|
||||
public int getNumLines() {
|
||||
return myNumLines;
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ class IntLCS {
|
||||
myCurrentEnds = new int[myMaxX + myMaxY + 1];
|
||||
}
|
||||
|
||||
public int execute() {
|
||||
public int execute() throws FilesTooBigForDiffException {
|
||||
for (int d =0; d <= myMaxX + myMaxY; d++) {
|
||||
int minDiag = -calcBound(myMaxY, d);
|
||||
int maxDiag = calcBound(myMaxX, d);
|
||||
@@ -103,7 +103,7 @@ class IntLCS {
|
||||
return skipEquals(x, y);
|
||||
}
|
||||
|
||||
private int encodeStep(int prevEnd, int diagLength, int tDiagonal, boolean afterVertical) {
|
||||
private int encodeStep(int prevEnd, int diagLength, int tDiagonal, boolean afterVertical) throws FilesTooBigForDiffException {
|
||||
int end = prevEnd + diagLength;
|
||||
int prevDiagonal = tDiagonal + myMaxY;
|
||||
if (!afterVertical) end++;
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.intellij.util.diff;
|
||||
* @author dyoma
|
||||
*/
|
||||
final class LinkedDiffPaths {
|
||||
private static final int MAX_LEN = 10000000;
|
||||
|
||||
private int[] mySteps = new int[10];
|
||||
private int[] myPrevSteps = new int[10];
|
||||
private int myPosition = 0;
|
||||
@@ -53,7 +55,7 @@ final class LinkedDiffPaths {
|
||||
return myMaxY + 1;
|
||||
}
|
||||
|
||||
public int encodeStep(int x, int y, int diagLength, boolean afterVertical, int prevIndex) {
|
||||
public int encodeStep(int x, int y, int diagLength, boolean afterVertical, int prevIndex) throws FilesTooBigForDiffException {
|
||||
int encodedPath = diagLength;
|
||||
if (afterVertical) encodedPath |= VERTICAL_DIRECTION_FLAG;
|
||||
int position = incPosition();
|
||||
@@ -64,7 +66,7 @@ final class LinkedDiffPaths {
|
||||
return position;
|
||||
}
|
||||
|
||||
private int incPosition() {
|
||||
private int incPosition() throws FilesTooBigForDiffException {
|
||||
int length = myPrevSteps.length;
|
||||
if (myPosition == length - 1) {
|
||||
myPrevSteps = copy(length, myPrevSteps);
|
||||
@@ -74,7 +76,10 @@ final class LinkedDiffPaths {
|
||||
return myPosition;
|
||||
}
|
||||
|
||||
private int[] copy(int length, int[] prevArray) {
|
||||
private int[] copy(int length, int[] prevArray) throws FilesTooBigForDiffException {
|
||||
if (length * 2 >= MAX_LEN) {
|
||||
throw new FilesTooBigForDiffException(MAX_LEN);
|
||||
}
|
||||
int[] array = new int[length * 2];
|
||||
System.arraycopy(prevArray, 0, array, 0, length);
|
||||
return array;
|
||||
|
||||
@@ -56,7 +56,7 @@ public class DiffTest extends TestCase {
|
||||
IntLCSTest.checkLastChange(change, 5, 5, 3, 0); // inserted: AB2
|
||||
}
|
||||
|
||||
public void testEqualUpToOneEnd() throws FilesTooBigFirDiffException {
|
||||
public void testEqualUpToOneEnd() throws FilesTooBigForDiffException {
|
||||
Diff.Change change = Diff.buildChanges(DATA_AB, new Object[]{"a", "b", "1"});
|
||||
IntLCSTest.checkLastChange(change, 2, 2, 1, 0);
|
||||
}
|
||||
|
||||
@@ -22,47 +22,47 @@ import junit.framework.TestCase;
|
||||
* @author dyoma
|
||||
*/
|
||||
public class IntLCSTest extends TestCase {
|
||||
public void testDiag() {
|
||||
public void testDiag() throws FilesTooBigForDiffException {
|
||||
Diff.Change change = buildChange(new int[]{1, 2, 3}, new int[]{1, 2, 3}, 0);
|
||||
assertNull(change);
|
||||
}
|
||||
|
||||
public void testOneAtBegging() {
|
||||
public void testOneAtBegging() throws FilesTooBigForDiffException {
|
||||
Diff.Change change = buildChange(new int[]{1, 2}, new int[]{1, 3}, 2);
|
||||
checkLastChange(change, 1, 1, 1, 1);
|
||||
}
|
||||
|
||||
public void testOneAntEnd() {
|
||||
public void testOneAntEnd() throws FilesTooBigForDiffException {
|
||||
Diff.Change change = buildChange(new int[]{1, 3}, new int[]{2, 3}, 2);
|
||||
checkLastChange(change, 0, 0, 1, 1);
|
||||
}
|
||||
|
||||
public void testOneOverAtEnd() {
|
||||
public void testOneOverAtEnd() throws FilesTooBigForDiffException {
|
||||
Diff.Change change = buildChange(new int[]{1, 2}, new int[]{1, 2, 3}, 1);
|
||||
checkLastChange(change, 2, 2, 1, 0);
|
||||
}
|
||||
|
||||
public void testOneOverAtBegging() {
|
||||
public void testOneOverAtBegging() throws FilesTooBigForDiffException {
|
||||
Diff.Change change = buildChange(new int[]{1, 2, 3}, new int[]{2, 3}, 1);
|
||||
checkLastChange(change, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public void testOneTail() {
|
||||
public void testOneTail() throws FilesTooBigForDiffException {
|
||||
assertEquals(1, new IntLCS(new int[]{1, 2}, new int[]{1, 2, 3}).execute());
|
||||
}
|
||||
|
||||
public void testSingleMiddle() {
|
||||
public void testSingleMiddle() throws FilesTooBigForDiffException {
|
||||
Diff.Change change = buildChange(new int[]{1, 2, 3}, new int[]{4, 2, 5}, 4);
|
||||
checkChange(change, 0, 0, 1, 1);
|
||||
checkLastChange(change.link, 2, 2, 1, 1);
|
||||
}
|
||||
|
||||
public void testAbsolutelyDifferent() {
|
||||
public void testAbsolutelyDifferent() throws FilesTooBigForDiffException {
|
||||
assertEquals(4, new IntLCS(new int[]{1, 2}, new int[]{3, 4}).execute());
|
||||
assertEquals(6, new IntLCS(new int[]{1, 2, 3}, new int[]{4, 5, 6}).execute());
|
||||
}
|
||||
|
||||
private Diff.Change buildChange(int[] first, int[] second, int expectedNonDiags) {
|
||||
private Diff.Change buildChange(int[] first, int[] second, int expectedNonDiags) throws FilesTooBigForDiffException {
|
||||
IntLCS intLCS = new IntLCS(first, second);
|
||||
assertEquals(expectedNonDiags, intLCS.execute());
|
||||
Reindexer reindexer = new Reindexer();
|
||||
|
||||
@@ -26,7 +26,7 @@ public class LinkedDiffPathsTest extends TestCase {
|
||||
return new LinkedDiffPaths(maxX, maxY);
|
||||
}
|
||||
|
||||
public void testOneDeleteAtferEnd() {
|
||||
public void testOneDeleteAtferEnd() throws FilesTooBigForDiffException {
|
||||
LinkedDiffPaths paths = createPaths(2, 3);
|
||||
int key = paths.encodeStep(1, 1, 2, false, -1);
|
||||
paths.encodeStep(1, 2, 0, true, key);
|
||||
@@ -34,14 +34,14 @@ public class LinkedDiffPathsTest extends TestCase {
|
||||
IntLCSTest.checkLastChange(change, 2, 2, 1, 0);
|
||||
}
|
||||
|
||||
public void testOneInsertedAtBegging() {
|
||||
public void testOneInsertedAtBegging() throws FilesTooBigForDiffException {
|
||||
LinkedDiffPaths paths = createPaths(3, 2);
|
||||
paths.encodeStep(2, 1, 2, false, -1);
|
||||
Diff.Change change = decode(paths);
|
||||
IntLCSTest.checkLastChange(change, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public void testSingleMiddleChange() {
|
||||
public void testSingleMiddleChange() throws FilesTooBigForDiffException {
|
||||
LinkedDiffPaths paths = createPaths(3, 3);
|
||||
int key = paths.encodeStep(0, 0, 1, true, -1);
|
||||
key = paths.encodeStep(1, 0, 0, false, key);
|
||||
@@ -49,7 +49,7 @@ public class LinkedDiffPathsTest extends TestCase {
|
||||
IntLCSTest.checkLastChange(decode(paths), 1, 1, 1, 1);
|
||||
}
|
||||
|
||||
public void testSingleChangeAtEnd() {
|
||||
public void testSingleChangeAtEnd() throws FilesTooBigForDiffException {
|
||||
LinkedDiffPaths paths = createPaths(2, 2);
|
||||
int key = paths.encodeStep(0, 0, 1, false, -1);
|
||||
key = paths.encodeStep(0, 1, 0, true, key);
|
||||
@@ -57,7 +57,7 @@ public class LinkedDiffPathsTest extends TestCase {
|
||||
IntLCSTest.checkLastChange(decode(paths), 1, 1, 1, 1);
|
||||
}
|
||||
|
||||
public void testNotSquareChangeAtEnd() {
|
||||
public void testNotSquareChangeAtEnd() throws FilesTooBigForDiffException {
|
||||
LinkedDiffPaths paths = createPaths(2, 3);
|
||||
int key = paths.encodeStep(0, 0, 1, false, -1);
|
||||
key = paths.encodeStep(0, 1, 0, true, key);
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.intellij.openapi.diff.impl.util.TextDiffTypeEnum;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.util.BeforeAfter;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -116,8 +117,15 @@ public class TextPatchBuilder {
|
||||
String[] beforeLines = new LineTokenizer(beforeContent).execute();
|
||||
String[] afterLines = new LineTokenizer(afterContent).execute();
|
||||
|
||||
DiffFragment[] woFormattingBlocks = DiffPolicy.LINES_WO_FORMATTING.buildFragments(beforeContent, afterContent);
|
||||
DiffFragment[] step1lineFragments = new DiffCorrection.TrueLineBlocks(ComparisonPolicy.DEFAULT).correctAndNormalize(woFormattingBlocks);
|
||||
DiffFragment[] woFormattingBlocks;
|
||||
DiffFragment[] step1lineFragments;
|
||||
try {
|
||||
woFormattingBlocks = DiffPolicy.LINES_WO_FORMATTING.buildFragments(beforeContent, afterContent);
|
||||
step1lineFragments = new DiffCorrection.TrueLineBlocks(ComparisonPolicy.DEFAULT).correctAndNormalize(woFormattingBlocks);
|
||||
}
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
throw new VcsException("File '" + myBasePath + "' is too big and there are too many changes to build diff", e);
|
||||
}
|
||||
ArrayList<LineFragment> fragments = new DiffFragmentsProcessor().process(step1lineFragments);
|
||||
|
||||
if (fragments.size() > 1 || (fragments.size() == 1 && fragments.get(0).getType() != null && fragments.get(0).getType() != TextDiffTypeEnum.NONE)) {
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.diff;
|
||||
|
||||
import com.intellij.openapi.util.text.LineTokenizer;
|
||||
import com.intellij.util.diff.Diff;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
/**
|
||||
* author: lesya
|
||||
@@ -36,7 +37,7 @@ public class FindBlock {
|
||||
}
|
||||
|
||||
|
||||
public Block getBlockInThePrevVersion() {
|
||||
public Block getBlockInThePrevVersion() throws FilesTooBigForDiffException {
|
||||
|
||||
Diff.Change change = Diff.buildChanges(myResult.getSource(), myCurrentVersion.getSource());
|
||||
while (change != null) {
|
||||
|
||||
@@ -33,7 +33,7 @@ import com.intellij.ui.TableSpeedSearch;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.components.JBLoadingPanel;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -271,7 +271,14 @@ public class DirDiffPanel implements Disposable {
|
||||
}
|
||||
clearDiffPanel();
|
||||
if (element.getType() == DType.CHANGED) {
|
||||
myDiffPanelComponent = element.getSource().getDiffComponent(element.getTarget(), project, myDiffWindow.getWindow());
|
||||
try {
|
||||
myDiffPanelComponent = element.getSource().getDiffComponent(element.getTarget(), project, myDiffWindow.getWindow());
|
||||
}
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
// todo KB: check
|
||||
myDiffPanelComponent = null;
|
||||
myErrorLabel = new JLabel("Can not build diff for file " + element.getTarget().getPath() + ". File is too big and there are too many changes.");
|
||||
}
|
||||
if (myDiffPanelComponent != null) {
|
||||
myDiffPanel.add(myDiffPanelComponent, BorderLayout.CENTER);
|
||||
myCurrentElement = element.getSource();
|
||||
|
||||
@@ -24,14 +24,18 @@ import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.openapi.editor.markup.*;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.VcsBundle;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.EditorNotificationPanel;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -46,6 +50,8 @@ import java.util.ListIterator;
|
||||
*/
|
||||
public class LineStatusTracker {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.ex.LineStatusTracker");
|
||||
private static final Key<CanNotCalculateDiffPanel> PANEL_KEY = new Key<CanNotCalculateDiffPanel>("LineStatusTracker.CanNotCalculateDiffPanel");
|
||||
|
||||
private final Object myLock = new Object();
|
||||
// true -> have contents
|
||||
private BaseLoadState myBaseLoaded;
|
||||
@@ -64,8 +70,12 @@ public class LineStatusTracker {
|
||||
@Nullable
|
||||
private RevisionPack myBaseRevisionNumber;
|
||||
private String myPreviousBaseRevision;
|
||||
private boolean myAnathemaThrown;
|
||||
private FileEditorManager myFileEditorManager;
|
||||
private final VirtualFile myVirtualFile;
|
||||
|
||||
private LineStatusTracker(final Document document, final Document upToDateDocument, final Project project) {
|
||||
private LineStatusTracker(final Document document, final Document upToDateDocument, final Project project, final VirtualFile virtualFile) {
|
||||
myVirtualFile = virtualFile;
|
||||
myApplication = ApplicationManager.getApplication();
|
||||
myDocument = document;
|
||||
myUpToDateDocument = upToDateDocument;
|
||||
@@ -73,6 +83,8 @@ public class LineStatusTracker {
|
||||
myProject = project;
|
||||
myBaseLoaded = BaseLoadState.LOADING;
|
||||
myRanges = new ArrayList<Range>();
|
||||
myAnathemaThrown = false;
|
||||
myFileEditorManager = FileEditorManager.getInstance(myProject);
|
||||
}
|
||||
|
||||
public void initialize(@NotNull final String upToDateContent, @NotNull RevisionPack baseRevisionNumber) {
|
||||
@@ -119,14 +131,34 @@ public class LineStatusTracker {
|
||||
myApplication.assertReadAccessAllowed();
|
||||
|
||||
synchronized (myLock) {
|
||||
removeAnathema();
|
||||
removeHighlightersFromMarkupModel();
|
||||
myRanges = new RangesBuilder(myDocument, myUpToDateDocument).getRanges();
|
||||
try {
|
||||
myRanges = new RangesBuilder(myDocument, myUpToDateDocument).getRanges();
|
||||
}
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
installAnathema();
|
||||
return;
|
||||
}
|
||||
for (final Range range : myRanges) {
|
||||
range.setHighlighter(createHighlighter(range));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeAnathema() {
|
||||
if (! myAnathemaThrown) return;
|
||||
myAnathemaThrown = false;
|
||||
final FileEditor[] editors = myFileEditorManager.getEditors(myVirtualFile);
|
||||
for (FileEditor editor : editors) {
|
||||
final CanNotCalculateDiffPanel panel = editor.getUserData(PANEL_KEY);
|
||||
if (panel != null) {
|
||||
myFileEditorManager.removeTopComponent(editor, panel);
|
||||
editor.putUserData(PANEL_KEY, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"AutoBoxing"})
|
||||
private RangeHighlighter createHighlighter(final Range range) {
|
||||
int first =
|
||||
@@ -163,6 +195,7 @@ public class LineStatusTracker {
|
||||
if (myDocumentListener != null) {
|
||||
myDocument.removeDocumentListener(myDocumentListener);
|
||||
}
|
||||
removeAnathema();
|
||||
removeHighlightersFromMarkupModel();
|
||||
myRanges.clear();
|
||||
}
|
||||
@@ -173,7 +206,7 @@ public class LineStatusTracker {
|
||||
}
|
||||
|
||||
public VirtualFile getVirtualFile() {
|
||||
return FileDocumentManager.getInstance().getFile(getDocument());
|
||||
return myVirtualFile;
|
||||
}
|
||||
|
||||
public List<Range> getRanges() {
|
||||
@@ -192,6 +225,7 @@ public class LineStatusTracker {
|
||||
public void startBulkUpdate() {
|
||||
synchronized (myLock) {
|
||||
myBulkUpdate = true;
|
||||
removeAnathema();
|
||||
removeHighlightersFromMarkupModel();
|
||||
myRanges.clear();
|
||||
}
|
||||
@@ -228,6 +262,7 @@ public class LineStatusTracker {
|
||||
myUpToDateDocument.setReadOnly(false);
|
||||
myUpToDateDocument.setText("");
|
||||
myUpToDateDocument.setReadOnly(true);
|
||||
removeAnathema();
|
||||
removeHighlightersFromMarkupModel();
|
||||
myRanges.clear();
|
||||
myBaseLoaded = BaseLoadState.LOADING;
|
||||
@@ -246,7 +281,7 @@ public class LineStatusTracker {
|
||||
myApplication.assertWriteAccessAllowed();
|
||||
|
||||
synchronized (myLock) {
|
||||
if (myBulkUpdate || (BaseLoadState.LOADED != myBaseLoaded)) return;
|
||||
if (myBulkUpdate || myAnathemaThrown || (BaseLoadState.LOADED != myBaseLoaded)) return;
|
||||
try {
|
||||
myFirstChangedLine = myDocument.getLineNumber(e.getOffset());
|
||||
myLastChangedLine = myDocument.getLineNumber(e.getOffset() + e.getOldLength());
|
||||
@@ -298,7 +333,7 @@ public class LineStatusTracker {
|
||||
myApplication.assertWriteAccessAllowed();
|
||||
|
||||
synchronized (myLock) {
|
||||
if (myBulkUpdate || (BaseLoadState.LOADED != myBaseLoaded)) return;
|
||||
if (myBulkUpdate || myAnathemaThrown || (BaseLoadState.LOADED != myBaseLoaded)) return;
|
||||
try {
|
||||
|
||||
int line = myDocument.getLineNumber(e.getOffset() + e.getNewLength());
|
||||
@@ -340,11 +375,15 @@ public class LineStatusTracker {
|
||||
}
|
||||
}
|
||||
} catch (ProcessCanceledException ignore) {
|
||||
} catch (FilesTooBigForDiffException e1) {
|
||||
installAnathema();
|
||||
removeHighlightersFromMarkupModel();
|
||||
myRanges.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Range> getNewChangedRanges() {
|
||||
private List<Range> getNewChangedRanges() throws FilesTooBigForDiffException {
|
||||
List<String> lines = new DocumentWrapper(myDocument).getLines(myFirstChangedLine, myLastChangedLine);
|
||||
List<String> uLines = new DocumentWrapper(myUpToDateDocument)
|
||||
.getLines(myUpToDateFirstLine, myUpToDateLastLine);
|
||||
@@ -567,9 +606,9 @@ public class LineStatusTracker {
|
||||
}
|
||||
}
|
||||
|
||||
public static LineStatusTracker createOn(final Document doc, final Project project) {
|
||||
public static LineStatusTracker createOn(@Nullable VirtualFile virtualFile, final Document doc, final Project project) {
|
||||
final Document document = new DocumentImpl(true);
|
||||
return new LineStatusTracker(doc, document, project);
|
||||
return new LineStatusTracker(doc, document, project, virtualFile);
|
||||
}
|
||||
|
||||
public void baseRevisionLoadFailed() {
|
||||
@@ -621,4 +660,23 @@ public class LineStatusTracker {
|
||||
return myRevision.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
private void installAnathema() {
|
||||
myAnathemaThrown = true;
|
||||
final FileEditor[] editors = myFileEditorManager.getAllEditors(myVirtualFile);
|
||||
for (FileEditor editor : editors) {
|
||||
CanNotCalculateDiffPanel panel = editor.getUserData(PANEL_KEY);
|
||||
if (panel == null) {
|
||||
final CanNotCalculateDiffPanel newPanel = new CanNotCalculateDiffPanel();
|
||||
editor.putUserData(PANEL_KEY, newPanel);
|
||||
myFileEditorManager.addTopComponent(editor, newPanel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CanNotCalculateDiffPanel extends EditorNotificationPanel {
|
||||
public CanNotCalculateDiffPanel() {
|
||||
myLabel.setText("Can not highlight changed lines. File is too big and there are too many changes.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.ex;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.diff.Diff;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@@ -29,11 +30,11 @@ import java.util.List;
|
||||
public class RangesBuilder {
|
||||
private List<Range> myRanges;
|
||||
|
||||
public RangesBuilder(Document current, Document upToDate) {
|
||||
public RangesBuilder(Document current, Document upToDate) throws FilesTooBigForDiffException {
|
||||
this(new DocumentWrapper(current).getLines(), new DocumentWrapper(upToDate).getLines(), 0, 0);
|
||||
}
|
||||
|
||||
public RangesBuilder(List<String> current, List<String> upToDate, int shift, int uShift) {
|
||||
public RangesBuilder(List<String> current, List<String> upToDate, int shift, int uShift) throws FilesTooBigForDiffException {
|
||||
myRanges = new LinkedList<Range>();
|
||||
|
||||
Diff.Change ch = Diff.buildChanges(ArrayUtil.toStringArray(upToDate), ArrayUtil.toStringArray(current));
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.intellij.openapi.vcs.history.*;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.table.TableView;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import com.intellij.util.text.DateFormatUtil;
|
||||
import com.intellij.util.ui.ColumnInfo;
|
||||
import com.intellij.util.ui.ListTableModel;
|
||||
@@ -240,7 +241,15 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
if (myIsInLoading) return;
|
||||
if (myChangesOnlyCheckBox.isSelected()) {
|
||||
loadContentsFor(myRevisions.toArray(new VcsFileRevision[myRevisions.size()]));
|
||||
((ListTableModel)myList.getModel()).setItems(filteredRevisions());
|
||||
try {
|
||||
((ListTableModel)myList.getModel()).setItems(filteredRevisions());
|
||||
}
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
myChangesOnlyCheckBox.setEnabled(false);
|
||||
myChangesOnlyCheckBox.setSelected(false);
|
||||
setErrorText(e.getMessage());
|
||||
((ListTableModel)myList.getModel()).setItems(myRevisions);
|
||||
}
|
||||
((ListTableModel)myList.getModel()).fireTableDataChanged();
|
||||
updateDiff(0, 0);
|
||||
|
||||
@@ -252,7 +261,7 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
|
||||
}
|
||||
|
||||
private List<VcsFileRevision> filteredRevisions() {
|
||||
private List<VcsFileRevision> filteredRevisions() throws FilesTooBigForDiffException {
|
||||
ArrayList<VcsFileRevision> result = new ArrayList<VcsFileRevision>();
|
||||
VcsFileRevision nextRevision = myRevisions.get(myRevisions.size() - 1);
|
||||
result.add(nextRevision);
|
||||
@@ -292,8 +301,13 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
}
|
||||
|
||||
if (myIsDisposed) return;
|
||||
myDiffPanel.setContents(new SimpleContent(getContentToShow(firstRev), myContentFileType),
|
||||
new SimpleContent(getContentToShow(secondRev), myContentFileType));
|
||||
try {
|
||||
myDiffPanel.setContents(new SimpleContent(getContentToShow(firstRev), myContentFileType),
|
||||
new SimpleContent(getContentToShow(secondRev), myContentFileType));
|
||||
}
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
myDiffPanel.setTooBigFileErrorContents();
|
||||
}
|
||||
myDiffPanel.setTitle1(VcsBundle.message("diff.content.title.revision.number", firstRev.getRevisionNumber()));
|
||||
myDiffPanel.setTitle2(VcsBundle.message("diff.content.title.revision.number", secondRev.getRevisionNumber()));
|
||||
|
||||
@@ -395,14 +409,14 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getContentToShow(VcsFileRevision revision) {
|
||||
protected String getContentToShow(VcsFileRevision revision) throws FilesTooBigForDiffException {
|
||||
final Block block = getBlock(revision);
|
||||
if (block == null) return "";
|
||||
return block.getBlockContent();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Block getBlock(VcsFileRevision revision){
|
||||
private Block getBlock(VcsFileRevision revision) throws FilesTooBigForDiffException {
|
||||
if (myRevisionToContentMap.containsKey(revision))
|
||||
return myRevisionToContentMap.get(revision);
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ public class LineStatusTrackerManager implements ProjectComponent, LineStatusTra
|
||||
if (myLineStatusTrackers.containsKey(document)) return;
|
||||
assert ! myPartner.containsKey(document);
|
||||
|
||||
final LineStatusTracker tracker = LineStatusTracker.createOn(document, myProject);
|
||||
final LineStatusTracker tracker = LineStatusTracker.createOn(virtualFile, document, myProject);
|
||||
myLineStatusTrackers.put(document, tracker);
|
||||
|
||||
startAlarm(document, virtualFile);
|
||||
|
||||
Reference in New Issue
Block a user