public boolean isMarkedAsPlainText(@NotNull VirtualFile file) { if (!(file instanceof VirtualFileWithId) || file.isDirectory()) return false; if (!mySetsInitialized) { synchronized (LOCK) { if (!mySetsInitialized) { initPlainTextFileSets(); mySetsInitialized = true; } } } if (!myPlainTextFileSets.isEmpty()) { for (Collection<VirtualFile> projectSet : myPlainTextFileSets.values()) { if (projectSet != null && projectSet.contains(file)) return true; } } return false; }
@Override public boolean value(VirtualFile file) { if (myIndexableFilesFilter != null && !myIndexableFilesFilter.containsFileId(((VirtualFileWithId)file).getId())) { if (myFilesFromOtherProjects >= MAX_FILES_TO_UPDATE_FROM_OTHER_PROJECT) return false; ++myFilesFromOtherProjects; return true; } if (FileBasedIndexImpl.belongsToScope(file, myRestrictedTo, myFilter)) return true; if (myFilesFromOtherProjects < MAX_FILES_TO_UPDATE_FROM_OTHER_PROJECT) { ++myFilesFromOtherProjects; return true; } return false; }
public boolean hasStubElementsOfType(final DomFileElement domFileElement, final Class<? extends DomElement> clazz) { final VirtualFile file = domFileElement.getFile().getVirtualFile(); if (!(file instanceof VirtualFileWithId)) return false; final String clazzName = clazz.getName(); final int virtualFileId = ((VirtualFileWithId)file).getId(); CommonProcessors.FindFirstProcessor<? super PsiFile> processor = new CommonProcessors.FindFirstProcessor<PsiFile>(); StubIndex.getInstance().processElements(KEY, clazzName, domFileElement.getFile().getProject(), GlobalSearchScope.fileScope(domFileElement.getFile()), new IdFilter() { @Override public boolean containsFileId(int id) { return id == virtualFileId; } }, PsiFile.class, processor ); return processor.isFound(); }
public boolean hasStubElementsWithNamespaceKey(final DomFileElement domFileElement, final String namespaceKey) { final VirtualFile file = domFileElement.getFile().getVirtualFile(); if (!(file instanceof VirtualFileWithId)) return false; final int virtualFileId = ((VirtualFileWithId)file).getId(); CommonProcessors.FindFirstProcessor<PsiFile> processor = new CommonProcessors.FindFirstProcessor<PsiFile>(); StubIndex.getInstance().processElements( KEY, namespaceKey, domFileElement.getFile().getProject(), GlobalSearchScope.fileScope(domFileElement.getFile()), new IdFilter() { @Override public boolean containsFileId(int id) { return id == virtualFileId; } }, PsiFile.class, processor ); return processor.isFound(); }
@NotNull private static XmlFileHeader calcXmlFileHeader(final XmlFile file) { if (file instanceof PsiFileEx && ((PsiFileEx)file).isContentsLoaded() && file.getNode().isParsed()) { return computeHeaderByPsi(file); } if (!XmlUtil.isStubBuilding() && file.getFileType() == XmlFileType.INSTANCE) { VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile instanceof VirtualFileWithId) { ObjectStubTree tree = StubTreeLoader.getInstance().readFromVFile(file.getProject(), virtualFile); if (tree != null) { Stub root = tree.getRoot(); if (root instanceof FileStub) { return ((FileStub)root).getHeader(); } } } } if (!file.isValid()) return XmlFileHeader.EMPTY; return NanoXmlUtil.parseHeader(file); }
@Nonnull String[] list(@Nonnull VirtualFile file) { String path = file.getPath(); FileInfo[] fileInfo = myKernel.listChildren(path); if (fileInfo == null || fileInfo.length == 0) { return ArrayUtil.EMPTY_STRING_ARRAY; } String[] names = new String[fileInfo.length]; TIntObjectHashMap<THashMap<String, FileAttributes>> map = getMap(); int parentId = ((VirtualFileWithId)file).getId(); THashMap<String, FileAttributes> nestedMap = map.get(parentId); if (nestedMap == null) { nestedMap = new THashMap<String, FileAttributes>(fileInfo.length, FileUtil.PATH_HASHING_STRATEGY); map.put(parentId, nestedMap); } for (int i = 0, length = fileInfo.length; i < length; i++) { FileInfo info = fileInfo[i]; String name = info.getName(); nestedMap.put(name, info.toFileAttributes()); names[i] = name; } return names; }
@Nullable FileAttributes getAttributes(@Nonnull VirtualFile file) { VirtualFile parent = file.getParent(); int parentId = parent instanceof VirtualFileWithId ? ((VirtualFileWithId)parent).getId() : -((VirtualFileWithId)file).getId(); TIntObjectHashMap<THashMap<String, FileAttributes>> map = getMap(); THashMap<String, FileAttributes> nestedMap = map.get(parentId); String name = file.getName(); FileAttributes attributes = nestedMap != null ? nestedMap.get(name) : null; if (attributes == null) { if (nestedMap != null && !(nestedMap instanceof IncompleteChildrenMap)) { return null; // our info from parent doesn't mention the child in this refresh session } FileInfo info = myKernel.getInfo(file.getPath()); if (info == null) { return null; } attributes = info.toFileAttributes(); if (nestedMap == null) { nestedMap = new IncompleteChildrenMap<>(FileUtil.PATH_HASHING_STRATEGY); map.put(parentId, nestedMap); } nestedMap.put(name, attributes); } return attributes; }
private <K, V> boolean processValuesInOneFile(@Nonnull ID<K, V> indexId, @Nonnull K dataKey, @Nonnull VirtualFile restrictToFile, @Nonnull ValueProcessor<V> processor, @Nonnull GlobalSearchScope scope) { if (!(restrictToFile instanceof VirtualFileWithId)) return true; int restrictedFileId = getFileId(restrictToFile); return processValueIterator(indexId, dataKey, restrictToFile, scope, valueIt -> { while (valueIt.hasNext()) { V value = valueIt.next(); if (valueIt.getValueAssociationPredicate().contains(restrictedFileId) && !processor.process(restrictToFile, value)) { return false; } } return true; }); }
@Override public boolean value(VirtualFile file) { int fileId = ((VirtualFileWithId)file).getId(); if (myIndexableFilesFilter != null && fileId > 0 && !myIndexableFilesFilter.containsFileId(fileId)) { if (myFilesFromOtherProjects >= MAX_FILES_TO_UPDATE_FROM_OTHER_PROJECT) return false; ++myFilesFromOtherProjects; return true; } if (fileId < 0 && file instanceof DeletedVirtualFileStub) { //file = ((FileBasedIndexImpl.MyLightVirtualFile)file).getOriginalFile(); return true; } if (FileBasedIndexImpl.belongsToScope(file, myRestrictedTo, myFilter)) return true; if (myFilesFromOtherProjects < MAX_FILES_TO_UPDATE_FROM_OTHER_PROJECT) { ++myFilesFromOtherProjects; return true; } return false; }
@Override public Data getFileData(@Nonnull Project project, @Nonnull VirtualFile file) { ApplicationManager.getApplication().assertReadAccessAllowed(); ProgressManager.checkCanceled(); if (!(file instanceof VirtualFileWithId)) return myCalculator.calcData(project, file); int stamp = PersistentFS.getInstance().getModificationCount(file) + ((GistManagerImpl)GistManager.getInstance()).getReindexCount(); try (DataInputStream stream = getFileAttribute(project).readAttribute(file)) { if (stream != null && DataInputOutputUtil.readINT(stream) == stamp) { return stream.readBoolean() ? myExternalizer.read(stream) : null; } } catch (IOException e) { LOG.error(e); } Data result = myCalculator.calcData(project, file); cacheResult(stamp, result, project, file); return result; }
public boolean hasStubElementsOfType(final DomFileElement domFileElement, final Class<? extends DomElement> clazz) { final VirtualFile file = domFileElement.getFile().getVirtualFile(); if(!(file instanceof VirtualFileWithId)) { return false; } final String clazzName = clazz.getName(); final int virtualFileId = ((VirtualFileWithId) file).getId(); CommonProcessors.FindFirstProcessor<? super PsiFile> processor = new CommonProcessors.FindFirstProcessor<PsiFile>(); StubIndex.getInstance().process(KEY, clazzName, domFileElement.getFile().getProject(), GlobalSearchScope.fileScope(domFileElement.getFile()) , new IdFilter() { @Override public boolean containsFileId(int id) { return id == virtualFileId; } }, processor); return processor.isFound(); }
public boolean hasStubElementsWithNamespaceKey(final DomFileElement domFileElement, final String namespaceKey) { final VirtualFile file = domFileElement.getFile().getVirtualFile(); if(!(file instanceof VirtualFileWithId)) { return false; } final int virtualFileId = ((VirtualFileWithId) file).getId(); CommonProcessors.FindFirstProcessor<PsiFile> processor = new CommonProcessors.FindFirstProcessor<PsiFile>(); StubIndex.getInstance().process(KEY, namespaceKey, domFileElement.getFile().getProject(), GlobalSearchScope.fileScope(domFileElement.getFile ()), new IdFilter() { @Override public boolean containsFileId(int id) { return id == virtualFileId; } }, processor); return processor.isFound(); }
@Nullable private PsiClass findClassInIndex(String qName, GlobalSearchScope scope) { VirtualFile bestFile = null; PsiClass bestClass = null; final Collection<PsiClass> classes = JavaFullClassNameIndex.getInstance().get(qName.hashCode(), myManager.getProject(), scope); for (PsiClass aClass : classes) { PsiFile file = aClass.getContainingFile(); if (file == null) { LOG.error("aClass=" + aClass + " of class " + aClass.getClass() + "; valid=" + aClass.isValid()); continue; } final boolean valid = aClass.isValid(); VirtualFile vFile = file.getVirtualFile(); if (!valid) { LOG.error("Invalid class " + aClass + "; " + file + (file.isValid() ? "" : " (invalid)") + "; virtualFile:" + vFile + (vFile != null && !vFile.isValid() ? " (invalid)" : "") + "; id=" + (vFile == null ? 0 : ((VirtualFileWithId)vFile).getId()), new PsiInvalidElementAccessException(aClass)); continue; } final String qualifiedName = aClass.getQualifiedName(); if (qualifiedName == null || !qualifiedName.equals(qName)) continue; if (!hasAcceptablePackage(vFile)) continue; if (bestFile == null || scope.compare(vFile, bestFile) > 0) { bestFile = vFile; bestClass = aClass; } } return bestClass; }
@Override public void applyEditorTo(JavaScratchConfiguration configuration) throws ConfigurationException { myCommonProgramParameters.applyTo(configuration); myModuleSelector.applyTo(configuration); configuration.MAIN_CLASS_NAME = myMainClass.getComponent().getText().trim(); configuration.ALTERNATIVE_JRE_PATH = myJrePathEditor.getJrePathOrName(); configuration.ALTERNATIVE_JRE_PATH_ENABLED = myJrePathEditor.isAlternativeJreSelected(); final VirtualFile vFile = getVFileFromEditor(); configuration.SCRATCH_FILE_ID = vFile instanceof VirtualFileWithId ? ((VirtualFileWithId)vFile).getId() : 0; }
@Override protected boolean setupConfigurationFromContext(JavaScratchConfiguration configuration, ConfigurationContext context, Ref<PsiElement> sourceElement) { final Location location = context.getLocation(); if (location != null) { final VirtualFile vFile = location.getVirtualFile(); if (vFile instanceof VirtualFileWithId && vFile.getFileType() == ScratchFileType.INSTANCE) { final PsiFile psiFile = location.getPsiElement().getContainingFile(); if (psiFile != null && psiFile.getLanguage() == JavaLanguage.INSTANCE) { configuration.SCRATCH_FILE_ID = ((VirtualFileWithId)vFile).getId(); return super.setupConfigurationFromContext(configuration, context, sourceElement); } } } return false; }
public static int getFileId(@NotNull final VirtualFile file) { if (file instanceof VirtualFileWithId) { return ((VirtualFileWithId)file).getId(); } throw new IllegalArgumentException("Virtual file doesn't support id: " + file + ", implementation class: " + file.getClass().getName()); }
@Override public VirtualFile[] getIncludedFiles(@NotNull VirtualFile file, boolean compileTimeOnly, boolean recursively) { if (file instanceof VirtualFileWithId) { return myIncludedHolder.getAllFiles(file, compileTimeOnly, recursively); } else { return VirtualFile.EMPTY_ARRAY; } }
@Nullable @Override public RootType getRootType(@Nullable VirtualFile file) { if (file == null) return null; VirtualFile directory = file.isDirectory() ? file : file.getParent(); if (!(directory instanceof VirtualFileWithId)) return null; RootType result = myIndex.getInfoForFile(directory); return result == NULL_TYPE ? null : result; }
public void testAccessingFileByID() throws Exception { File dir = createTempDirectory(); File file = new File(dir, "test.txt"); assertTrue(file.createNewFile()); VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file); assertNotNull(vFile); int id = ((VirtualFileWithId)vFile).getId(); assertSame(vFile, PersistentFS.getInstance().findFileById(id)); vFile.delete(this); assertNull(PersistentFS.getInstance().findFileById(id)); }
@Override @Nullable public StubTree getStubTree() { ApplicationManager.getApplication().assertReadAccessAllowed(); if (Boolean.TRUE.equals(getUserData(BUILDING_STUB))) return null; final StubTree derefd = derefStub(); if (derefd != null) return derefd; if (getTreeElement() != null) return null; if (!(getContentElementType() instanceof IStubFileElementType)) return null; final VirtualFile vFile = getVirtualFile(); if (!(vFile instanceof VirtualFileWithId)) return null; final PsiFile stubBindingRoot = getViewProvider().getStubBindingRoot(); if (stubBindingRoot != this) { LOG.error("Attempted to create stubs for non-root file: " + this + ", stub binding root: " + stubBindingRoot); return null; } ObjectStubTree tree = StubTreeLoader.getInstance().readOrBuild(getProject(), vFile, this); if (!(tree instanceof StubTree)) return null; StubTree stubHolder = (StubTree)tree; synchronized (PsiLock.LOCK) { if (getTreeElement() != null) return null; final StubTree derefdOnLock = derefStub(); if (derefdOnLock != null) return derefdOnLock; //noinspection unchecked ((StubBase)stubHolder.getRoot()).setPsi(this); myStub = new SoftReference<StubTree>(stubHolder); return stubHolder; } }
public StubTree calcStubTree() { FileElement fileElement = calcTreeElement(); synchronized (myStubFromTreeLock) { StubTree tree = fileElement.getUserData(STUB_TREE_IN_PARSED_TREE); if (tree == null) { ApplicationManager.getApplication().assertReadAccessAllowed(); IElementType contentElementType = getContentElementType(); if (!(contentElementType instanceof IStubFileElementType)) { VirtualFile vFile = getVirtualFile(); throw new AssertionError("ContentElementType: " + contentElementType + "; file: " + this + "\n\t" + "Boolean.TRUE.equals(getUserData(BUILDING_STUB)) = " + Boolean.TRUE.equals(getUserData(BUILDING_STUB)) + "\n\t" + "getTreeElement() = " + getTreeElement() + "\n\t" + "vFile instanceof VirtualFileWithId = " + (vFile instanceof VirtualFileWithId) + "\n\t" + "StubUpdatingIndex.canHaveStub(vFile) = " + StubTreeLoader.getInstance().canHaveStub(vFile)); } StubElement currentStubTree = ((IStubFileElementType)contentElementType).getBuilder().buildStubTree(this); tree = new StubTree((PsiFileStub)currentStubTree); tree.setDebugInfo("created in calcStubTree"); try { TreeUtil.bindStubsToTree(this, tree); } catch (TreeUtil.StubBindingException e) { rebuildStub(); throw new RuntimeException("Stub and PSI element type mismatch in " + getName(), e); } fileElement.putUserData(STUB_TREE_IN_PARSED_TREE, tree); } return tree; } }
@NotNull private static XmlFileHeader calcXmlFileHeader(final XmlFile file) { if (file instanceof PsiFileEx && ((PsiFileEx)file).isContentsLoaded() && file.getNode().isParsed()) { return computeHeaderByPsi(file); } if (!XmlUtil.isStubBuilding() && file.getFileType() == XmlFileType.INSTANCE) { VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile instanceof VirtualFileWithId) { ObjectStubTree tree = StubTreeLoader.getInstance().readFromVFile(file.getProject(), virtualFile); if (tree != null) { Stub root = tree.getRoot(); if (root instanceof FileStub) { return ((FileStub)root).getHeader(); } } } } if (!file.isValid()) return XmlFileHeader.EMPTY; if (XmlUtil.isStubBuilding() && file.getFileType() == XmlFileType.INSTANCE) { FileContent fileContent = file.getUserData(DomStubBuilder.CONTENT_FOR_DOM_STUBS); if (fileContent != null) { //noinspection IOResourceOpenedButNotSafelyClosed return NanoXmlUtil.parseHeader(new CharSequenceReader(fileContent.getContentAsText())); } } return NanoXmlUtil.parseHeader(file); }
@Nullable public static AstPath getNodePath(@Nonnull CompositeElement node) { if (node instanceof FileElement) { PsiElement psi = node.getCachedPsi(); if (!(psi instanceof PsiFileImpl)) return null; PsiFileImpl file = (PsiFileImpl)psi; if (!(file.getVirtualFile() instanceof VirtualFileWithId) || file.getElementTypeForStubBuilder() == null) { return null; } return new RootPath(file); } return node.getUserData(NODE_PATH); }
static boolean belongsToScope(VirtualFile file, VirtualFile restrictedTo, GlobalSearchScope filter) { if (!(file instanceof VirtualFileWithId) || !file.isValid()) { return false; } if (restrictedTo != null && !Comparing.equal(file, restrictedTo) || filter != null && restrictedTo == null && !filter.accept(file)) { return false; } return true; }
@Nullable public ProjectIndexableFilesFilter projectIndexableFiles(@Nullable Project project) { if (project == null || myUpdatingFiles.get() > 0) return null; if (myProjectsBeingUpdated.contains(project)) return null; SoftReference<ProjectIndexableFilesFilter> reference = project.getUserData(ourProjectFilesSetKey); ProjectIndexableFilesFilter data = com.intellij.reference.SoftReference.dereference(reference); if (data != null && data.myModificationCount == myFilesModCount) return data; if (myCalcIndexableFilesLock.tryLock()) { // make best effort for calculating filter try { reference = project.getUserData(ourProjectFilesSetKey); data = com.intellij.reference.SoftReference.dereference(reference); if (data != null && data.myModificationCount == myFilesModCount) { return data; } long start = System.currentTimeMillis(); final TIntArrayList filesSet = new TIntArrayList(); iterateIndexableFiles(fileOrDir -> { ProgressManager.checkCanceled(); filesSet.add(((VirtualFileWithId)fileOrDir).getId()); return true; }, project, SilentProgressIndicator.create()); ProjectIndexableFilesFilter filter = new ProjectIndexableFilesFilter(filesSet, myFilesModCount); project.putUserData(ourProjectFilesSetKey, new SoftReference<>(filter)); long finish = System.currentTimeMillis(); LOG.debug(filesSet.size() + " files iterated in " + (finish - start) + " ms"); return filter; } finally { myCalcIndexableFilesLock.unlock(); } } return null; // ok, no filtering }
@Nonnull @Override public List<VirtualFile> getFiles() { List<VirtualFile> files; synchronized (myFiles) { files = myFiles; } // When processing roots concurrently myFiles looses the local order of local vs archive files // If we process the roots in 2 threads we can just separate local vs archive // IMPORTANT: also remove duplicated file that can appear due to roots intersection BitSet usedFileIds = new BitSet(files.size()); List<VirtualFile> localFileSystemFiles = new ArrayList<>(files.size() / 2); List<VirtualFile> archiveFiles = new ArrayList<>(files.size() / 2); for (VirtualFile file : files) { int fileId = ((VirtualFileWithId)file).getId(); if (fileId > 0) { if (usedFileIds.get(fileId)) continue; usedFileIds.set(fileId); } if (file.getFileSystem() instanceof LocalFileSystem) { localFileSystemFiles.add(file); } else { archiveFiles.add(file); } } localFileSystemFiles.addAll(archiveFiles); return localFileSystemFiles; }
@Override public void registerIndexableSet(@Nonnull IndexableFileSet set, @Nullable Project project) { myIndexableSets.add(set); myIndexableSetToProjectMap.put(set, project); if (project != null) { ((PsiManagerImpl)PsiManager.getInstance(project)).addTreeChangePreprocessor(event -> { if (event.isGenericChange() && event.getCode() == PsiTreeChangeEventImpl.PsiEventType.CHILDREN_CHANGED) { PsiFile file = event.getFile(); if (file != null) { waitUntilIndicesAreInitialized(); VirtualFile virtualFile = file.getVirtualFile(); if (!clearUpToDateStateForPsiIndicesOfUnsavedDocuments(virtualFile)) { // change in persistent file if (virtualFile instanceof VirtualFileWithId) { int fileId = ((VirtualFileWithId)virtualFile).getId(); boolean wasIndexed = false; List<ID<?, ?>> candidates = getAffectedIndexCandidates(virtualFile); for (ID<?, ?> psiBackedIndex : myPsiDependentIndices) { if (!candidates.contains(psiBackedIndex)) continue; if (getInputFilter(psiBackedIndex).acceptInput(project, virtualFile)) { getIndex(psiBackedIndex).resetIndexedStateForFile(fileId); wasIndexed = true; } } if (wasIndexed) { myChangedFilesCollector.scheduleForUpdate(virtualFile); IndexingStamp.flushCache(fileId); } } } } } }); } }
@Override @NotNull public GlobalSearchScope getUseScope(@NotNull PsiElement element) { VirtualFile vDirectory; final VirtualFile virtualFile; final PsiFile containingFile; final GlobalSearchScope allScope = GlobalSearchScope.allScope(myManager.getProject()); if (element instanceof PsiDirectory) { vDirectory = ((PsiDirectory)element).getVirtualFile(); virtualFile = null; containingFile = null; } else { containingFile = element.getContainingFile(); if (containingFile == null) return allScope; virtualFile = containingFile.getVirtualFile(); if (virtualFile == null) return allScope; if (virtualFile instanceof VirtualFileWindow) { return GlobalSearchScope.fileScope(myProject, ((VirtualFileWindow)virtualFile).getDelegate()); } vDirectory = virtualFile.getParent(); } if (vDirectory == null) return allScope; final ProjectFileIndex projectFileIndex = myProjectRootManager.getFileIndex(); final Module module = projectFileIndex.getModuleForFile(vDirectory); if (module == null) { VirtualFile notNullVFile = virtualFile != null ? virtualFile : vDirectory; final List<OrderEntry> entries = projectFileIndex.getOrderEntriesForFile(notNullVFile); if (entries.isEmpty() && myAdditionalIndexableFileSet.isInSet(notNullVFile)) { return allScope; } GlobalSearchScope result = LibraryScopeCache.getInstance(myProject).getLibraryUseScope(entries); return containingFile == null || virtualFile.isDirectory() || result.contains(virtualFile) ? result : GlobalSearchScope.fileScope(containingFile).uniteWith(result); } boolean isTest = projectFileIndex.isInTestSourceContent(vDirectory); GlobalSearchScope scope = isTest ? GlobalSearchScope.moduleTestsWithDependentsScope(module) : GlobalSearchScope.moduleWithDependentsScope(module); RefResolveService resolveService; if (virtualFile instanceof VirtualFileWithId && RefResolveService.ENABLED && (resolveService = RefResolveService.getInstance(myProject)).isUpToDate()) { return resolveService.restrictByBackwardIds(virtualFile, scope); } return scope; }
@Nullable("null means the service has not resolved all files and is not ready yet") public abstract int[] getBackwardIds(@NotNull VirtualFileWithId file);
@Override @Nullable public StubTree getStubTree() { ApplicationManager.getApplication().assertReadAccessAllowed(); if (Boolean.TRUE.equals(getUserData(BUILDING_STUB))) return null; final StubTree derefd = derefStub(); if (derefd != null) return derefd; if (getTreeElement() != null) return null; if (getElementTypeForStubBuilder() == null) return null; final VirtualFile vFile = getVirtualFile(); if (!(vFile instanceof VirtualFileWithId)) return null; ObjectStubTree tree = StubTreeLoader.getInstance().readOrBuild(getProject(), vFile, this); if (!(tree instanceof StubTree)) return null; StubTree stubHolder = (StubTree)tree; final FileViewProvider viewProvider = getViewProvider(); final List<Pair<IStubFileElementType, PsiFile>> roots = StubTreeBuilder.getStubbedRoots(viewProvider); synchronized (PsiLock.LOCK) { if (getTreeElement() != null) return null; final StubTree derefdOnLock = derefStub(); if (derefdOnLock != null) return derefdOnLock; final PsiFileStub baseRoot = stubHolder.getRoot(); if (baseRoot instanceof PsiFileStubImpl && !((PsiFileStubImpl)baseRoot).rootsAreSet()) { LOG.error("Stub roots must be set when stub tree was read or built with StubTreeLoader"); return stubHolder; } final PsiFileStub[] stubRoots = baseRoot.getStubRoots(); if (stubRoots.length != roots.size()) { LOG.error("stubRoots.length = " + stubRoots.length + "; roots.size() = " + roots.size()); } // set all stub trees to avoid reading file when stub tree for another psi root is accessed int matchingRoot = 0; for (Pair<IStubFileElementType, PsiFile> root : roots) { final PsiFileStub matchingStub = stubRoots[matchingRoot++]; PsiFileImpl eachPsiRoot = (PsiFileImpl)root.second; //noinspection unchecked ((StubBase)matchingStub).setPsi(eachPsiRoot); final StubTree stubTree = new StubTree(matchingStub); FileElement fileElement = eachPsiRoot.getTreeElement(); if (fileElement != null) { stubTree.setDebugInfo("created in getStubTree(), with AST"); // Set references from these stubs to AST, because: // Stub index might call getStubTree on main PSI file, but then use getPlainListFromAllRoots and return stubs from another file. // Even if that file already has AST, stub.getPsi() should be the same as in AST TreeUtil.bindStubsToTree(eachPsiRoot, stubTree, fileElement); } else { stubTree.setDebugInfo("created in getStubTree(), no AST"); if (eachPsiRoot == this) stubHolder = stubTree; eachPsiRoot.myStub = new SoftReference<StubTree>(stubTree); } eachPsiRoot.putUserData(ObjectStubTree.LAST_STUB_TREE_HASH, null); } return stubHolder; } }
@NotNull public StubTree calcStubTree() { FileElement fileElement = calcTreeElement(); StubTree tree = SoftReference.dereference(fileElement.getUserData(STUB_TREE_IN_PARSED_TREE)); if (tree != null) { return tree; } synchronized (myStubFromTreeLock) { tree = SoftReference.dereference(fileElement.getUserData(STUB_TREE_IN_PARSED_TREE)); if (tree == null) { ApplicationManager.getApplication().assertReadAccessAllowed(); IStubFileElementType contentElementType = getElementTypeForStubBuilder(); if (contentElementType == null) { VirtualFile vFile = getVirtualFile(); String message = "ContentElementType: " + getContentElementType() + "; file: " + this + "\n\t" + "Boolean.TRUE.equals(getUserData(BUILDING_STUB)) = " + Boolean.TRUE.equals(getUserData(BUILDING_STUB)) + "\n\t" + "getTreeElement() = " + getTreeElement() + "\n\t" + "vFile instanceof VirtualFileWithId = " + (vFile instanceof VirtualFileWithId) + "\n\t" + "StubUpdatingIndex.canHaveStub(vFile) = " + StubTreeLoader.getInstance().canHaveStub(vFile); rebuildStub(); throw new AssertionError(message); } StubElement currentStubTree = contentElementType.getBuilder().buildStubTree(this); if (currentStubTree == null) { throw new AssertionError("Stub tree wasn't built for " + contentElementType + "; file: " + this); } tree = new StubTree((PsiFileStub)currentStubTree); tree.setDebugInfo("created in calcStubTree"); try { TreeUtil.bindStubsToTree(this, tree, fileElement); } catch (TreeUtil.StubBindingException e) { rebuildStub(); throw new RuntimeException("Stub and PSI element type mismatch in " + getName(), e); } fileElement.putUserData(STUB_TREE_IN_PARSED_TREE, new SoftReference<StubTree>(tree)); } return tree; } }
public static boolean isApplicableFor(@NotNull VirtualFile file) { if (!(file instanceof VirtualFileWithId) || file.isDirectory()) return false; FileType originalType = FileTypeManager.getInstance().getFileTypeByFileName(file.getName()); return !originalType.isBinary() && originalType != FileTypes.PLAIN_TEXT && originalType != StdFileTypes.JAVA; }
protected boolean addFile(@NotNull VirtualFile file) { if (!(file instanceof VirtualFileWithId) || file.isDirectory()) return false; myFiles.add(file); return true; }
private void cacheInfo(VirtualFile file, T info) { myInfoCache.put(((VirtualFileWithId)file).getId(), info); }
private T getCachedInfo(VirtualFile file) { return myInfoCache.get(((VirtualFileWithId)file).getId()); }
DeletedVirtualFileStub(VirtualFileWithId original) { setOriginalFile((VirtualFile)original); myFileId = -Math.abs(original.getId()); }