avoid editor (and project) leaking in tests (from pending task to be executed in EDT in AsyncEditorLoader)

also makes sure editor asynchronous loading always 'finishes' (as reported by AsyncEditorLoader.isEditorLoaded)
even if exception occurred during loading
This commit is contained in:
Dmitry Batrak
2016-12-28 18:42:23 +03:00
parent 05324198e3
commit 314333e4e9
4 changed files with 37 additions and 16 deletions
@@ -91,23 +91,27 @@ public class AsyncEditorLoader {
long startStamp = myEditor.getDocument().getModificationStamp();
return ourExecutor.submit(() -> {
Ref<Runnable> ref = new Ref<>();
while (!myEditorComponent.isDisposed()) {
ProgressIndicatorUtils.runWithWriteActionPriority(
() -> ref.set(psiDocumentManager.commitAndRunReadAction(() -> myProject.isDisposed() ? EmptyRunnable.INSTANCE
: myTextEditor.loadEditorInBackground())),
new ProgressIndicatorBase()
);
Runnable continuation = ref.get();
if (continuation != null) {
invokeLater(() -> {
if (startStamp == myEditor.getDocument().getModificationStamp()) loadingFinished(continuation);
else if (!myProject.isDisposed() && !myEditorComponent.isDisposed()) scheduleLoading();
});
return continuation;
try {
while (!myEditorComponent.isDisposed()) {
ProgressIndicatorUtils.runWithWriteActionPriority(
() -> ref.set(psiDocumentManager.commitAndRunReadAction(() -> myProject.isDisposed() ? EmptyRunnable.INSTANCE
: myTextEditor.loadEditorInBackground())),
new ProgressIndicatorBase()
);
Runnable continuation = ref.get();
if (continuation != null) {
invokeLater(() -> {
if (startStamp == myEditor.getDocument().getModificationStamp()) loadingFinished(continuation);
else if (!myProject.isDisposed() && !myEditorComponent.isDisposed()) scheduleLoading();
});
return continuation;
}
TimeUnit.MILLISECONDS.sleep(RETRY_TIME_MS);
}
TimeUnit.MILLISECONDS.sleep(RETRY_TIME_MS);
}
invokeLater(() -> loadingFinished(null));
finally {
if (ref.isNull()) invokeLater(() -> loadingFinished(null));
}
return null;
});
}
@@ -38,6 +38,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.WritingAccessProvider;
import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.ui.EditorNotifications;
import com.intellij.ui.EditorNotificationsImpl;
@@ -393,7 +394,9 @@ public class NonProjectFileAccessTest extends HeavyFileEditorManagerTestCase {
private Editor getEditor(VirtualFile file) {
myOpenedFiles.add(file);
return FileEditorManager.getInstance(getProject()).openTextEditor(new OpenFileDescriptor(getProject(), file, 0), false);
Editor editor = FileEditorManager.getInstance(getProject()).openTextEditor(new OpenFileDescriptor(getProject(), file, 0), false);
EditorTestUtil.waitForLoading(editor);
return editor;
}
protected void typeInChar(Editor e, char c) {
@@ -20,6 +20,7 @@ import com.intellij.injected.editor.EditorWindow;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.*;
@@ -34,12 +35,14 @@ import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
import com.intellij.openapi.editor.impl.softwrap.SoftWrapDrawingType;
import com.intellij.openapi.editor.impl.softwrap.SoftWrapPainter;
import com.intellij.openapi.editor.impl.softwrap.mapping.SoftWrapApplianceManager;
import com.intellij.openapi.fileEditor.impl.text.AsyncEditorLoader;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -49,6 +52,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.LockSupport;
import static org.junit.Assert.*;
@@ -466,6 +470,15 @@ public class EditorTestUtil {
});
}
public static void waitForLoading(Editor editor) {
ApplicationManager.getApplication().assertIsDispatchThread();
if (editor == null) return;
while (!AsyncEditorLoader.isEditorLoaded(editor)) {
LockSupport.parkNanos(100_000_000);
UIUtil.dispatchAllInvocationEvents();
}
}
public static class CaretAndSelectionState {
public final List<CaretInfo> carets;
public final TextRange blockSelection;
@@ -1377,6 +1377,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
Editor editor = instance.openTextEditor(new OpenFileDescriptor(project, file), false);
EditorTestUtil.waitForLoading(editor);
if (editor != null) {
DaemonCodeAnalyzer.getInstance(getProject()).restart();
}