private void checkPsiModificationAllowed(@NotNull final PsiTreeChangeEvent event) { if (!toProcessPsiEvent()) return; final PsiFile psiFile = event.getFile(); if (!(psiFile instanceof PsiFileEx) || !((PsiFileEx) psiFile).isContentsLoaded()) return; final Document document = myPsiDocumentManager.getCachedDocument(psiFile); if (document != null && myPsiDocumentManager.isUncommited(document)) { throw new IllegalStateException("Attempt to modify PSI for non-committed Document!"); } }
public boolean commitTransaction(final Document document) { ApplicationManager.getApplication().assertIsDispatchThread(); final DocumentChangeTransaction documentChangeTransaction = removeTransaction(document); if (documentChangeTransaction == null) return false; final PsiFile changeScope = documentChangeTransaction.myChangeScope; try { mySyncDocument = document; final PsiTreeChangeEventImpl fakeEvent = new PsiTreeChangeEventImpl(changeScope.getManager()); fakeEvent.setParent(changeScope); fakeEvent.setFile(changeScope); checkPsiModificationAllowed(fakeEvent); doSync( fakeEvent, true, new DocSyncAction() { @Override public void syncDocument( @NotNull Document document, @NotNull PsiTreeChangeEventImpl event) { doCommitTransaction(document, documentChangeTransaction); } }); myBus .syncPublisher(PsiDocumentTransactionListener.TOPIC) .transactionCompleted(document, changeScope); } catch (Throwable e) { myPsiDocumentManager.forceReload( changeScope.getViewProvider().getVirtualFile(), changeScope.getViewProvider()); ExceptionUtil.rethrowAllAsUnchecked(e); } finally { mySyncDocument = null; } return true; }
private DocumentEx getCachedDocument(PsiFile psiFile, boolean force) { final DocumentEx document = (DocumentEx) myPsiDocumentManager.getCachedDocument(psiFile); if (document == null || document instanceof DocumentWindow || !force && getTransaction(document) == null) { return null; } return document; }
private void doSync( @NotNull final PsiTreeChangeEvent event, boolean force, @NotNull final DocSyncAction syncAction) { if (!toProcessPsiEvent()) return; final PsiFile psiFile = event.getFile(); if (psiFile == null || psiFile.getNode() == null) return; final DocumentEx document = (DocumentEx) myPsiDocumentManager.getCachedDocument(psiFile); if (document == null || document instanceof DocumentWindow) return; if (!force && getTransaction(document) == null) { return; } TextBlock textBlock = TextBlock.get(psiFile); if (!textBlock.isEmpty()) { throw new IllegalStateException("Attempt to modify PSI for non-committed Document!"); } textBlock.performAtomically( new Runnable() { @Override public void run() { syncAction.syncDocument(document, (PsiTreeChangeEventImpl) event); } }); final boolean insideTransaction = myTransactionsMap.containsKey(document); if (!insideTransaction) { document.setModificationStamp(psiFile.getViewProvider().getModificationStamp()); if (LOG.isDebugEnabled()) { PsiDocumentManagerBase.checkConsistency(psiFile, document); } } psiFile.getViewProvider().contentsSynchronized(); }
public boolean toProcessPsiEvent() { return !myIgnorePsiEvents && !myPsiDocumentManager.isCommitInProgress() && !ApplicationManager.getApplication().hasWriteAction(IgnorePsiEventsMarker.class); }