public StubTree calcStubTree() { FileElement fileElement = calcTreeElement(); synchronized (myStubFromTreeLock) { SoftReference<StubTree> ref = fileElement.getUserData(STUB_TREE_IN_PARSED_TREE); StubTree tree = SoftReference.dereference(ref); if (tree == null) { ApplicationManager.getApplication().assertReadAccessAllowed(); IElementType contentElementType = getContentElementType(); if (!(contentElementType instanceof IStubFileElementType)) { VirtualFile vFile = getVirtualFile(); String message = "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); rebuildStub(); throw new AssertionError(message); } StubElement currentStubTree = ((IStubFileElementType) 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); } 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; } }
@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; } }
private void rebuildStub() { final VirtualFile vFile = getVirtualFile(); if (vFile != null && vFile.isValid()) { ApplicationManager.getApplication() .invokeLater( new Runnable() { @Override public void run() { final Document doc = FileDocumentManager.getInstance().getCachedDocument(vFile); if (doc != null) { FileDocumentManager.getInstance().saveDocument(doc); } } }, ModalityState.NON_MODAL); StubTreeLoader.getInstance().rebuildStubTree(vFile); } }
protected void reportStubAstMismatch(String message, StubTree stubTree, Document cachedDocument) { rebuildStub(); clearStub("stub-psi mismatch"); scheduleDropCachesWithInvalidStubPsi(); String msg = message; msg += "\n file=" + this; msg += ", modStamp=" + getModificationStamp(); msg += "\n stub debugInfo=" + stubTree.getDebugInfo(); msg += "\n document before=" + cachedDocument; ObjectStubTree latestIndexedStub = StubTreeLoader.getInstance().readFromVFile(getProject(), getVirtualFile()); msg += "\nlatestIndexedStub=" + latestIndexedStub; if (latestIndexedStub != null) { msg += "\n same size=" + (stubTree.getPlainList().size() == latestIndexedStub.getPlainList().size()); msg += "\n debugInfo=" + latestIndexedStub.getDebugInfo(); } FileViewProvider viewProvider = getViewProvider(); msg += "\n viewProvider=" + viewProvider; msg += "\n viewProvider stamp: " + viewProvider.getModificationStamp(); VirtualFile file = viewProvider.getVirtualFile(); msg += "; file stamp: " + file.getModificationStamp(); msg += "; file modCount: " + file.getModificationCount(); Document document = FileDocumentManager.getInstance().getCachedDocument(file); if (document != null) { msg += "\n doc saved: " + !FileDocumentManager.getInstance().isDocumentUnsaved(document); msg += "; doc stamp: " + document.getModificationStamp(); msg += "; doc size: " + document.getTextLength(); msg += "; committed: " + PsiDocumentManager.getInstance(getProject()).isCommitted(document); } throw new AssertionError(msg + "\n------------\n"); }