@Override @SuppressWarnings({"CloneDoesntDeclareCloneNotSupportedException", "CloneDoesntCallSuperClone"}) protected PsiFileImpl clone() { FileViewProvider viewProvider = getViewProvider(); FileViewProvider providerCopy = viewProvider.clone(); final Language language = getLanguage(); if (providerCopy == null) { throw new AssertionError( "Unable to clone the view provider: " + viewProvider + "; " + language); } PsiFileImpl clone = BlockSupportImpl.getFileCopy(this, providerCopy); copyCopyableDataTo(clone); if (getTreeElement() != null) { // not set by provider in clone final FileElement treeClone = (FileElement) calcTreeElement().clone(); clone.setTreeElementPointer( treeClone); // should not use setTreeElement here because cloned file still have // VirtualFile (SCR17963) treeClone.setPsi(clone); } if (viewProvider.isEventSystemEnabled()) { clone.myOriginalFile = this; } else if (myOriginalFile != null) { clone.myOriginalFile = myOriginalFile; } return clone; }
protected boolean isPsiUpToDate(@NotNull VirtualFile vFile) { final FileViewProvider provider = myManager.findViewProvider(vFile); Language language = getLanguage(); if (provider == null || provider.getPsi(language) == this) { // provider == null in tests return true; } Language baseLanguage = provider.getBaseLanguage(); return baseLanguage != language && provider.getPsi(baseLanguage) == this; }
@Override public boolean isValid() { FileViewProvider provider = getViewProvider(); final VirtualFile vFile = provider.getVirtualFile(); if (!vFile.isValid()) return false; if (!provider.isEventSystemEnabled()) return true; // "dummy" file if (myManager.getProject().isDisposed()) return false; return isPsiUpToDate(vFile); }
@Override @NotNull public PsiFile[] getPsiRoots() { final FileViewProvider viewProvider = getViewProvider(); final Set<Language> languages = viewProvider.getLanguages(); final PsiFile[] roots = new PsiFile[languages.size()]; int i = 0; for (Language language : languages) { PsiFile psi = viewProvider.getPsi(language); if (psi == null) { LOG.error("PSI is null for " + language + "; in file: " + this); } roots[i++] = psi; } if (roots.length > 1) { Arrays.sort(roots, FILE_BY_LANGUAGE_ID); } return roots; }
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"); }
public void unloadContent() { ApplicationManager.getApplication().assertWriteAccessAllowed(); clearCaches(); myViewProvider.beforeContentsSynchronized(); synchronized (PsiLock.LOCK) { FileElement treeElement = derefTreeElement(); DebugUtil.startPsiModification("unloadContent"); try { if (treeElement != null) { myTreeElementPointer = null; treeElement.detachFromFile(); DebugUtil.onInvalidated(treeElement); } clearStub("unloadContent"); } finally { DebugUtil.finishPsiModification(); } } }
@NotNull private FileElement loadTreeElement() { ApplicationManager.getApplication().assertReadAccessAllowed(); final FileViewProvider viewProvider = getViewProvider(); if (viewProvider.isPhysical() && myManager.isAssertOnFileLoading(viewProvider.getVirtualFile())) { LOG.error( "Access to tree elements not allowed in tests. path='" + viewProvider.getVirtualFile().getPresentableUrl() + "'"); } Document cachedDocument = FileDocumentManager.getInstance().getCachedDocument(getViewProvider().getVirtualFile()); FileElement treeElement = createFileElement(viewProvider.getContents()); treeElement.setPsi(this); List<Pair<StubBasedPsiElementBase, CompositeElement>> bindings = calcStubAstBindings(treeElement, cachedDocument); synchronized (PsiLock.LOCK) { FileElement existing = derefTreeElement(); if (existing != null) { return existing; } switchFromStubToAst(bindings); myStub = null; myTreeElementPointer = createTreeElementPointer(treeElement); if (LOG.isDebugEnabled() && viewProvider.isPhysical()) { LOG.debug("Loaded text for file " + viewProvider.getVirtualFile().getPresentableUrl()); } return treeElement; } }
protected PsiFileImpl(@NotNull FileViewProvider provider) { myManager = (PsiManagerEx) provider.getManager(); myViewProvider = provider; }