void (boolean mustCancelItself, @NotNull Runnable action) { PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); highlightErrors(); myDaemonCodeAnalyzer.waitForTermination(); TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(getEditor()); AtomicBoolean run = new AtomicBoolean(); Disposable disposable = Disposer.newDisposable(); AtomicReference<RuntimeException> stopDaemonReason = new AtomicReference<>(); StorageUtilKt.setDEBUG_LOG(""); getProject().getMessageBus().connect(disposable).subscribe(DaemonCodeAnalyzer.DAEMON_EVENT_TOPIC, new DaemonCodeAnalyzer.DaemonListener() { @Override public void daemonCancelEventOccurred(@NotNull String reason) { RuntimeException e = new RuntimeException("Some bastard's restarted daemon: " + reason + "\nStorage write log: ----------\n" + StorageUtilKt.getDEBUG_LOG() + "\n--------------"); stopDaemonReason.compareAndSet(null, e); } }); try { while (true) { try { int[] toIgnore = new int[0]; Runnable callbackWhileWaiting = () -> { if (!run.getAndSet(true)) { action.run(); } }; myDaemonCodeAnalyzer.runPasses(getFile(), getDocument(getFile()), textEditor, toIgnore, true, callbackWhileWaiting); break; } catch (ProcessCanceledException ignored) { } } if (mustCancelItself) { assertNotNull(stopDaemonReason.get()); } else { if (stopDaemonReason.get() != null) throw stopDaemonReason.get(); } } finally { StorageUtilKt.setDEBUG_LOG(null); Disposer.dispose(disposable); } }