diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java index 3fd44e3ebef9..819d56f3f56c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java @@ -299,13 +299,16 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { return Collections.emptyList(); } - if (!ourPersistence.areChildrenLoaded(this)) { - final String[] names = ourPersistence.listPersisted(this); - final NewVirtualFileSystem delegate = PersistentFS.replaceWithNativeFS(getFileSystem()); - for (String name : names) { - findChild(name, false, false, delegate); - } + if (ourPersistence.areChildrenLoaded(this)) { + return Arrays.asList(getChildren()); } + + final String[] names = ourPersistence.listPersisted(this); + final NewVirtualFileSystem delegate = PersistentFS.replaceWithNativeFS(getFileSystem()); + for (String name : names) { + findChild(name, false, false, delegate); + } + return getCachedChildren(); } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/PersistentFsTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/PersistentFsTest.java index 1d4b76e993a4..59568a5f7d35 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/PersistentFsTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/PersistentFsTest.java @@ -187,6 +187,60 @@ public class PersistentFsTest extends PlatformTestCase { assertEquals(1, logCount[0]); } + public void testIterInDbChildrenWorksForRemovedDirsAfterRestart() throws IOException { + // test (re)creates /subDir/subSubDir/Foo.txt outside tested/watched project and checks removal events on subDir / subSubDir / Foo.txt + // test starts real testing ("after restart") after launching second time using same VFS + // hours spent writing this test: 4 + VirtualFile projectStructure = createTestProjectStructure(); + String testName = getTestName(false); + + // wrt persistence subDir becomes partially loaded and subsubDir becomes fully loaded + File nestedDirOutsideTheProject = new File(projectStructure.getPath() + "../../../"+testName + "/subDir", "subSubDir"); + Disposable disposable = null; + + try { + boolean atleastSecondRun = nestedDirOutsideTheProject.getParentFile().getParentFile().exists(); + StringBuilder eventLog = new StringBuilder(); + + if (atleastSecondRun) { + disposable = Disposer.newDisposable(); + getProject().getMessageBus().connect(disposable).subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() { + @Override + public void before(@NotNull List events) { + for(VFileEvent event:events) { + if (event instanceof VFileDeleteEvent) process(((VFileDeleteEvent)event).getFile()); + } + } + private void process(VirtualFile file) { + String path = file.getPath(); + eventLog.append(path.substring(path.indexOf(testName) + testName.length() + 1)).append("\n"); + Iterable files = ((NewVirtualFile)file).iterInDbChildren(); + for(VirtualFile nested:files) process(nested); + } + }); + } + + // recreating structure will fire vfs removal events + VirtualFile nestedDirOutsideTheProjectFile = VfsUtil.createDirectories(nestedDirOutsideTheProject.getPath()); + WriteAction.run(() -> nestedDirOutsideTheProjectFile.createChildData(null, "Foo.txt")); + + // subsubDir becomes fully loaded wrt persistence + nestedDirOutsideTheProjectFile.getChildren(); + + if (atleastSecondRun) { + assertEquals("subDir\n" + + "subDir/subSubDir\n" + + "subDir/subSubDir/Foo.txt\n", + eventLog.toString() + ); + } + } finally { + if (disposable != null) Disposer.dispose(disposable); + // remove /subDir via java.io to have vfs events on next test launch + FileUtil.delete(nestedDirOutsideTheProject.getParentFile()); + } + } + public void testModCountIncreases() throws IOException { VirtualFile vFile = setupFile(); ManagingFS managingFS = ManagingFS.getInstance();