private void commitTransaction(final PomTransaction transaction) { final ProgressIndicator progressIndicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); final PsiDocumentManagerBase manager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject); final PsiToDocumentSynchronizer synchronizer = manager.getSynchronizer(); final PsiFile containingFileByTree = getContainingFileByTree(transaction.getChangeScope()); Document document = containingFileByTree != null ? manager.getCachedDocument(containingFileByTree) : null; if (document != null) { final int oldLength = containingFileByTree.getTextLength(); boolean success = synchronizer.commitTransaction(document); if (success) { BlockSupportImpl.sendAfterChildrenChangedEvent((PsiManagerImpl)PsiManager.getInstance(myProject), (PsiFileImpl)containingFileByTree, oldLength, true); } } if (containingFileByTree != null) { boolean isFromCommit = ApplicationManager.getApplication().isDispatchThread() && ApplicationManager.getApplication().hasWriteAction(CommitToPsiFileAction.class); if (!isFromCommit && !synchronizer.isIgnorePsiEvents()) { reparseParallelTrees(containingFileByTree); } } if (progressIndicator != null) progressIndicator.finishNonCancelableSection(); }
@SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod") public void reparseFileFromText(@Nonnull PsiFileImpl file) { ApplicationManager.getApplication().assertIsDispatchThread(); if (isCommitInProgress()) throw new IllegalStateException("Re-entrant commit is not allowed"); FileElement node = file.calcTreeElement(); CharSequence text = node.getChars(); ourIsFullReparseInProgress = true; try { WriteAction.run(() -> { ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); if (indicator == null) indicator = new EmptyProgressIndicator(); DiffLog log = BlockSupportImpl.makeFullParse(file, node, text, indicator, text).getFirst(); log.doActualPsiChange(file); file.getViewProvider().contentsSynchronized(); }); } finally { ourIsFullReparseInProgress = false; } }
public static void ensureCorrectReparse(@NotNull final PsiFile file) { final String psiToStringDefault = DebugUtil.psiToString(file, false, false); final String fileText = file.getText(); final DiffLog diffLog = new BlockSupportImpl(file.getProject()).reparseRange( file, TextRange.allOf(fileText), fileText, new EmptyProgressIndicator(), fileText); diffLog.performActualPsiChange(file); TestCase.assertEquals(psiToStringDefault, DebugUtil.psiToString(file, false, false)); }
private void commitTransaction(final PomTransaction transaction) { final ProgressIndicator progressIndicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); final PsiDocumentManagerBase manager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject); final PsiToDocumentSynchronizer synchronizer = manager.getSynchronizer(); final PsiFile containingFileByTree = getContainingFileByTree(transaction.getChangeScope()); Document document = containingFileByTree != null ? manager.getCachedDocument(containingFileByTree) : null; boolean docSynced = false; if (document != null) { final int oldLength = containingFileByTree.getTextLength(); docSynced = synchronizer.commitTransaction(document); if (docSynced) { BlockSupportImpl.sendAfterChildrenChangedEvent((PsiManagerImpl)PsiManager.getInstance(myProject), containingFileByTree, oldLength, true); } } if (containingFileByTree != null) { boolean isFromCommit = ApplicationManager.getApplication().isDispatchThread() && ApplicationManager.getApplication().hasWriteAction(CommitToPsiFileAction.class); if (!isFromCommit && !synchronizer.isIgnorePsiEvents()) { reparseParallelTrees(containingFileByTree); if (docSynced) { containingFileByTree.getViewProvider().contentsSynchronized(); } } } if (progressIndicator != null) progressIndicator.finishNonCancelableSection(); }
private void startTransaction(@NotNull PomTransaction transaction) { final ProgressIndicator progressIndicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); if(progressIndicator != null) progressIndicator.startNonCancelableSection(); final PsiDocumentManagerBase manager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject); final PsiToDocumentSynchronizer synchronizer = manager.getSynchronizer(); final PsiElement changeScope = transaction.getChangeScope(); LOG.assertTrue(changeScope != null); final PsiFile containingFileByTree = getContainingFileByTree(changeScope); boolean physical = changeScope.isPhysical(); if (physical && synchronizer.toProcessPsiEvent() && isDocumentUncommitted(containingFileByTree)) { // fail-fast to prevent any psi modifications that would cause psi/document text mismatch // PsiToDocumentSynchronizer assertions happen inside event processing and are logged by PsiManagerImpl.fireEvent instead of being rethrown // so it's important to throw something outside event processing throw new IllegalStateException("Attempt to modify PSI for non-committed Document!"); } if (containingFileByTree != null) { ((SmartPointerManagerImpl) SmartPointerManager.getInstance(myProject)).fastenBelts(containingFileByTree.getViewProvider().getVirtualFile()); } BlockSupportImpl.sendBeforeChildrenChangeEvent((PsiManagerImpl)PsiManager.getInstance(myProject), changeScope, true); Document document = containingFileByTree == null ? null : physical ? manager.getDocument(containingFileByTree) : manager.getCachedDocument(containingFileByTree); if(document != null) { synchronizer.startTransaction(myProject, document, changeScope); } }
@NotNull private DiffLog merge(@NotNull final ASTNode oldRoot, @NotNull StartMarker newRoot, @NotNull CharSequence lastCommittedText) { DiffLog diffLog = new DiffLog(); DiffTreeChangeBuilder<ASTNode, LighterASTNode> builder = new ConvertFromTokensToASTBuilder(newRoot, diffLog); MyTreeStructure treeStructure = new MyTreeStructure(newRoot, null); ShallowNodeComparator<ASTNode, LighterASTNode> comparator = new MyComparator(getUserDataUnprotected(CUSTOM_COMPARATOR), treeStructure); ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); BlockSupportImpl.diffTrees(oldRoot, builder, comparator, treeStructure, indicator == null ? new EmptyProgressIndicator() : indicator, lastCommittedText); return diffLog; }
private void startTransaction(final PomTransaction transaction) { final ProgressIndicator progressIndicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); if(progressIndicator != null) progressIndicator.startNonCancelableSection(); final PsiDocumentManagerBase manager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject); final PsiToDocumentSynchronizer synchronizer = manager.getSynchronizer(); final PsiElement changeScope = transaction.getChangeScope(); BlockSupportImpl.sendBeforeChildrenChangeEvent((PsiManagerImpl)PsiManager.getInstance(myProject), transaction.getChangeScope(), true); LOG.assertTrue(changeScope != null); final PsiFile containingFileByTree = getContainingFileByTree(changeScope); Document document = containingFileByTree == null ? null : manager.getCachedDocument(containingFileByTree); if(document != null) { synchronizer.startTransaction(myProject, document, transaction.getChangeScope()); } }
@NotNull private DiffLog merge(@NotNull final ASTNode oldRoot, @NotNull StartMarker newRoot) { DiffLog diffLog = new DiffLog(); final ConvertFromTokensToASTBuilder builder = new ConvertFromTokensToASTBuilder(newRoot, diffLog); final MyTreeStructure treeStructure = new MyTreeStructure(newRoot, null); final MyComparator comparator = new MyComparator(getUserDataUnprotected(CUSTOM_COMPARATOR), treeStructure); final ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); BlockSupportImpl.diffTrees(oldRoot, builder, comparator, treeStructure, indicator); return diffLog; }
private void commitTransaction(final PomTransaction transaction) { final ProgressIndicator progressIndicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); final PsiDocumentManagerBase manager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject); final PsiToDocumentSynchronizer synchronizer = manager.getSynchronizer(); final PsiFile containingFileByTree = getContainingFileByTree(transaction.getChangeScope()); Document document = containingFileByTree != null ? manager.getCachedDocument(containingFileByTree) : null; boolean isFromCommit = ApplicationManager.getApplication().isDispatchThread() && ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject)).isCommitInProgress(); boolean isPhysicalPsiChange = containingFileByTree != null && !isFromCommit && !synchronizer.isIgnorePsiEvents(); if (isPhysicalPsiChange) { reparseParallelTrees(containingFileByTree, synchronizer); } boolean docSynced = false; if (document != null) { final int oldLength = containingFileByTree.getTextLength(); docSynced = synchronizer.commitTransaction(document); if (docSynced) { BlockSupportImpl.sendAfterChildrenChangedEvent((PsiManagerImpl)PsiManager.getInstance(myProject), containingFileByTree, oldLength, true); } } if (isPhysicalPsiChange && docSynced) { containingFileByTree.getViewProvider().contentsSynchronized(); } if (progressIndicator != null) progressIndicator.finishNonCancelableSection(); }
@Nonnull private DiffLog merge(@Nonnull final ASTNode oldRoot, @Nonnull StartMarker newRoot, @Nonnull CharSequence lastCommittedText) { DiffLog diffLog = new DiffLog(); DiffTreeChangeBuilder<ASTNode, LighterASTNode> builder = new ConvertFromTokensToASTBuilder(newRoot, diffLog); MyTreeStructure treeStructure = new MyTreeStructure(newRoot, null); ShallowNodeComparator<ASTNode, LighterASTNode> comparator = new MyComparator(getUserDataUnprotected(CUSTOM_COMPARATOR), treeStructure); ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); BlockSupportImpl.diffTrees(oldRoot, builder, comparator, treeStructure, indicator == null ? new EmptyProgressIndicator() : indicator, lastCommittedText); return diffLog; }
private static void mergePsi(@Nonnull PsiFile oldFile, @Nonnull ASTNode oldFileNode, @Nonnull PsiFile injectedPsi, @Nonnull ASTNode injectedNode) { if (!oldFile.textMatches(injectedPsi)) { InjectedFileViewProvider oldViewProvider = (InjectedFileViewProvider)oldFile.getViewProvider(); oldViewProvider.performNonPhysically(() -> { DebugUtil.performPsiModification("injected tree diff", () -> { final DiffLog diffLog = BlockSupportImpl.mergeTrees((PsiFileImpl)oldFile, oldFileNode, injectedNode, new DaemonProgressIndicator(), oldFileNode.getText()); diffLog.doActualPsiChange(oldFile); }); }); } }
private void startTransaction(@Nonnull PomTransaction transaction) { final ProgressIndicator progressIndicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); if(progressIndicator != null) progressIndicator.startNonCancelableSection(); final PsiDocumentManagerBase manager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject); final PsiToDocumentSynchronizer synchronizer = manager.getSynchronizer(); final PsiElement changeScope = transaction.getChangeScope(); final PsiFile containingFileByTree = getContainingFileByTree(changeScope); if (containingFileByTree != null && !(containingFileByTree instanceof DummyHolder) && !manager.isCommitInProgress()) { PsiUtilCore.ensureValid(containingFileByTree); } boolean physical = changeScope.isPhysical(); if (synchronizer.toProcessPsiEvent()) { // fail-fast to prevent any psi modifications that would cause psi/document text mismatch // PsiToDocumentSynchronizer assertions happen inside event processing and are logged by PsiManagerImpl.fireEvent instead of being rethrown // so it's important to throw something outside event processing if (isDocumentUncommitted(containingFileByTree)) { throw new IllegalStateException("Attempt to modify PSI for non-committed Document!"); } CommandProcessor commandProcessor = CommandProcessor.getInstance(); if (physical && !commandProcessor.isUndoTransparentActionInProgress() && commandProcessor.getCurrentCommand() == null) { throw new IncorrectOperationException("Must not change PSI outside command or undo-transparent action. See com.intellij.openapi.command.WriteCommandAction or com.intellij.openapi.command.CommandProcessor"); } } if (containingFileByTree != null) { ((SmartPointerManagerImpl) SmartPointerManager.getInstance(myProject)).fastenBelts(containingFileByTree.getViewProvider().getVirtualFile()); if (containingFileByTree instanceof PsiFileImpl) { ((PsiFileImpl)containingFileByTree).beforeAstChange(); } } BlockSupportImpl.sendBeforeChildrenChangeEvent((PsiManagerImpl)PsiManager.getInstance(myProject), changeScope, true); Document document = containingFileByTree == null ? null : physical ? manager.getDocument(containingFileByTree) : manager.getCachedDocument(containingFileByTree); if(document != null) { synchronizer.startTransaction(myProject, document, changeScope); } }
@Nonnull private static BooleanRunnable doCommit(@Nonnull final CommitTask task, @Nonnull final PsiFile file, @Nonnull final FileASTNode oldFileNode, @Nonnull ProperTextRange changedPsiRange, @Nonnull List<BooleanRunnable> outReparseInjectedProcessors) { Document document = task.getDocument(); final CharSequence newDocumentText = document.getImmutableCharSequence(); final Boolean data = document.getUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY); if (data != null) { document.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, null); file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, data); } Trinity<DiffLog, ASTNode, ASTNode> result = BlockSupportImpl.reparse(file, oldFileNode, changedPsiRange, newDocumentText, task.indicator, task.myLastCommittedText); DiffLog diffLog = result.getFirst(); ASTNode oldRoot = result.getSecond(); ASTNode newRoot = result.getThird(); PsiDocumentManagerBase documentManager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(task.project); List<BooleanRunnable> injectedRunnables = documentManager.reparseChangedInjectedFragments(document, file, changedPsiRange, task.indicator, oldRoot, newRoot); outReparseInjectedProcessors.addAll(injectedRunnables); return () -> { FileViewProvider viewProvider = file.getViewProvider(); Document document1 = task.getDocument(); if (!task.isStillValid() || ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(file.getProject())).getCachedViewProvider(document1) != viewProvider) { return false; // optimistic locking failed } if (!ApplicationManager.getApplication().isWriteAccessAllowed()) { VirtualFile vFile = viewProvider.getVirtualFile(); LOG.error("Write action expected" + "; document=" + document1 + "; file=" + file + " of " + file.getClass() + "; file.valid=" + file.isValid() + "; file.eventSystemEnabled=" + viewProvider.isEventSystemEnabled() + "; viewProvider=" + viewProvider + " of " + viewProvider.getClass() + "; language=" + file.getLanguage() + "; vFile=" + vFile + " of " + vFile.getClass() + "; free-threaded=" + AbstractFileViewProvider.isFreeThreaded(viewProvider)); } diffLog.doActualPsiChange(file); assertAfterCommit(document1, file, (FileElement)oldFileNode); return true; }; }