@Override @NotNull public byte[] contentsToByteArray(@NotNull final VirtualFile file, boolean cacheContent) throws IOException { InputStream contentStream = null; boolean reloadFromDelegate; boolean outdated; int fileId; synchronized (myInputLock) { fileId = getFileId(file); outdated = checkFlag(fileId, MUST_RELOAD_CONTENT) || FSRecords.getLength(fileId) == -1L; reloadFromDelegate = outdated || (contentStream = readContent(file)) == null; } if (reloadFromDelegate) { final NewVirtualFileSystem delegate = getDelegate(file); final byte[] content; if (outdated) { // in this case, file can have out-of-date length. so, update it first (it's needed for // correct contentsToByteArray() work) // see IDEA-90813 for possible bugs FSRecords.setLength(fileId, delegate.getLength(file)); content = delegate.contentsToByteArray(file); } else { // a bit of optimization content = delegate.contentsToByteArray(file); FSRecords.setLength(fileId, content.length); } ApplicationEx application = (ApplicationEx) ApplicationManager.getApplication(); // we should cache every local files content // because the local history feature is currently depends on this cache, // perforce offline mode as well if ((!delegate.isReadOnly() || // do not cache archive content unless asked cacheContent && !application.isInternal() && !application.isUnitTestMode()) && content.length <= PersistentFSConstants.FILE_LENGTH_TO_CACHE_THRESHOLD) { synchronized (myInputLock) { writeContent(file, new ByteSequence(content), delegate.isReadOnly()); setFlag(file, MUST_RELOAD_CONTENT, false); } } return content; } else { try { final int length = (int) file.getLength(); assert length >= 0 : file; return FileUtil.loadBytes(contentStream, length); } catch (IOException e) { throw FSRecords.handleError(e); } } }
@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; }