diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java b/platform/lang-api/src/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java index 7a989a8311a9..62bc48d80351 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java +++ b/platform/lang-api/src/com/intellij/codeInsight/daemon/DaemonCodeAnalyzer.java @@ -31,16 +31,16 @@ public abstract class DaemonCodeAnalyzer { public abstract void settingsChanged(); @Deprecated - public abstract void updateVisibleHighlighters(Editor editor); + public abstract void updateVisibleHighlighters(@NotNull Editor editor); public abstract void setUpdateByTimerEnabled(boolean value); public abstract boolean isHighlightingAvailable(PsiFile file); - public abstract void setImportHintsEnabled(PsiFile file, boolean value); + public abstract void setImportHintsEnabled(@NotNull PsiFile file, boolean value); public abstract void resetImportHintsEnabledForProject(); - public abstract void setHighlightingEnabled(PsiFile file, boolean value); - public abstract boolean isImportHintsEnabled(PsiFile file); + public abstract void setHighlightingEnabled(@NotNull PsiFile file, boolean value); + public abstract boolean isImportHintsEnabled(@NotNull PsiFile file); public abstract boolean isAutohintsAvailable(PsiFile file); /** @@ -55,5 +55,6 @@ public abstract class DaemonCodeAnalyzer { public interface DaemonListener { void daemonFinished(); + void daemonCancelEventOccurred(); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java index a58325cae261..84c3ac58c788 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java @@ -252,14 +252,12 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx } @TestOnly - public void cleanupAfterTest(boolean forceDispose) { + public void cleanupAfterTest() { projectClosed(); - if (forceDispose) { - Disposer.dispose(myStatusBarUpdater); - myStatusBarUpdater = null; - Disposer.dispose(myDaemonListeners); - myDaemonListeners = null; - } + Disposer.dispose(myStatusBarUpdater); + myStatusBarUpdater = null; + Disposer.dispose(myDaemonListeners); + myDaemonListeners = null; setUpdateByTimerEnabled(false); waitForTermination(); } @@ -298,9 +296,6 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx assert myInitialized : "Disposing not initialized component"; assert !myDisposed : "Double dispose"; - // clear dangling references to PsiFiles/Documents. SCR#10358 - myFileStatusMap.markAllFilesDirty(); - stopProcess(false); myDisposed = true; @@ -370,7 +365,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx return myUpdateByTimerEnabled; } - public void setImportHintsEnabled(PsiFile file, boolean value) { + public void setImportHintsEnabled(@NotNull PsiFile file, boolean value) { VirtualFile vFile = file.getVirtualFile(); if (value) { myDisabledHintsFiles.remove(vFile); @@ -386,7 +381,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx myDisabledHintsFiles.clear(); } - public void setHighlightingEnabled(PsiFile file, boolean value) { + public void setHighlightingEnabled(@NotNull PsiFile file, boolean value) { if (value) { myDisabledHighlightingFiles.remove(file); } @@ -408,7 +403,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx return !fileType.isBinary(); } - public boolean isImportHintsEnabled(PsiFile file) { + public boolean isImportHintsEnabled(@NotNull PsiFile file) { return isAutohintsAvailable(file) && !myDisabledHintsFiles.contains(file.getVirtualFile()); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java index cfd6d91d0a49..0746219ef8f5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.daemon.impl; import com.intellij.ProjectTopics; import com.intellij.codeHighlighting.Pass; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.codeInsight.hint.TooltipController; import com.intellij.ide.PowerSaveMode; import com.intellij.ide.todo.TodoConfiguration; @@ -51,6 +52,8 @@ import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.roots.ModuleRootEvent; import com.intellij.openapi.roots.ModuleRootListener; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.UserDataHolderEx; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; import com.intellij.openapi.vfs.VirtualFile; @@ -63,6 +66,7 @@ import com.intellij.profile.codeInspection.InspectionProfileManager; import com.intellij.psi.*; import com.intellij.psi.impl.PsiDocumentManagerImpl; import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; +import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.UIUtil; import gnu.trove.THashSet; @@ -89,12 +93,18 @@ class DaemonListeners implements Disposable { private volatile boolean cutOperationJustHappened; private final EditorTracker myEditorTracker; + private final DaemonCodeAnalyzer.DaemonListener myDaemonEventPublisher; + private static final Key DAEMON_INITIALIZED = Key.create("DAEMON_INITIALIZED"); public DaemonListeners(Project project, DaemonCodeAnalyzerImpl daemonCodeAnalyzer, EditorTracker editorTracker) { myProject = project; myDaemonCodeAnalyzer = daemonCodeAnalyzer; + LOG.assertTrue(((UserDataHolderEx)myProject).replace(DAEMON_INITIALIZED, null, Boolean.TRUE), "Daemon listeners already initialized for the project "+myProject); + + MessageBus messageBus = myProject.getMessageBus(); + myDaemonEventPublisher = messageBus.syncPublisher(DaemonCodeAnalyzer.DAEMON_EVENT_TOPIC); + final MessageBusConnection connection = messageBus.connect(); - final MessageBusConnection connection = myProject.getMessageBus().connect(); EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster(); eventMulticaster.addDocumentListener(new DocumentAdapter() { @@ -184,11 +194,11 @@ class DaemonListeners implements Disposable { connection.subscribe(DumbService.DUMB_MODE, new DumbService.DumbModeListener() { public void enteredDumbMode() { - myDaemonCodeAnalyzer.restart(); + stopDaemonAndRestartAllFiles(); } public void exitDumbMode() { - myDaemonCodeAnalyzer.restart(); + stopDaemonAndRestartAllFiles(); } }); @@ -199,6 +209,7 @@ class DaemonListeners implements Disposable { } }); + CommandProcessor.getInstance().addCommandListener(new MyCommandListener(), this); ApplicationListener applicationListener = new MyApplicationListener(); ApplicationManager.getApplication().addApplicationListener(applicationListener, this); @@ -210,7 +221,7 @@ class DaemonListeners implements Disposable { public void propertyChanged(VirtualFilePropertyEvent event) { String propertyName = event.getPropertyName(); if (VirtualFile.PROP_NAME.equals(propertyName)) { - myDaemonCodeAnalyzer.restart(); + stopDaemonAndRestartAllFiles(); PsiFile psiFile = PsiManager.getInstance(myProject).findFile(event.getFile()); if (psiFile != null && !myDaemonCodeAnalyzer.isHighlightingAvailable(psiFile)) { Document document = FileDocumentManager.getInstance().getCachedDocument(event.getFile()); @@ -274,6 +285,7 @@ class DaemonListeners implements Disposable { } public void dispose() { + LOG.assertTrue(((UserDataHolderEx)myProject).replace(DAEMON_INITIALIZED, Boolean.TRUE, null), "Daemon listeners already disposed for the project "+myProject); } boolean canChangeFileSilently(PsiFileSystemItem file) { @@ -382,25 +394,25 @@ class DaemonListeners implements Disposable { private class MyEditorColorsListener implements EditorColorsListener { public void globalSchemeChange(EditorColorsScheme scheme) { - myDaemonCodeAnalyzer.restart(); + stopDaemonAndRestartAllFiles(); } } private class MyTodoListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent evt) { if (TodoConfiguration.PROP_TODO_PATTERNS.equals(evt.getPropertyName())) { - myDaemonCodeAnalyzer.restart(); + stopDaemonAndRestartAllFiles(); } } } private class MyProfileChangeListener extends ProfileChangeAdapter { public void profileChanged(Profile profile) { - myDaemonCodeAnalyzer.restart(); + stopDaemonAndRestartAllFiles(); } public void profileActivated(Profile oldProfile, Profile profile) { - myDaemonCodeAnalyzer.restart(); + stopDaemonAndRestartAllFiles(); } } @@ -469,9 +481,15 @@ class DaemonListeners implements Disposable { } private void stopDaemon(boolean toRestartAlarm) { + myDaemonEventPublisher.daemonCancelEventOccurred(); myDaemonCodeAnalyzer.stopProcess(toRestartAlarm); } + private void stopDaemonAndRestartAllFiles() { + myDaemonEventPublisher.daemonCancelEventOccurred(); + myDaemonCodeAnalyzer.restart(); + } + Collection getSelectedEditors() { // Editors in modal context List editors = myEditorTracker.getActiveEditors(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/StatusBarUpdater.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/StatusBarUpdater.java index 6606a78841af..71c57dc24609 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/StatusBarUpdater.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/StatusBarUpdater.java @@ -63,6 +63,10 @@ public class StatusBarUpdater implements Disposable { public void daemonFinished() { updateLater(); } + + @Override + public void daemonCancelEventOccurred() { + } }); }