move RootIndex.getDirectoriesByPackageName stuff to a separate class

This commit is contained in:
peter
2015-05-30 16:53:27 +02:00
parent 6f7156d96e
commit 7e5e8bc17a
4 changed files with 99 additions and 95 deletions
@@ -276,8 +276,6 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertTrue(new File(path + File.separatorChar + "dir1" + File.separatorChar + "dir2").mkdirs());
assertTrue(new File(path + File.separatorChar + "CVS").mkdirs());
VirtualFileManager.getInstance().syncRefresh();
myIndex.checkConsistency();
}
public void testDeleteDir() throws Exception {
@@ -285,45 +283,29 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile subdir2 = createChildDirectory(subdir1, "subdir2");
createChildDirectory(subdir2, "subdir3");
myIndex.checkConsistency();
delete(subdir1);
myIndex.checkConsistency();
}
public void testMoveDir() throws Exception {
VirtualFile subdir = createChildDirectory(mySrcDir2, "subdir1");
createChildDirectory(subdir, "subdir2");
myIndex.checkConsistency();
move(subdir, mySrcDir1);
myIndex.checkConsistency();
}
public void testRenameDir() throws Exception {
VirtualFile subdir = createChildDirectory(mySrcDir2, "subdir1");
createChildDirectory(subdir, "subdir2");
myIndex.checkConsistency();
rename(subdir, "abc.d");
myIndex.checkConsistency();
}
public void testRenameRoot() throws Exception {
rename(myModule1Dir, "newName");
myIndex.checkConsistency();
}
public void testMoveRoot() throws Exception {
move(myModule1Dir, myModule3Dir);
myIndex.checkConsistency();
}
public void testAddProjectDir() throws Exception {
@@ -333,19 +315,14 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile newDir = createChildDirectory(myModule1Dir.getParent(), "newDir");
createChildDirectory(newDir, "subdir");
myIndex.checkConsistency();
PsiTestUtil.addContentRoot(myModule, newDir);
}
}.execute().throwException();
myIndex.checkConsistency();
}
public void testChangeIgnoreList() throws Exception {
VirtualFile newDir = createChildDirectory(myModule1Dir, "newDir");
myIndex.checkConsistency();
assertInProject(newDir);
final FileTypeManagerEx fileTypeManager = (FileTypeManagerEx)FileTypeManager.getInstance();
@@ -358,7 +335,6 @@ public class DirectoryIndexTest extends IdeaTestCase {
fileTypeManager.setIgnoredFilesList(list1);
}
});
myIndex.checkConsistency();
assertNotInProject(newDir);
}
finally {
@@ -383,7 +359,6 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
public void testAddModule() throws Exception {
myIndex.checkConsistency();
new WriteCommandAction.Simple(getProject()) {
@Override
@@ -395,9 +370,6 @@ public class DirectoryIndexTest extends IdeaTestCase {
PsiTestUtil.addContentRoot(module, newModuleContent);
}
}.execute().throwException();
myIndex.checkConsistency();
}
public void testModuleUnderIgnoredDir() throws IOException {
@@ -455,8 +427,6 @@ public class DirectoryIndexTest extends IdeaTestCase {
public void testExplicitExcludeOfInner() throws Exception {
PsiTestUtil.addExcludedRoot(myModule, myModule2Dir);
myIndex.checkConsistency();
checkInfo(myModule2Dir, myModule2, false, false, null, null);
checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
}
@@ -646,8 +616,6 @@ public class DirectoryIndexTest extends IdeaTestCase {
public void testLibraryDirInContent() throws Exception {
ModuleRootModificationUtil.addModuleLibrary(myModule, myModule1Dir.getUrl());
myIndex.checkConsistency();
checkInfo(myModule1Dir, myModule, true, false, "", null, myModule);
checkInfo(mySrcDir1, myModule, true, false, "", JavaSourceRootType.SOURCE, myModule);
@@ -146,11 +146,6 @@ public class DirectoryIndexImpl extends DirectoryIndex {
};
}
@TestOnly
public void checkConsistency() {
getRootIndex().checkConsistency();
}
@Override
public DirectoryInfo getInfoForDirectory(@NotNull VirtualFile dir) {
DirectoryInfo info = getInfoForFile(dir);
@@ -0,0 +1,92 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.util.LowMemoryWatcher;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author peter
*/
class PackageDirectoryCache {
private final RootIndex myRootIndex;
private final MultiMap<String, VirtualFile> myRootsByPackagePrefix;
private final Map<String, List<VirtualFile>> myDirectoriesByPackageNameCache = ContainerUtil.newConcurrentMap();
private final Set<String> myNonExistentPackages = ContainerUtil.newConcurrentSet();
@SuppressWarnings("UnusedDeclaration")
private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() {
@Override
public void run() {
myNonExistentPackages.clear();
}
});
PackageDirectoryCache(RootIndex rootIndex, MultiMap<String, VirtualFile> rootsByPackagePrefix) {
myRootIndex = rootIndex;
myRootsByPackagePrefix = rootsByPackagePrefix;
}
@NotNull
List<VirtualFile> getDirectoriesByPackageName(@NotNull final String packageName) {
List<VirtualFile> result = myDirectoriesByPackageNameCache.get(packageName);
if (result == null) {
if (myNonExistentPackages.contains(packageName)) return Collections.emptyList();
result = ContainerUtil.newSmartList();
if (StringUtil.isNotEmpty(packageName) && !StringUtil.startsWithChar(packageName, '.')) {
int i = packageName.lastIndexOf('.');
while (true) {
String shortName = packageName.substring(i + 1);
String parentPackage = i > 0 ? packageName.substring(0, i) : "";
for (VirtualFile parentDir : getDirectoriesByPackageName(parentPackage)) {
VirtualFile child = parentDir.findChild(shortName);
if (child != null && child.isDirectory() && myRootIndex.getInfoForFile(child).isInProject()
&& packageName.equals(myRootIndex.getPackageName(child))) {
result.add(child);
}
}
if (i < 0) break;
i = packageName.lastIndexOf('.', i - 1);
}
}
for (VirtualFile file : myRootsByPackagePrefix.get(packageName)) {
if (file.isDirectory()) {
result.add(file);
}
}
if (!result.isEmpty()) {
myDirectoriesByPackageNameCache.put(packageName, result);
} else {
myNonExistentPackages.add(packageName);
}
}
return result;
}
}
@@ -25,14 +25,12 @@ import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.LowMemoryWatcher;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.util.CollectionQuery;
import com.intellij.util.EmptyQuery;
import com.intellij.util.Query;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
@@ -54,23 +52,14 @@ public class RootIndex {
};
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.RootIndex");
private final MultiMap<String, VirtualFile> myRootsByPackagePrefix = MultiMap.create();
private final Map<VirtualFile, String> myPackagePrefixByRoot = ContainerUtil.newHashMap();
private final Map<String, List<VirtualFile>> myDirectoriesByPackageNameCache = ContainerUtil.newConcurrentMap();
private final Set<String> myNonExistentPackages = ContainerUtil.newConcurrentSet();
private final InfoCache myInfoCache;
private final List<JpsModuleSourceRootType<?>> myRootTypes = ContainerUtil.newArrayList();
private final TObjectIntHashMap<JpsModuleSourceRootType<?>> myRootTypeId = new TObjectIntHashMap<JpsModuleSourceRootType<?>>();
@NotNull private final Project myProject;
private final PackageDirectoryCache myPackageDirectoryCache;
private volatile Map<VirtualFile, OrderEntry[]> myOrderEntries;
@SuppressWarnings("UnusedDeclaration")
private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() {
@Override
public void run() {
myNonExistentPackages.clear();
}
});
// made public for Upsource
public RootIndex(@NotNull Project project, @NotNull InfoCache cache) {
@@ -78,6 +67,7 @@ public class RootIndex {
myInfoCache = cache;
final RootInfo info = buildRootInfo(project);
MultiMap<String, VirtualFile> rootsByPackagePrefix = MultiMap.create();
Set<VirtualFile> allRoots = info.getAllRoots();
for (VirtualFile root : allRoots) {
List<VirtualFile> hierarchy = getHierarchy(root, allRoots, info);
@@ -85,9 +75,10 @@ public class RootIndex {
? calcDirectoryInfo(root, hierarchy, info)
: new Pair<DirectoryInfo, String>(NonProjectDirectoryInfo.IGNORED, null);
cacheInfos(root, root, pair.first);
myRootsByPackagePrefix.putValue(pair.second, root);
rootsByPackagePrefix.putValue(pair.second, root);
myPackagePrefixByRoot.put(root, pair.second);
}
myPackageDirectoryCache = new PackageDirectoryCache(this, rootsByPackagePrefix);
}
@NotNull
@@ -241,13 +232,6 @@ public class RootIndex {
return array;
}
public void checkConsistency() {
for (VirtualFile file : myRootsByPackagePrefix.values()) {
assert file.exists() : file.getPath() + " does not exist";
}
}
private int getRootTypeId(@NotNull JpsModuleSourceRootType<?> rootType) {
if (myRootTypeId.containsKey(rootType)) {
return myRootTypeId.get(rootType);
@@ -316,43 +300,8 @@ public class RootIndex {
}
@NotNull
public Query<VirtualFile> getDirectoriesByPackageName(@NotNull final String packageName, final boolean includeLibrarySources) {
List<VirtualFile> result = myDirectoriesByPackageNameCache.get(packageName);
if (result == null) {
if (myNonExistentPackages.contains(packageName)) return EmptyQuery.getEmptyQuery();
result = ContainerUtil.newSmartList();
if (StringUtil.isNotEmpty(packageName) && !StringUtil.startsWithChar(packageName, '.')) {
int i = packageName.lastIndexOf('.');
while (true) {
String shortName = packageName.substring(i + 1);
String parentPackage = i > 0 ? packageName.substring(0, i) : "";
for (VirtualFile parentDir : getDirectoriesByPackageName(parentPackage, true)) {
VirtualFile child = parentDir.findChild(shortName);
if (child != null && child.isDirectory() && getInfoForFile(child).isInProject()
&& packageName.equals(getPackageName(child))) {
result.add(child);
}
}
if (i < 0) break;
i = packageName.lastIndexOf('.', i - 1);
}
}
for (VirtualFile file : myRootsByPackagePrefix.get(packageName)) {
if (file.isDirectory()) {
result.add(file);
}
}
if (!result.isEmpty()) {
myDirectoriesByPackageNameCache.put(packageName, result);
} else {
myNonExistentPackages.add(packageName);
}
}
Query<VirtualFile> getDirectoriesByPackageName(@NotNull final String packageName, final boolean includeLibrarySources) {
List<VirtualFile> result = myPackageDirectoryCache.getDirectoriesByPackageName(packageName);
if (!includeLibrarySources) {
result = ContainerUtil.filter(result, new Condition<VirtualFile>() {
@Override