@Override void doActualPsiChange(@NotNull PsiFile file, @NotNull ASTDiffBuilder astDiffBuilder) { ASTNode child = myOldNode; ASTNode parent = myOldParent; PsiElement psiParent = parent.getPsi(); PsiElement psiChild = file.isPhysical() ? child.getPsi() : null; if (psiParent != null && psiChild != null) { PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(file.getManager()); event.setParent(psiParent); event.setChild(psiChild); event.setFile(file); ((PsiManagerEx)file.getManager()).beforeChildRemoval(event); } astDiffBuilder.nodeDeleted(parent, child); ((TreeElement)child).rawRemove(); ((CompositeElement)parent).subtreeChanged(); DebugUtil.checkTreeStructure(parent); }
public static void sendAfterChildrenChangedEvent(@NotNull PsiManagerImpl manager, @NotNull PsiFile scope, int oldLength, boolean isGenericChange) { if (!scope.isPhysical()) { manager.afterChange(false); return; } PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(manager); event.setParent(scope); event.setFile(scope); event.setOffset(0); event.setOldLength(oldLength); event.setGenericChange(isGenericChange); manager.childrenChanged(event); }
@Override public void beforeRootsChange(final ModuleRootEvent event) { if (!myFileManager.isInitialized()) return; if (event.isCausedByFileTypesChange()) return; ApplicationManager.getApplication().runWriteAction( new ExternalChangeAction() { @Override public void run() { depthCounter++; if (depthCounter > 1) return; PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_ROOTS); final VirtualFile[] contentRoots = myProjectRootManager.getContentRoots(); LOG.assertTrue(myOldContentRoots == null); myOldContentRoots = contentRoots; treeEvent.setOldValue(contentRoots); myManager.beforePropertyChange(treeEvent); } } ); }
public static void sendAfterChildrenChangedEvent(@NotNull PsiManagerImpl manager, @NotNull PsiFileImpl scope, int oldLength, boolean isGenericChange) { if(!scope.isPhysical()) { manager.afterChange(false); return; } PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(manager); event.setParent(scope); event.setFile(scope); event.setOffset(0); event.setOldLength(oldLength); event.setGeneric(isGenericChange); manager.childrenChanged(event); }
void fireEvent(int parentStart, PsiFile file, CompositeElement parent) { PsiTreeChangeEventImpl e = createEvent(file, myOffset + parentStart); if (myOldChild == myNewChild && myNewChild != null) { childrenChanged(e, myNewChild, myOldLength); } else if (myOldChild != null && myNewChild != null) { childReplaced(e, myOldChild, myNewChild, parent); } else if (myOldChild != null) { childRemoved(e, myOldChild, parent); } else if (myNewChild != null) { childAdded(e, myNewChild, parent); } }
public void forceReload(@Nonnull VirtualFile vFile) { LanguageSubstitutors.cancelReparsing(vFile); FileViewProvider viewProvider = findCachedViewProvider(vFile); if (viewProvider == null) { return; } ApplicationManager.getApplication().assertWriteAccessAllowed(); VirtualFile dir = vFile.getParent(); PsiDirectory parentDir = dir == null ? null : getCachedDirectory(dir); PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(myManager); if (parentDir == null) { event.setPropertyName(PsiTreeChangeEvent.PROP_UNLOADED_PSI); myManager.beforePropertyChange(event); setViewProvider(vFile, null); myManager.propertyChanged(event); } else { event.setParent(parentDir); myManager.beforeChildrenChange(event); setViewProvider(vFile, null); myManager.childrenChanged(event); } }
void processFileTypesChanged() { if (myProcessingFileTypesChange) return; myProcessingFileTypesChange = true; DebugUtil.performPsiModification(null, () -> { try { ApplicationManager.getApplication().runWriteAction(() -> { PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(myManager); event.setPropertyName(PsiTreeChangeEvent.PROP_FILE_TYPES); myManager.beforePropertyChange(event); invalidateAllPsi(); myManager.propertyChanged(event); }); } finally { myProcessingFileTypesChange = false; } }); }
@Override public void fileCreated(@Nonnull VirtualFileEvent event) { final VirtualFile vFile = event.getFile(); ApplicationManager.getApplication().runWriteAction((ExternalChangeAction)() -> { VirtualFile parent = vFile.getParent(); PsiDirectory parentDir = getCachedDirectory(parent); if (parentDir == null) { // parent directory was never accessed via PSI handleVfsChangeWithoutPsi(vFile); return; } PsiFileSystemItem item = vFile.isDirectory() ? myFileManager.findDirectory(vFile) : myFileManager.findFile(vFile); if (item != null && item.getProject() == myManager.getProject()) { PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); treeEvent.setParent(parentDir); myManager.beforeChildAddition(treeEvent); treeEvent.setChild(item); myManager.childAdded(treeEvent); } }); }
@Override public void beforeFileDeletion(@Nonnull VirtualFileEvent event) { final VirtualFile vFile = event.getFile(); VirtualFile parent = vFile.getParent(); final PsiDirectory parentDir = getCachedDirectory(parent); if (parentDir == null) return; // do not notify listeners if parent directory was never accessed via PSI ApplicationManager.getApplication().runWriteAction((ExternalChangeAction)() -> { PsiFileSystemItem item = vFile.isDirectory() ? myFileManager.findDirectory(vFile) : myFileManager.getCachedPsiFile(vFile); if (item != null) { PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); treeEvent.setParent(parentDir); treeEvent.setChild(item); myManager.beforeChildRemoval(treeEvent); } }); }
@Override public void beforeRootsChange(final ModuleRootEvent event) { if (event.isCausedByFileTypesChange()) return; ApplicationManager.getApplication().runWriteAction((ExternalChangeAction)() -> { depthCounter++; if (depthCounter > 1) return; PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_ROOTS); final VirtualFile[] contentRoots = myProjectRootManager.getContentRoots(); LOG.assertTrue(myOldContentRoots == null); myOldContentRoots = contentRoots; treeEvent.setOldValue(contentRoots); myManager.beforePropertyChange(treeEvent); }); }
private static String eventText(PsiTreeChangeEvent event, PsiTreeChangeEventImpl.PsiEventType code) { PsiElement parent = event.getParent(); PsiElement oldChild = event.getOldChild(); if (oldChild == null) oldChild = event.getChild(); PsiElement newChild = event.getNewChild(); return code + ":" + (parent == null ? null : parent.getNode().getElementType()) + "/" + (oldChild == null ? null : oldChild.getNode().getElementType()) + "->" + (newChild == null ? null : newChild.getNode().getElementType()) + ";"; }
private void assertBeforeEventFired(PsiTreeChangeEvent afterEvent) { PsiTreeChangeEventImpl.PsiEventType code = ((PsiTreeChangeEventImpl)afterEvent).getCode(); assertFalse(code.name(), code.name().startsWith("BEFORE_")); PsiTreeChangeEventImpl.PsiEventType beforeCode = PsiTreeChangeEventImpl.PsiEventType.values()[code.ordinal() - 1]; assertTrue(beforeCode.name(), beforeCode.name().startsWith("BEFORE_")); String beforeText = eventText(afterEvent, beforeCode); int i = eventsFired.indexOf(beforeText); assertTrue("Event '" + beforeText + "' must be fired. Events so far: " + eventsFired, i >= 0); }
@Override void doActualPsiChange(@NotNull PsiFile file, @NotNull ASTDiffBuilder astDiffBuilder) { ASTNode anchor = null; ASTNode firstChildNode = myOldParent.getFirstChildNode(); for (int i = 0; i < myPos; i++) { anchor = anchor == null ? firstChildNode : anchor.getTreeNext(); } PsiElement psiParent = myOldParent.getPsi(); PsiElement psiChild = getPsi(myNewNode, file); if (psiParent != null && psiChild != null) { PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(file.getManager()); event.setParent(psiParent); event.setChild(psiChild); event.setFile(file); ((PsiManagerEx)file.getManager()).beforeChildAddition(event); } ((TreeElement)myNewNode).rawRemove(); if (anchor != null) { ((TreeElement)anchor).rawInsertAfterMe((TreeElement)myNewNode); } else { if (firstChildNode != null) { ((TreeElement)firstChildNode).rawInsertBeforeMe((TreeElement)myNewNode); } else { ((CompositeElement)myOldParent).rawAddChildren((TreeElement)myNewNode); } } astDiffBuilder.nodeInserted(myOldParent, myNewNode, myPos); ((TreeElement)myNewNode).clearCaches(); ((CompositeElement)myOldParent).subtreeChanged(); DebugUtil.checkTreeStructure(myOldParent); }
public static void sendBeforeChildrenChangeEvent(@NotNull PsiManagerImpl manager, @NotNull PsiElement scope, boolean isGenericChange) { if (!scope.isPhysical()) { manager.beforeChange(false); return; } PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(manager); event.setParent(scope); event.setFile(scope.getContainingFile()); TextRange range = scope.getTextRange(); event.setOffset(range == null ? 0 : range.getStartOffset()); event.setOldLength(scope.getTextLength()); // the "generic" event is being sent on every PSI change. It does not carry any specific info except the fact that "something has changed" event.setGenericChange(isGenericChange); manager.beforeChildrenChange(event); }
@Override public void childrenChanged(@NotNull PsiTreeChangeEvent event) { if (((PsiTreeChangeEventImpl)event).isGenericChange()) { return; } queueElement(event.getParent(), true, event); }
private void handleVfsChangeWithoutPsi(@NotNull VirtualFile vFile) { if (!myReportedUnloadedPsiChange && isInRootModel(vFile)) { PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(myManager); myFileManager.firePropertyChangedForUnloadedPsi(event, vFile); myReportedUnloadedPsiChange = true; } }
@Override public void registerIndexableSet(@NotNull IndexableFileSet set, @Nullable Project project) { myIndexableSets.add(set); myIndexableSetToProjectMap.put(set, project); if (project != null) { ((PsiManagerImpl)PsiManager.getInstance(project)).addTreeChangePreprocessor(new PsiTreeChangePreprocessor() { @Override public void treeChanged(@NotNull PsiTreeChangeEventImpl event) { if (event.isGenericChange() && event.getCode() == PsiTreeChangeEventImpl.PsiEventType.CHILDREN_CHANGED) { PsiFile file = event.getFile(); if (file != null) { VirtualFile virtualFile = file.getVirtualFile(); if (!clearUpToDateStateForPsiIndicesOfUnsavedDocuments(virtualFile)) { // change in persistent file if (virtualFile instanceof VirtualFileWithId) { int fileId = ((VirtualFileWithId)virtualFile).getId(); boolean wasIndexed = false; for (ID<?, ?> psiBackedIndex : myPsiDependentIndices) { if (IndexingStamp.isFileIndexedStateCurrent(fileId, psiBackedIndex)) { IndexingStamp.setFileIndexedStateOutdated(fileId, psiBackedIndex); wasIndexed = true; } } if (wasIndexed) { myChangedFilesCollector.scheduleForUpdate(virtualFile); IndexingStamp.flushCache(fileId); } } } } } } }); } }
public static void sendBeforeChildrenChangeEvent(@NotNull PsiManagerImpl manager, @NotNull PsiElement scope, boolean isGenericChange) { if(!scope.isPhysical()) { manager.beforeChange(false); return; } PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(manager); event.setParent(scope); event.setFile(scope.getContainingFile()); event.setOffset(scope.getTextRange().getStartOffset()); event.setOldLength(scope.getTextLength()); // the "generic" event is being sent on every PSI change. It does not carry any specific info except the fact that "something has changed" event.setGeneric(isGenericChange); manager.beforeChildrenChange(event); }
@Override public void childrenChanged(@NotNull PsiTreeChangeEvent event) { if (((PsiTreeChangeEventImpl)event).isGenericChildrenChange()) { return; } queueElement(event.getParent(), true, event); }
@Nonnull static PsiTreeChangeEventImpl createEvent(PsiFile file, int offset) { PsiTreeChangeEventImpl e = new PsiTreeChangeEventImpl(file.getManager()); e.setFile(file); e.setOffset(offset); return e; }
private void childReplaced(PsiTreeChangeEventImpl e, TreeElement oldChild, TreeElement newChild, CompositeElement parent) { e.setParent(parent.getPsi()); e.setOldChild(oldChild.getPsi()); e.setChild(newChild.getPsi()); e.setNewChild(newChild.getPsi()); e.setOldLength(myOldLength); getPsiManagerImpl(e).childReplaced(e); }
public static void sendBeforeChildrenChangeEvent(@Nonnull PsiManagerImpl manager, @Nonnull PsiElement scope, boolean isGenericChange) { if (!scope.isPhysical()) { manager.beforeChange(false); return; } PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(manager); event.setParent(scope); event.setFile(scope.getContainingFile()); TextRange range = scope.getTextRange(); event.setOffset(range == null ? 0 : range.getStartOffset()); event.setOldLength(scope.getTextLength()); // the "generic" event is being sent on every PSI change. It does not carry any specific info except the fact that "something has changed" event.setGenericChange(isGenericChange); manager.beforeChildrenChange(event); }
public static void sendAfterChildrenChangedEvent(@Nonnull PsiManagerImpl manager, @Nonnull PsiFile scope, int oldLength, boolean isGenericChange) { if (!scope.isPhysical()) { manager.afterChange(false); return; } PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(manager); event.setParent(scope); event.setFile(scope); event.setOffset(0); event.setOldLength(oldLength); event.setGenericChange(isGenericChange); manager.childrenChanged(event); }
public void firePropertyChangedForUnloadedPsi() { PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(myManager); event.setPropertyName(PsiTreeChangeEvent.PROP_UNLOADED_PSI); myManager.beforePropertyChange(event); myManager.propertyChanged(event); }
@Override public void childrenChanged(@Nonnull PsiTreeChangeEvent event) { if (((PsiTreeChangeEventImpl)event).isGenericChange()) { return; } queueElement(event.getParent(), true, event); }
@Override public void fileDeleted(@Nonnull final VirtualFileEvent event) { final VirtualFile vFile = event.getFile(); VirtualFile parent = event.getParent(); final PsiDirectory parentDir = getCachedDirectory(parent); final PsiFile psiFile = myFileManager.getCachedPsiFileInner(vFile); PsiElement element; if (psiFile != null) { clearViewProvider(vFile, "PSI fileDeleted"); element = psiFile; } else { final PsiDirectory psiDir = myFileManager.getCachedDirectory(vFile); if (psiDir != null) { myFileManager.removeInvalidFilesAndDirs(false); element = psiDir; } else if (parent != null) { handleVfsChangeWithoutPsi(parent); return; } else { element = null; } } if (element != null && parentDir != null) { ApplicationManager.getApplication().runWriteAction((ExternalChangeAction)() -> { PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); treeEvent.setParent(parentDir); treeEvent.setChild(element); myManager.childRemoved(treeEvent); }); } }
@Override public void registerIndexableSet(@Nonnull IndexableFileSet set, @Nullable Project project) { myIndexableSets.add(set); myIndexableSetToProjectMap.put(set, project); if (project != null) { ((PsiManagerImpl)PsiManager.getInstance(project)).addTreeChangePreprocessor(event -> { if (event.isGenericChange() && event.getCode() == PsiTreeChangeEventImpl.PsiEventType.CHILDREN_CHANGED) { PsiFile file = event.getFile(); if (file != null) { waitUntilIndicesAreInitialized(); VirtualFile virtualFile = file.getVirtualFile(); if (!clearUpToDateStateForPsiIndicesOfUnsavedDocuments(virtualFile)) { // change in persistent file if (virtualFile instanceof VirtualFileWithId) { int fileId = ((VirtualFileWithId)virtualFile).getId(); boolean wasIndexed = false; List<ID<?, ?>> candidates = getAffectedIndexCandidates(virtualFile); for (ID<?, ?> psiBackedIndex : myPsiDependentIndices) { if (!candidates.contains(psiBackedIndex)) continue; if (getInputFilter(psiBackedIndex).acceptInput(project, virtualFile)) { getIndex(psiBackedIndex).resetIndexedStateForFile(fileId); wasIndexed = true; } } if (wasIndexed) { myChangedFilesCollector.scheduleForUpdate(virtualFile); IndexingStamp.flushCache(fileId); } } } } } }); } }
@Override public void treeChanged(@NotNull PsiTreeChangeEventImpl event) { if (event.getFile() instanceof HeaderPsiFile) { ArmaPluginUserData.getInstance().reparseConfigs(event.getFile()); } }
private void logEvent(PsiTreeChangeEvent event) { PsiTreeChangeEventImpl.PsiEventType code = ((PsiTreeChangeEventImpl)event).getCode(); eventsFired += eventText(event, code); }
@Override public void beforeChildRemoval(@NotNull final PsiTreeChangeEventImpl event) { }
@Override public void beforeChildReplacement(@NotNull final PsiTreeChangeEventImpl event) { }
@Override public void beforeChildAddition(@NotNull PsiTreeChangeEventImpl event) { }
@Override public void fileMoved(@NotNull VirtualFileMoveEvent event) { final VirtualFile vFile = event.getFile(); final PsiDirectory oldParentDir = myFileManager.findDirectory(event.getOldParent()); final PsiDirectory newParentDir = myFileManager.findDirectory(event.getNewParent()); if (oldParentDir == null && newParentDir == null) return; final PsiElement oldElement = vFile.isDirectory() ? myFileManager.getCachedDirectory(vFile) : myFileManager.getCachedPsiFileInner(vFile); myFileManager.removeInvalidFilesAndDirs(true); final PsiElement newElement; final FileViewProvider newViewProvider; if (!vFile.isDirectory()){ newViewProvider = myFileManager.createFileViewProvider(vFile, true); newElement = newViewProvider.getPsi(myFileManager.findViewProvider(vFile).getBaseLanguage()); } else { newElement = myFileManager.findDirectory(vFile); newViewProvider = null; } if (oldElement == null && newElement == null) return; ApplicationManager.getApplication().runWriteAction( new ExternalChangeAction() { @Override public void run() { PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager); if (oldElement == null) { myFileManager.setViewProvider(vFile, newViewProvider); treeEvent.setParent(newParentDir); treeEvent.setChild(newElement); myManager.childAdded(treeEvent); } else { if (newElement == null) { myFileManager.setViewProvider(vFile, null); treeEvent.setParent(oldParentDir); treeEvent.setChild(oldElement); myManager.childRemoved(treeEvent); } else { if (newElement instanceof PsiDirectory || FileManagerImpl.areViewProvidersEquivalent(newViewProvider, ((PsiFile) oldElement).getViewProvider())) { treeEvent.setOldParent(oldParentDir); treeEvent.setNewParent(newParentDir); treeEvent.setChild(oldElement); myManager.childMoved(treeEvent); } else { myFileManager.setViewProvider(vFile, newViewProvider); PsiTreeChangeEventImpl treeRemoveEvent = new PsiTreeChangeEventImpl(myManager); treeRemoveEvent.setParent(oldParentDir); treeRemoveEvent.setChild(oldElement); myManager.childRemoved(treeRemoveEvent); PsiTreeChangeEventImpl treeAddEvent = new PsiTreeChangeEventImpl(myManager); treeAddEvent.setParent(newParentDir); treeAddEvent.setChild(newElement); myManager.childAdded(treeAddEvent); } } } } } ); }