@NotNull private TIntHashSet calcForwardRefs( @NotNull final VirtualFile virtualFile, @NotNull final ProgressIndicator indicator) throws IndexNotReadyException, ApplicationUtil.CannotRunReadActionException { final TIntHashSet forward = new TIntHashSet(); final PsiFile psiFile = ApplicationUtil.tryRunReadAction( () -> { if (myProject.isDisposed()) throw new ProcessCanceledException(); if (fileCount.incrementAndGet() % 100 == 0) { PsiManager.getInstance(myProject).dropResolveCaches(); try { storage.flush(); log.flush(); } catch (IOException e) { LOG.error(e); } } return PsiManager.getInstance(myProject).findFile(virtualFile); }); final int fileId = getAbsId(virtualFile); if (psiFile != null) { bytesSize.addAndGet(virtualFile.getLength()); final Set<PsiElement> resolved = new THashSet<PsiElement>(); ApplicationUtil.tryRunReadAction( new Runnable() { @Override public void run() { indicator.checkCanceled(); if (psiFile instanceof PsiJavaFile) { psiFile.accept( new JavaRecursiveElementWalkingVisitor() { @Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { indicator.checkCanceled(); resolveReference(reference, resolved); super.visitReferenceElement(reference); } }); } else { psiFile.accept( new PsiRecursiveElementWalkingVisitor() { @Override public void visitElement(PsiElement element) { for (PsiReference reference : element.getReferences()) { indicator.checkCanceled(); resolveReference(reference, resolved); } super.visitElement(element); } }); } indicator.checkCanceled(); for (PsiElement element : resolved) { PsiFile file = element.getContainingFile(); addIdAndSuperClasses(file, forward); } } }); } forward.remove(fileId); return forward; }
private void initListeners(@NotNull MessageBus messageBus, @NotNull PsiManager psiManager) { messageBus .connect() .subscribe( VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() { @Override public void after(@NotNull List<? extends VFileEvent> events) { fileCount.set(0); List<VirtualFile> files = ContainerUtil.mapNotNull( events, new Function<VFileEvent, VirtualFile>() { @Override public VirtualFile fun(VFileEvent event) { return event.getFile(); } }); queue(files, "VFS events " + events.size()); } }); psiManager.addPsiTreeChangeListener( new PsiTreeChangeAdapter() { @Override public void childrenChanged(@NotNull PsiTreeChangeEvent event) { PsiFile file = event.getFile(); VirtualFile virtualFile = PsiUtilCore.getVirtualFile(file); if (virtualFile != null) { queue(Collections.singletonList(virtualFile), event); } } @Override public void propertyChanged(@NotNull PsiTreeChangeEvent event) { childrenChanged(event); } }); messageBus .connect() .subscribe( DumbService.DUMB_MODE, new DumbService.DumbModeListener() { @Override public void enteredDumbMode() { disable(); } @Override public void exitDumbMode() { enable(); } }); messageBus .connect() .subscribe( PowerSaveMode.TOPIC, new PowerSaveMode.Listener() { @Override public void powerSaveStateChanged() { if (PowerSaveMode.isEnabled()) { enable(); } else { disable(); } } }); myApplication.addApplicationListener( new ApplicationAdapter() { @Override public void beforeWriteActionStart(@NotNull Object action) { disable(); } @Override public void writeActionFinished(@NotNull Object action) { enable(); } @Override public void applicationExiting() { disable(); } }, this); VirtualFileManager.getInstance() .addVirtualFileManagerListener( new VirtualFileManagerListener() { @Override public void beforeRefreshStart(boolean asynchronous) { disable(); } @Override public void afterRefreshFinish(boolean asynchronous) { enable(); } }, this); HeavyProcessLatch.INSTANCE.addListener( new HeavyProcessLatch.HeavyProcessListener() { @Override public void processStarted() {} @Override public void processFinished() { wakeUp(); } }, this); }