void (@NotNull PsiFile file, @NotNull Editor editor, @NotNull List<? extends HighlightInfo> infos) { ApplicationManager.getApplication().assertIsNonDispatchThread(); ApplicationManager.getApplication().assertReadAccessNotAllowed(); // have to be able to wait over the write action to finish, must not hold RA for that for (HighlightInfo info : infos) { PsiReference reference = info.unresolvedReference; if (reference == null) continue; if (info.isUnresolvedReferenceQuickFixesComputed()) continue; PsiElement refElement = ReadAction.compute(() -> reference.getElement()); Future<?> job = refElement.getUserData(JOB); if (job == null) { CompletableFuture<Object> newFuture = new CompletableFuture<>(); job = ((UserDataHolderEx)refElement).putUserDataIfAbsent(JOB, newFuture); if (job == newFuture) { try { ReadAction.run(() -> registerReferenceFixes(info, editor, file, reference, new ProperTextRange(file.getTextRange()))); newFuture.complete(null); } catch (Throwable t) { newFuture.completeExceptionally(t); } } } try { // wait outside RA job.get(100, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { throw new RuntimeException(e); } } }