diff --git a/platform/lang-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java b/platform/lang-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java index d1afeda79323..8d0a5766ba16 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java @@ -19,8 +19,6 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.roots.ContentIterator; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import java.util.Set; @@ -37,9 +35,7 @@ public class AdditionalIndexableFileSet implements IndexableFileSet { public AdditionalIndexableFileSet(IndexedRootsProvider... extensions) { for (IndexedRootsProvider provider : extensions) { - for (String url : provider.getRootsToIndex()) { - ContainerUtil.addIfNotNull(VirtualFileManager.getInstance().findFileByUrl(url), myRoots); - } + myRoots.addAll(IndexableSetContributor.getRootsToIndex(provider)); } } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java index aac358d4351c..50e59becfa26 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java @@ -1906,9 +1906,7 @@ public class FileBasedIndex implements ApplicationComponent { if (project.isDisposed()) { return; } - final Set rootsToIndex = provider.getRootsToIndex(); - for (String url : rootsToIndex) { - final VirtualFile root = VirtualFileManager.getInstance().findFileByUrl(url); + for (VirtualFile root : IndexableSetContributor.getRootsToIndex(provider)) { if (visitedRoots.add(root)) { iterateRecursively(root, processor, indicator); } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexableSetContributor.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexableSetContributor.java new file mode 100644 index 000000000000..3cf4d907d819 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexableSetContributor.java @@ -0,0 +1,41 @@ +package com.intellij.util.indexing; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.NotNullFunction; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author peter + */ +public abstract class IndexableSetContributor implements IndexedRootsProvider { + @Override + public final Set getRootsToIndex() { + return ContainerUtil.map2Set(getAdditionalRootsToIndex(), new NotNullFunction() { + @NotNull + @Override + public String fun(VirtualFile virtualFile) { + return virtualFile.getUrl(); + } + }); + } + + public static Set getRootsToIndex(IndexedRootsProvider provider) { + if (provider instanceof IndexableSetContributor) { + return ((IndexableSetContributor)provider).getAdditionalRootsToIndex(); + } + + final HashSet result = new HashSet(); + for (String url : provider.getRootsToIndex()) { + ContainerUtil.addIfNotNull(VirtualFileManager.getInstance().findFileByUrl(url), result); + } + return result; + } + + + public abstract Set getAdditionalRootsToIndex(); +} diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexedRootsProvider.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexedRootsProvider.java index 5e683479b1a8..bca1b6d4aede 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/IndexedRootsProvider.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexedRootsProvider.java @@ -21,6 +21,7 @@ import com.intellij.openapi.extensions.ExtensionPointName; import java.util.Set; /** + * @deprecated extend {@link com.intellij.util.indexing.IndexableSetContributor} instead * @author Dmitry Avdeev */ public interface IndexedRootsProvider { @@ -28,6 +29,7 @@ public interface IndexedRootsProvider { ExtensionPointName EP_NAME = new ExtensionPointName("com.intellij.indexedRootsProvider"); /** + * @deprecated * @return each string is VFS url {@link com.intellij.openapi.vfs.VirtualFile#getUrl()} of the root to index. Cannot depend on project. */ Set getRootsToIndex(); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java index f39fae603943..ae295622ec5d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java @@ -126,23 +126,27 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap } @TestOnly - public void cleanupForNextTest() throws IOException { + public void cleanupForNextTest(Set survivors) throws IOException { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { FileDocumentManager.getInstance().saveAllDocuments(); - refresh(false); } }); ((PersistentFS)ManagingFS.getInstance()).clearIdCache(); - - final VirtualFile[] roots = ManagingFS.getInstance().getRoots(this); - for (VirtualFile root : roots) { - if (root instanceof VirtualDirectoryImpl) { + + for (VirtualFile root : ManagingFS.getInstance().getRoots(this)) { + if (root instanceof VirtualDirectoryImpl && !survivors.contains(root)) { final VirtualDirectoryImpl directory = (VirtualDirectoryImpl)root; - directory.cleanupCachedChildren(); + directory.cleanupCachedChildren(survivors); } } + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + refresh(false); + } + }); + myRootsToWatch.clear(); final File file = new File(FileUtil.getTempDirectory()); 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 f04cd9ac6405..c09216c8e727 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 @@ -360,8 +360,16 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } @TestOnly - public synchronized void cleanupCachedChildren() { - myChildren = null; + public synchronized void cleanupCachedChildren(Set survivors) { + if (survivors.contains(this)) { + for (VirtualFile file : getCachedChildren()) { + if (file instanceof VirtualDirectoryImpl) { + ((VirtualDirectoryImpl)file).cleanupCachedChildren(survivors); + } + } + } else { + myChildren = null; + } } public InputStream getInputStream() throws IOException { diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 6139fac76449..802273fc7c08 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -53,6 +53,7 @@ import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl; import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl; import com.intellij.openapi.vfs.newvfs.ManagingFS; +import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl; import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS; import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; import com.intellij.psi.PsiDocumentManager; @@ -62,6 +63,8 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.impl.PsiManagerEx; import com.intellij.util.PatchedWeakReference; +import com.intellij.util.indexing.IndexableSetContributor; +import com.intellij.util.indexing.IndexedRootsProvider; import junit.framework.TestCase; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -73,6 +76,7 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.HashSet; +import java.util.Set; /** * @author yole @@ -96,6 +100,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro private ThreadTracker myThreadTracker; protected static boolean ourPlatformPrefixInitialized; + private static Set ourEternallyLivingFiles; static { Logger.setFactory(TestLoggerFactory.getInstance()); @@ -267,7 +272,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro try { LocalFileSystemImpl localFileSystem = (LocalFileSystemImpl)LocalFileSystem.getInstance(); if (localFileSystem != null) { - localFileSystem.cleanupForNextTest(); + localFileSystem.cleanupForNextTest(eternallyLivingFiles()); } } catch (IOException e) { @@ -283,6 +288,35 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro PatchedWeakReference.clearAll(); } + private static void addSubTree(VirtualFile root, Set to) { + if (root instanceof VirtualDirectoryImpl) { + for (VirtualFile child : ((VirtualDirectoryImpl)root).getCachedChildren()) { + to.add(child); + addSubTree(child, to); + } + } + } + + private static Set eternallyLivingFiles() { + if (ourEternallyLivingFiles != null) { + return ourEternallyLivingFiles; + } + + Set survivors = new HashSet(); + + for (IndexedRootsProvider provider : IndexedRootsProvider.EP_NAME.getExtensions()) { + for (VirtualFile file : IndexableSetContributor.getRootsToIndex(provider)) { + addSubTree(file, survivors); + while (file != null && survivors.add(file)) { + file = file.getParent(); + } + } + } + + ourEternallyLivingFiles = survivors; + return survivors; + } + protected void tearDown() throws Exception { LightPlatformTestCase.doTearDown(getProject(), ourApplication, false); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/AbstractDslIndexedRootsProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/AbstractDslIndexedRootsProvider.java index e8c01b69eac4..de632f999bdb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/AbstractDslIndexedRootsProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/AbstractDslIndexedRootsProvider.java @@ -18,13 +18,14 @@ package org.jetbrains.plugins.groovy.dsl; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.PathUtil; +import com.intellij.util.indexing.IndexableSetContributor; import java.io.File; import java.util.Collections; import java.util.Set; -public class AbstractDslIndexedRootsProvider implements GroovyDslIndexedRootProvider { - private final Set ourDslsDirs; +public class AbstractDslIndexedRootsProvider extends IndexableSetContributor implements GroovyDslIndexedRootProvider{ + private final Set ourDslsDirs; public AbstractDslIndexedRootsProvider() { final File jarPath = new File(PathUtil.getJarPathForClass(getClass())); @@ -38,7 +39,7 @@ public class AbstractDslIndexedRootsProvider implements GroovyDslIndexedRootProv final VirtualFile parent = LocalFileSystem.getInstance().refreshAndFindFileByPath(dirPath); assert parent != null : dirPath; parent.getChildren(); - ourDslsDirs = Collections.singleton(parent.getUrl()); + ourDslsDirs = Collections.singleton(parent); parent.refresh(true, true); } @@ -46,7 +47,8 @@ public class AbstractDslIndexedRootsProvider implements GroovyDslIndexedRootProv return "standardDsls"; } - public Set getRootsToIndex() { + @Override + public Set getAdditionalRootsToIndex() { return ourDslsDirs; } } diff --git a/xml/impl/src/com/intellij/xml/index/ExternalResourcesRootsProvider.java b/xml/impl/src/com/intellij/xml/index/ExternalResourcesRootsProvider.java index d30732b5eb60..3506b1a0cddf 100644 --- a/xml/impl/src/com/intellij/xml/index/ExternalResourcesRootsProvider.java +++ b/xml/impl/src/com/intellij/xml/index/ExternalResourcesRootsProvider.java @@ -21,7 +21,7 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.hash.HashSet; -import com.intellij.util.indexing.IndexedRootsProvider; +import com.intellij.util.indexing.IndexableSetContributor; import org.jetbrains.annotations.Nullable; import java.net.URL; @@ -30,7 +30,7 @@ import java.util.Set; /** * @author Dmitry Avdeev */ -public class ExternalResourcesRootsProvider implements IndexedRootsProvider { +public class ExternalResourcesRootsProvider extends IndexableSetContributor { private static final URL ourRoot = ExternalResourcesRootsProvider.class.getResource(ExternalResourceManagerImpl.STANDARD_SCHEMAS); @Nullable @@ -38,17 +38,17 @@ public class ExternalResourcesRootsProvider implements IndexedRootsProvider { return ourRoot == null ? null : VfsUtil.findFileByURL(ourRoot); } - public Set getRootsToIndex() { + public Set getAdditionalRootsToIndex() { final VirtualFile standardSchemas = getStandardSchemas(); String path = FetchExtResourceAction.getExternalResourcesPath(); LocalFileSystem localFileSystem = LocalFileSystem.getInstance(); VirtualFile extResources = localFileSystem.findFileByPath(path); - HashSet roots = new HashSet(2); + HashSet roots = new HashSet(2); if (standardSchemas != null) { - roots.add(standardSchemas.getUrl()); + roots.add(standardSchemas); } if (extResources != null) { - roots.add(extResources.getUrl()); + roots.add(extResources); } return roots; }