make VirtualFilePointerManager more responsive to VFS changes to update virtual file pointers sooner to fix EA-87976 - assert: RootIndex.ensureValid

This commit is contained in:
Alexey Kudravtsev
2016-09-07 14:12:33 +03:00
parent a004b75c0b
commit 9e94a4253d
2 changed files with 53 additions and 0 deletions
@@ -26,6 +26,7 @@ import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.*;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener;
@@ -529,6 +530,13 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
}
@Override
public long getModificationCount() {
// depend on PersistentFS.getInstance().getStructureModificationCount() because com.intellij.openapi.vfs.impl.FilePointerPartNode.update is
// depend on its own modcount because we need to change both before and after VFS changes
return super.getModificationCount() + PersistentFS.getInstance().getStructureModificationCount();
}
private static class DelegatingDisposable implements Disposable {
private static final ConcurrentMap<Disposable, DelegatingDisposable> ourInstances =
ContainerUtil.newConcurrentMap(ContainerUtil.<Disposable>identityStrategy());
@@ -23,7 +23,11 @@ import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.impl.OrderEntryUtil;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryUtil;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
@@ -792,4 +796,45 @@ public class VirtualFilePointerTest extends PlatformTestCase {
assertEquals(dir2, p1.getFile());
assertEquals(dir2, p2.getFile());
}
public void testVirtualPointersMustBeAlreadyUpToDateInVFSChangeListeners() throws IOException {
File tempDirectory = createTempDirectory();
final VirtualFile root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDirectory);
VirtualFile dir1 = createChildDirectory(root, "dir1");
VirtualFile file = createChildData(dir1, "x.txt");
setFileText(file, "xxxxxx");
PsiTestUtil.addLibrary(getModule(), dir1.getPath());
VirtualFileAdapter listener = new VirtualFileAdapter() {
@Override
public void fileDeleted(@NotNull VirtualFileEvent event) {
ProjectRootManager.getInstance(getProject()).getFileIndex().getModuleForFile(dir1);
}
};
LocalFileSystem.getInstance().addVirtualFileListener(listener);
Disposer.register(disposable, () -> LocalFileSystem.getInstance().removeVirtualFileListener(listener));
assertTrue(FileUtil.delete(new File(dir1.getPath())));
System.out.println("deleted "+dir1);
try {
while (root.findChild("dir1") != null) {
UIUtil.dispatchAllInvocationEvents();
LocalFileSystem.getInstance().refresh(false);
}
}
finally {
ApplicationManager.getApplication().runWriteAction(() -> {
Library library = LibraryUtil.findLibrary(getModule(), "dir1");
LibraryTable.ModifiableModel model = library.getTable().getModifiableModel();
model.removeLibrary(library);
model.commit();
});
PsiTestUtil.removeAllRoots(getModule(), null);
}
}
}