project leak: clean fields in case of injected editors too

This commit is contained in:
Alexey Kudravtsev
2017-02-07 14:36:46 +03:00
parent f374cc7d19
commit ea76551d54
2 changed files with 26 additions and 43 deletions
@@ -24,15 +24,15 @@ import org.jetbrains.annotations.Nullable;
* <p>
* It's supposed to be used from EDT only.
*/
public abstract class EditorLastActionTracker {
public static EditorLastActionTracker getInstance() {
public interface EditorLastActionTracker {
static EditorLastActionTracker getInstance() {
return ApplicationManager.getApplication().getComponent(EditorLastActionTracker.class);
}
/**
* Returns the id of the previously invoked action or <code>null</code>, if no history exists yet, or last user activity was of
* Returns the id of the previously invoked action or {@code null}, if no history exists yet, or last user activity was of
* non-action type, like mouse clicking in editor or text typing, or previous action was invoked for a different editor.
*/
@Nullable
public abstract String getLastActionId();
String getLastActionId();
}
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.editor.impl;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.AnActionListener;
@@ -22,16 +23,12 @@ import com.intellij.openapi.components.ApplicationComponentAdapter;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.EditorLastActionTracker;
import com.intellij.openapi.editor.event.EditorEventMulticaster;
import com.intellij.openapi.editor.event.EditorMouseEvent;
import com.intellij.openapi.editor.event.EditorMouseListener;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.editor.event.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class EditorLastActionTrackerImpl extends EditorLastActionTracker implements ApplicationComponentAdapter, AnActionListener, EditorMouseListener, Disposable {
private static final Key<Boolean> DISPOSABLE_SET = Key.create("EditorLastActionTracker.dispose.handler.set");
public class EditorLastActionTrackerImpl extends EditorMouseAdapter
implements ApplicationComponentAdapter, AnActionListener, EditorMouseListener, Disposable, EditorLastActionTracker {
private final ActionManager myActionManager;
private final EditorEventMulticaster myEditorEventMulticaster;
@@ -42,6 +39,23 @@ public class EditorLastActionTrackerImpl extends EditorLastActionTracker impleme
EditorLastActionTrackerImpl(ActionManager actionManager, EditorFactory editorFactory) {
myActionManager = actionManager;
myEditorEventMulticaster = editorFactory.getEventMulticaster();
// to prevent leaks
editorFactory.addEditorFactoryListener(new EditorFactoryAdapter() {
@Override
public void editorReleased(@NotNull EditorFactoryEvent event) {
EditorImpl killedEditor = (EditorImpl)event.getEditor();
if (is(myCurrentEditor, killedEditor)) {
myCurrentEditor = null;
}
if (is(myLastEditor, killedEditor)) {
myLastEditor = null;
}
}
}, this);
}
private static boolean is(Editor currentEditor, EditorImpl killedEditor) {
return currentEditor == killedEditor || currentEditor instanceof EditorWindow && ((EditorWindow)currentEditor).getDelegate() == killedEditor;
}
@Override
@@ -63,7 +77,6 @@ public class EditorLastActionTrackerImpl extends EditorLastActionTracker impleme
@Override
public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) {
myCurrentEditor = CommonDataKeys.EDITOR.getData(dataContext);
registerDisposeHandler(myCurrentEditor);
if (myCurrentEditor != myLastEditor) {
resetLastAction();
}
@@ -96,16 +109,6 @@ public class EditorLastActionTrackerImpl extends EditorLastActionTracker impleme
resetLastAction();
}
@Override
public void mouseEntered(EditorMouseEvent e) {
}
@Override
public void mouseExited(EditorMouseEvent e) {
}
private String getActionId(AnAction action) {
return action instanceof ActionStub ? ((ActionStub)action).getId() : myActionManager.getId(action);
}
@@ -114,24 +117,4 @@ public class EditorLastActionTrackerImpl extends EditorLastActionTracker impleme
myLastActionId = null;
myLastEditor = null;
}
private void registerDisposeHandler(final Editor editor) {
if (!(editor instanceof EditorImpl)) {
return;
}
EditorImpl editorImpl = (EditorImpl)editor;
if (!editorImpl.isDisposed() && editorImpl.replace(DISPOSABLE_SET, null, Boolean.TRUE)) {
Disposer.register(editorImpl.getDisposable(), new Disposable() {
@Override
public void dispose() {
if (myCurrentEditor == editor) {
myCurrentEditor = null;
}
if (myLastEditor == editor) {
myLastEditor = null;
}
}
});
}
}
}