@Override public <K> Collection<K> getAllKeys(final StubIndexKey<K, ?> indexKey, @NotNull Project project) { FileBasedIndex.getInstance() .ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, GlobalSearchScope.allScope(project)); final MyIndex<K> index = (MyIndex<K>) myIndices.get(indexKey); try { return index.getAllKeys(); } catch (StorageException e) { forceRebuild(e); } catch (RuntimeException e) { final Throwable cause = e.getCause(); if (cause instanceof IOException || cause instanceof StorageException) { forceRebuild(e); } throw e; } return Collections.emptyList(); }
public StubIndexImpl(FileBasedIndex fileBasedIndex /* need this to ensure initialization order*/) throws IOException { final boolean forceClean = Boolean.TRUE == ourForcedClean.getAndSet(Boolean.FALSE); final StubIndexExtension<?, ?>[] extensions = Extensions.getExtensions(StubIndexExtension.EP_NAME); boolean needRebuild = false; for (StubIndexExtension extension : extensions) { //noinspection unchecked needRebuild |= registerIndexer(extension, forceClean); } if (needRebuild) { if (ApplicationManager.getApplication().isUnitTestMode()) { requestRebuild(); } else { forceRebuild(new Throwable()); } } dropUnregisteredIndices(); }
@Override public <Key, Psi extends PsiElement> Collection<Psi> get( @NotNull final StubIndexKey<Key, Psi> indexKey, @NotNull final Key key, final Project project, final GlobalSearchScope scope) { FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, scope); final PersistentFS fs = (PersistentFS) ManagingFS.getInstance(); final PsiManager psiManager = PsiManager.getInstance(project); final List<Psi> result = new ArrayList<Psi>(); final MyIndex<Key> index = (MyIndex<Key>) myIndices.get(indexKey); try { try { // disable up-to-date check to avoid locks on attempt to acquire index write lock while // holding at the same time the readLock for this index FileBasedIndex.disableUpToDateCheckForCurrentThread(); index.getReadLock().lock(); final ValueContainer<TIntArrayList> container = index.getData(key); container.forEach( new ValueContainer.ContainerAction<TIntArrayList>() { @Override public void perform(final int id, final TIntArrayList value) { final VirtualFile file = IndexInfrastructure.findFileByIdIfCached(fs, id); if (file != null && (scope == null || scope.contains(file))) { StubTree stubTree = null; final PsiFile _psifile = psiManager.findFile(file); PsiFileWithStubSupport psiFile = null; if (_psifile != null && !(_psifile instanceof PsiPlainTextFile)) { if (_psifile instanceof PsiFileWithStubSupport) { psiFile = (PsiFileWithStubSupport) _psifile; stubTree = psiFile.getStubTree(); if (stubTree == null && psiFile instanceof PsiFileImpl) { stubTree = ((PsiFileImpl) psiFile).calcStubTree(); } } } if (stubTree != null || psiFile != null) { if (stubTree == null) { stubTree = StubTreeLoader.getInstance().readFromVFile(project, file); if (stubTree != null) { final List<StubElement<?>> plained = stubTree.getPlainList(); for (int i = 0; i < value.size(); i++) { final StubElement<?> stub = plained.get(value.get(i)); final ASTNode tree = psiFile.findTreeForStub(stubTree, stub); if (tree != null) { if (tree.getElementType() == stubType(stub)) { result.add((Psi) tree.getPsi()); } else { String persistedStubTree = ((PsiFileStubImpl) stubTree.getRoot()).printTree(); String stubTreeJustBuilt = ((PsiFileStubImpl) ((IStubFileElementType) ((PsiFileImpl) psiFile).getContentElementType()) .getBuilder() .buildStubTree(psiFile)) .printTree(); StringBuilder builder = new StringBuilder(); builder.append("Oops\n"); builder.append("Recorded stub:-----------------------------------\n"); builder.append(persistedStubTree); builder.append( "\nAST built stub: ------------------------------------\n"); builder.append(stubTreeJustBuilt); builder.append("\n"); LOG.info(builder.toString()); // requestReindex() may want to acquire write lock (for indices not // requiring content loading) // thus, because here we are under read lock, need to use invoke later ApplicationManager.getApplication() .invokeLater( new Runnable() { @Override public void run() { FileBasedIndex.getInstance().requestReindex(file); } }, ModalityState.NON_MODAL); } } } } } else { final List<StubElement<?>> plained = stubTree.getPlainList(); for (int i = 0; i < value.size(); i++) { result.add((Psi) plained.get(value.get(i)).getPsi()); } } } } } }); } finally { index.getReadLock().unlock(); FileBasedIndex.enableUpToDateCheckForCurrentThread(); } } catch (StorageException e) { forceRebuild(e); } catch (RuntimeException e) { final Throwable cause = FileBasedIndex.getCauseToRebuildIndex(e); if (cause != null) { forceRebuild(cause); } else { throw e; } } return result; }