diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java index 316b7b2d55d1..2ee91a9a65ed 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java @@ -56,7 +56,7 @@ public class LineStatusTracker { new Key("LineStatusTracker.CanNotCalculateDiffPanel"); private final Object myLock = new Object(); - private BaseLoadState myBaseLoaded; + private boolean myInitialized; @NotNull private final Project myProject; @NotNull private final Document myDocument; @@ -91,8 +91,6 @@ public class LineStatusTracker { myVcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject); myRanges = new ArrayList(); - - myBaseLoaded = BaseLoadState.LOADING; } public void initialize(@NotNull final String vcsContent, @NotNull RevisionPack baseRevisionNumber) { @@ -116,7 +114,7 @@ public class LineStatusTracker { } } finally { - myBaseLoaded = BaseLoadState.LOADED; + myInitialized = true; } } } @@ -311,7 +309,7 @@ public class LineStatusTracker { synchronized (myLock) { if (myReleased) return; - if (myBulkUpdate || mySuppressUpdate || myAnathemaThrown || BaseLoadState.LOADED != myBaseLoaded) return; + if (myBulkUpdate || mySuppressUpdate || myAnathemaThrown || !myInitialized) return; assert myDocument == e.getDocument(); try { @@ -338,7 +336,7 @@ public class LineStatusTracker { synchronized (myLock) { if (myReleased) return; - if (myBulkUpdate || mySuppressUpdate || myAnathemaThrown || BaseLoadState.LOADED != myBaseLoaded) return; + if (myBulkUpdate || mySuppressUpdate || myAnathemaThrown || !myInitialized) return; assert myDocument == e.getDocument(); int afterChangedLines; @@ -897,18 +895,6 @@ public class LineStatusTracker { return new LineStatusTracker(doc, document, project, virtualFile); } - public void baseRevisionLoadFailed() { - synchronized (myLock) { - myBaseLoaded = BaseLoadState.FAILED; - } - } - - public enum BaseLoadState { - LOADING, - FAILED, - LOADED - } - public static class RevisionPack { private final long myNumber; private final VcsRevisionNumber myRevision; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.java index 24d93eaf2bae..b4a2e7592697 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.java @@ -186,13 +186,25 @@ public class LineStatusTrackerManager implements ProjectComponent, LineStatusTra @Override public LineStatusTracker getLineStatusTracker(final Document document) { myApplication.assertReadAccessAllowed(); - if (isDisabled()) return null; - synchronized (myLock) { + if (isDisabled()) return null; + return myLineStatusTrackers.get(document); } } + private void resetTrackersForOpenFiles() { + myApplication.assertReadAccessAllowed(); + if (isDisabled()) return; + + log("LineStatusTrackerManager: fileStatusesChanged"); + + final VirtualFile[] openFiles = myFileEditorManager.getOpenFiles(); + for (final VirtualFile openFile : openFiles) { + resetTracker(openFile); + } + } + private void resetTracker(@NotNull final VirtualFile virtualFile) { myApplication.assertReadAccessAllowed(); if (isDisabled()) return; @@ -206,40 +218,29 @@ public class LineStatusTrackerManager implements ProjectComponent, LineStatusTra log("resetting tracker for file " + virtualFile.getPath()); final boolean editorOpened = myFileEditorManager.isFileOpen(virtualFile); - final boolean shouldBeInstalled = shouldBeInstalled(virtualFile) && editorOpened; + final boolean shouldBeInstalled = editorOpened && shouldBeInstalled(virtualFile); synchronized (myLock) { final LineStatusTracker tracker = myLineStatusTrackers.get(document); - if (tracker == null && (!shouldBeInstalled)) return; - - if (tracker != null) { + if (tracker != null && shouldBeInstalled) { + refreshTracker(tracker); + } + else if (tracker != null) { releaseTracker(document); } - if (shouldBeInstalled) { + else if (shouldBeInstalled) { installTracker(virtualFile, document); } } } - private void releaseTracker(@NotNull final Document document) { - if (isDisabled()) return; - - synchronized (myLock) { - myPartner.remove(document); - final LineStatusTracker tracker = myLineStatusTrackers.remove(document); - if (tracker != null) { - tracker.release(); - } - } - } - private boolean shouldBeInstalled(@Nullable final VirtualFile virtualFile) { - ApplicationManager.getApplication().assertIsDispatchThread(); + myApplication.assertIsDispatchThread(); + if (isDisabled()) return false; if (virtualFile == null || virtualFile instanceof LightVirtualFile) return false; if (!virtualFile.isInLocalFileSystem()) return false; - if (isDisabled()) return false; final FileStatusManager statusManager = FileStatusManager.getInstance(myProject); if (statusManager == null) return false; final AbstractVcs activeVcs = myVcsManager.getVcsFor(virtualFile); @@ -255,8 +256,30 @@ public class LineStatusTrackerManager implements ProjectComponent, LineStatusTra return true; } + private void refreshTracker(@NotNull LineStatusTracker tracker) { + synchronized (myLock) { + if (isDisabled()) return; + + startAlarm(tracker.getDocument(), tracker.getVirtualFile()); + } + } + + private void releaseTracker(@NotNull final Document document) { + synchronized (myLock) { + if (isDisabled()) return; + + myPartner.remove(document); + final LineStatusTracker tracker = myLineStatusTrackers.remove(document); + if (tracker != null) { + tracker.release(); + } + } + } + private void installTracker(@NotNull final VirtualFile virtualFile, @NotNull final Document document) { synchronized (myLock) { + if (isDisabled()) return; + if (myLineStatusTrackers.containsKey(document)) return; assert !myPartner.containsKey(document); @@ -296,7 +319,7 @@ public class LineStatusTrackerManager implements ProjectComponent, LineStatusTra final Pair baseRevision = myStatusProvider.getBaseRevision(myVirtualFile); if (baseRevision == null) { - log("installTracker() for file " + myVirtualFile.getPath() + " failed: null returned for base revision number"); + log("installTracker() for file " + myVirtualFile.getPath() + " failed: null returned for base revision"); reportTrackerBaseLoadFailed(); return; } @@ -304,7 +327,7 @@ public class LineStatusTrackerManager implements ProjectComponent, LineStatusTra // loads are sequential (in single threaded QueueProcessor); // so myLoadCounter can't take less value for greater base revision -> the only thing we want from it final LineStatusTracker.RevisionPack revisionPack = new LineStatusTracker.RevisionPack(myLoadCounter, baseRevision.first); - ++myLoadCounter; + myLoadCounter++; final String converted = StringUtil.convertLineSeparators(baseRevision.second); final Runnable runnable = new Runnable() { @@ -333,28 +356,13 @@ public class LineStatusTrackerManager implements ProjectComponent, LineStatusTra private void reportTrackerBaseLoadFailed() { synchronized (myLock) { log("base revision load failed for file " + myVirtualFile.getPath()); - final LineStatusTracker tracker = myLineStatusTrackers.get(myDocument); - if (tracker != null) { - tracker.baseRevisionLoadFailed(); - } + releaseTracker(myDocument); } } } - private void resetTrackersForOpenFiles() { - myApplication.assertReadAccessAllowed(); - if (isDisabled()) return; - - final VirtualFile[] openFiles = myFileEditorManager.getOpenFiles(); - for (final VirtualFile openFile : openFiles) { - resetTracker(openFile); - } - } - private class MyFileStatusListener implements FileStatusListener { public void fileStatusesChanged() { - if (myProject.isDisposed()) return; - log("LineStatusTrackerManager: fileStatusesChanged"); resetTrackersForOpenFiles(); } @@ -371,12 +379,13 @@ public class LineStatusTrackerManager implements ProjectComponent, LineStatusTra if (editor.getProject() != null && editor.getProject() != myProject) return; final Document document = editor.getDocument(); final VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document); + if (virtualFile == null) return; + // TODO: is there possible race between editorCreated / editorReleased ? new AbstractCalledLater(myProject, ModalityState.NON_MODAL) { @Override public void run() { if (shouldBeInstalled(virtualFile)) { - assert virtualFile != null; installTracker(virtualFile, document); } }