diff --git a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java index 36140ab44c21..f86ee9b496be 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java @@ -49,7 +49,7 @@ import static java.util.Collections.singletonList; public class DirectoryIndexTest extends IdeaTestCase { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.DirectoryIndexTest"); - private DirectoryIndex myIndex; + private DirectoryIndexImpl myIndex; private Module myModule2, myModule3; private VirtualFile myRootVFile; @@ -176,7 +176,7 @@ public class DirectoryIndexTest extends IdeaTestCase { } }); - myIndex = DirectoryIndex.getInstance(myProject); + myIndex = (DirectoryIndexImpl)DirectoryIndex.getInstance(myProject); // to not interfere with previous test firing vfs events VirtualFileManager.getInstance().syncRefresh(); } @@ -481,12 +481,12 @@ public class DirectoryIndexTest extends IdeaTestCase { ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Collections.emptyList(), Arrays.asList(mySrcDir1.getUrl())); checkInfo(mySrcDir1, myModule, false, true, "", JavaSourceRootType.SOURCE, myModule, myModule); - OrderEntry[] entries = myIndex.getInfoForFile(mySrcDir1).getOrderEntries(); + OrderEntry[] entries = myIndex.getOrderEntries(myIndex.getInfoForFile(mySrcDir1)); assertInstanceOf(entries[0], LibraryOrderEntry.class); assertInstanceOf(entries[1], ModuleSourceOrderEntry.class); checkInfo(myTestSrc1, myModule, false, true, "testSrc", JavaSourceRootType.TEST_SOURCE, myModule, myModule); - entries = myIndex.getInfoForFile(myTestSrc1).getOrderEntries(); + entries = myIndex.getOrderEntries(myIndex.getInfoForFile(myTestSrc1)); assertInstanceOf(entries[0], LibraryOrderEntry.class); assertInstanceOf(entries[1], ModuleSourceOrderEntry.class); } @@ -494,7 +494,7 @@ public class DirectoryIndexTest extends IdeaTestCase { public void testModuleSourceAsLibraryClasses() throws Exception { ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Arrays.asList(mySrcDir1.getUrl()), Collections.emptyList()); checkInfo(mySrcDir1, myModule, true, false, "", JavaSourceRootType.SOURCE, myModule); - assertInstanceOf(assertOneElement(assertInProject(mySrcDir1).getOrderEntries()), ModuleSourceOrderEntry.class); + assertInstanceOf(assertOneElement(myIndex.getOrderEntries(assertInProject(mySrcDir1))), ModuleSourceOrderEntry.class); } public void testModulesWithSameSourceContentRoot() { @@ -657,7 +657,7 @@ public class DirectoryIndexTest extends IdeaTestCase { checkInfo(myLibSrcDir, myModule, true, true, "", null, myModule, myModule3); checkInfo(myResDir, myModule, true, false, "", JavaResourceRootType.RESOURCE, myModule); - assertInstanceOf(assertOneElement(assertInProject(myResDir).getOrderEntries()), ModuleSourceOrderEntry.class); + assertInstanceOf(assertOneElement(myIndex.getOrderEntries(assertInProject(myResDir))), ModuleSourceOrderEntry.class); checkInfo(myExcludedLibSrcDir, null, true, false, "lib.src.exc", null, myModule3, myModule); checkInfo(myExcludedLibClsDir, null, true, false, "lib.cls.exc", null, myModule3); @@ -931,10 +931,10 @@ public class DirectoryIndexTest extends IdeaTestCase { assertEquals(packageName, fileIndex.getPackageNameByDirectory(file)); } - assertEquals(Arrays.toString(info.getOrderEntries()), modulesOfOrderEntries.length, info.getOrderEntries().length); + assertEquals(Arrays.toString(myIndex.getOrderEntries(info)), modulesOfOrderEntries.length, myIndex.getOrderEntries(info).length); for (Module aModule : modulesOfOrderEntries) { - OrderEntry found = info.findOrderEntryWithOwnerModule(aModule); - assertNotNull("not found: " + aModule + " in " + Arrays.toString(info.getOrderEntries()), found); + OrderEntry found = myIndex.findOrderEntryWithOwnerModule(info, aModule); + assertNotNull("not found: " + aModule + " in " + Arrays.toString(myIndex.getOrderEntries(info)), found); } } @@ -953,7 +953,7 @@ public class DirectoryIndexTest extends IdeaTestCase { private DirectoryInfo assertInProject(VirtualFile file) { DirectoryInfo info = myIndex.getInfoForFile(file); assertTrue(file.toString(), info.isInProject()); - info.assertConsistency(); + myIndex.assertConsistency(info); return info; } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java index b1385686bc3a..09e489b3d1df 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java @@ -25,15 +25,14 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ModuleRootAdapter; -import com.intellij.openapi.roots.ModuleRootEvent; -import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.*; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.events.VFileEvent; +import com.intellij.util.IncorrectOperationException; import com.intellij.util.Query; import com.intellij.util.containers.ConcurrentIntObjectMap; import com.intellij.util.containers.StripedLockIntObjectConcurrentHashMap; @@ -43,6 +42,8 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import org.jetbrains.jps.model.module.JpsModuleSourceRootType; +import java.util.Arrays; +import java.util.Collections; import java.util.List; public class DirectoryIndexImpl extends DirectoryIndex { @@ -68,7 +69,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { }); } - private void subscribeToFileChanges() { + protected void subscribeToFileChanges() { myConnection.subscribe(FileTypeManager.TOPIC, new FileTypeListener.Adapter() { @Override public void fileTypesChanged(@NotNull FileTypeEvent event) { @@ -98,7 +99,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { }); } - private void markContentRootsForRefresh() { + protected void markContentRootsForRefresh() { Module[] modules = ModuleManager.getInstance(myProject).getModules(); for (Module module : modules) { VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); @@ -110,7 +111,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { } } - private void dispatchPendingEvents() { + protected void dispatchPendingEvents() { myConnection.deliverImmediately(); } @@ -124,24 +125,27 @@ public class DirectoryIndexImpl extends DirectoryIndex { private RootIndex getRootIndex() { RootIndex rootIndex = myRootIndex; if (rootIndex == null) { - myRootIndex = rootIndex = new RootIndex(myProject, new RootIndex.InfoCache() { - // Upsource can't use int-mapping because different files may have the same id there - private final ConcurrentIntObjectMap myInfoCache = new StripedLockIntObjectConcurrentHashMap(); - @Override - public void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info) { - myInfoCache.put(((NewVirtualFile)dir).getId(), info); - } - - @Override - public DirectoryInfo getCachedInfo(@NotNull VirtualFile dir) { - return myInfoCache.get(((NewVirtualFile)dir).getId()); - } - }); + myRootIndex = rootIndex = new RootIndex(myProject, createRootInfoCache()); } return rootIndex; } - @Override + protected RootIndex.InfoCache createRootInfoCache() { + return new RootIndex.InfoCache() { + // Upsource can't use int-mapping because different files may have the same id there + private final ConcurrentIntObjectMap myInfoCache = new StripedLockIntObjectConcurrentHashMap(); + @Override + public void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info) { + myInfoCache.put(((NewVirtualFile)dir).getId(), info); + } + + @Override + public DirectoryInfo getCachedInfo(@NotNull VirtualFile dir) { + return myInfoCache.get(((NewVirtualFile)dir).getId()); + } + }; + } + @TestOnly public void checkConsistency() { getRootIndex().checkConsistency(); @@ -181,6 +185,21 @@ public class DirectoryIndexImpl extends DirectoryIndex { return getRootIndex().getPackageName(dir); } + @NotNull + @Override + public OrderEntry[] getOrderEntries(@NotNull DirectoryInfo info) { + checkAvailability(); + return getRootIndex().getOrderEntries(info); + } + + @TestOnly + void assertConsistency(DirectoryInfo info) { + OrderEntry[] entries = getOrderEntries(info); + for (int i = 1; i < entries.length; i++) { + assert RootIndex.BY_OWNER_MODULE.compare(entries[i - 1], entries[i]) <= 0; + } + } + private void checkAvailability() { if (myDisposed) { ProgressManager.checkCanceled(); @@ -188,4 +207,95 @@ public class DirectoryIndexImpl extends DirectoryIndex { } } + @NotNull + private static OrderEntry createFakeOrderEntry(@NotNull final Module ownerModule) { + return new OrderEntry() { + @NotNull + @Override + public VirtualFile[] getFiles(OrderRootType type) { + throw new IncorrectOperationException(); + } + + @NotNull + @Override + public String[] getUrls(OrderRootType rootType) { + throw new IncorrectOperationException(); + } + + @NotNull + @Override + public String getPresentableName() { + throw new IncorrectOperationException(); + } + + @Override + public boolean isValid() { + throw new IncorrectOperationException(); + } + + @NotNull + @Override + public Module getOwnerModule() { + return ownerModule; + } + + @Override + public R accept(RootPolicy policy, @Nullable R initialValue) { + throw new IncorrectOperationException(); + } + + @Override + public int compareTo(@NotNull OrderEntry o) { + throw new IncorrectOperationException(); + } + + @Override + public boolean isSynthetic() { + throw new IncorrectOperationException(); + } + }; + } + + @Override + @Nullable + OrderEntry findOrderEntryWithOwnerModule(@NotNull DirectoryInfo info, @NotNull Module ownerModule) { + OrderEntry[] entries = getOrderEntries(info); + if (entries.length < 10) { + for (OrderEntry entry : entries) { + if (entry.getOwnerModule() == ownerModule) return entry; + } + return null; + } + int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), RootIndex.BY_OWNER_MODULE); + return index < 0 ? null : entries[index]; + } + + @Override + @NotNull + List findAllOrderEntriesWithOwnerModule(@NotNull DirectoryInfo info, @NotNull Module ownerModule) { + OrderEntry[] entries = getOrderEntries(info); + if (entries.length == 0) return Collections.emptyList(); + + if (entries.length == 1) { + OrderEntry entry = entries[0]; + return entry.getOwnerModule() == ownerModule ? Arrays.asList(entries) : Collections.emptyList(); + } + int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), RootIndex.BY_OWNER_MODULE); + if (index < 0) { + return Collections.emptyList(); + } + int firstIndex = index; + while (firstIndex - 1 >= 0 && entries[firstIndex - 1].getOwnerModule() == ownerModule) { + firstIndex--; + } + int lastIndex = index + 1; + while (lastIndex < entries.length && entries[lastIndex].getOwnerModule() == ownerModule) { + lastIndex++; + } + + OrderEntry[] subArray = new OrderEntry[lastIndex - firstIndex]; + System.arraycopy(entries, firstIndex, subArray, 0, lastIndex - firstIndex); + + return Arrays.asList(subArray); + } } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java index 9fdd8e09a57d..e87d3c749b10 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java @@ -17,23 +17,23 @@ package com.intellij.openapi.roots.impl; import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Query; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.TestOnly; import org.jetbrains.jps.model.module.JpsModuleSourceRootType; +import java.util.List; + public abstract class DirectoryIndex { public static DirectoryIndex getInstance(Project project) { assert !project.isDefault() : "Must not call DirectoryIndex for default project"; return ServiceManager.getService(project, DirectoryIndex.class); } - @TestOnly - public abstract void checkConsistency(); - /** * The same as {@link #getInfoForFile} but works only for directories or file roots and returns {@code null} for directories * which aren't included in project content or libraries @@ -62,4 +62,13 @@ public abstract class DirectoryIndex { public boolean isInitialized() { return true; } + + @NotNull + public abstract OrderEntry[] getOrderEntries(@NotNull DirectoryInfo info); + + @Nullable + abstract OrderEntry findOrderEntryWithOwnerModule(@NotNull DirectoryInfo info, @NotNull Module ownerModule); + + @NotNull + abstract List findAllOrderEntriesWithOwnerModule(@NotNull DirectoryInfo info, @NotNull Module ownerModule); } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java index 87448a584a23..cd5fbd7d5867 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java @@ -17,13 +17,8 @@ package com.intellij.openapi.roots.impl; import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.TestOnly; - -import java.util.List; public abstract class DirectoryInfo { /** @@ -61,16 +56,4 @@ public abstract class DirectoryInfo { @Nullable public abstract Module getModule(); - - @NotNull - public abstract OrderEntry[] getOrderEntries(); - - @Nullable - abstract OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule); - - @NotNull - abstract List findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule); - - @TestOnly - abstract void assertConsistency(); } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoImpl.java index 0be339bf3c5f..1c3ca4f2ff8d 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoImpl.java @@ -16,34 +16,16 @@ package com.intellij.openapi.roots.impl; import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.OrderEntry; -import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.roots.RootPolicy; -import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.TestOnly; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; /** * @author nik */ -public abstract class DirectoryInfoImpl extends DirectoryInfo { - public static final Comparator BY_OWNER_MODULE = new Comparator() { - @Override - public int compare(OrderEntry o1, OrderEntry o2) { - String name1 = o1.getOwnerModule().getName(); - String name2 = o2.getOwnerModule().getName(); - return name1.compareTo(name2); - } - }; +public class DirectoryInfoImpl extends DirectoryInfo { public static final int MAX_ROOT_TYPE_ID = Byte.MAX_VALUE; + private final VirtualFile myRoot;//original project root for which this information is calculated private final Module module; // module to which content it belongs or null private final VirtualFile libraryClassRoot; // class root in library private final VirtualFile contentRoot; @@ -53,8 +35,9 @@ public abstract class DirectoryInfoImpl extends DirectoryInfo { private final boolean myExcluded; private final byte mySourceRootTypeId; - DirectoryInfoImpl(Module module, VirtualFile contentRoot, VirtualFile sourceRoot, VirtualFile libraryClassRoot, + DirectoryInfoImpl(@NotNull VirtualFile root, Module module, VirtualFile contentRoot, VirtualFile sourceRoot, VirtualFile libraryClassRoot, boolean inModuleSource, boolean inLibrarySource, boolean isExcluded, int sourceRootTypeId) { + myRoot = root; this.module = module; this.libraryClassRoot = libraryClassRoot; this.contentRoot = contentRoot; @@ -74,30 +57,12 @@ public abstract class DirectoryInfoImpl extends DirectoryInfo { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - DirectoryInfoImpl info = (DirectoryInfoImpl)o; - - return mySourceRootTypeId == info.mySourceRootTypeId && - myInModuleSource == info.myInModuleSource && - myInLibrarySource == info.myInLibrarySource && - myExcluded == info.myExcluded && - Comparing.equal(contentRoot, info.contentRoot) && - Comparing.equal(libraryClassRoot, info.libraryClassRoot) && - Comparing.equal(module, info.module) && - Arrays.equals(getOrderEntries(), info.getOrderEntries()) && - Comparing.equal(sourceRoot, info.sourceRoot); + return myRoot.equals(((DirectoryInfoImpl)o).myRoot); } @Override public int hashCode() { - int result = module != null ? module.hashCode() : 0; - result = 31 * result + (libraryClassRoot != null ? libraryClassRoot.hashCode() : 0); - result = 31 * result + (contentRoot != null ? contentRoot.hashCode() : 0); - result = 31 * result + (sourceRoot != null ? sourceRoot.hashCode() : 0); - result = 31 * result + (myInModuleSource ? 1 : 0); - result = 31 * result + (myInLibrarySource ? 1 : 0); - result = 31 * result + (myExcluded ? 1 : 0); - result = 31 * result + (int)mySourceRootTypeId; - return result; + return myRoot.hashCode(); } @SuppressWarnings({"HardCodedStringLiteral"}) @@ -111,98 +76,9 @@ public abstract class DirectoryInfoImpl extends DirectoryInfo { ", libraryClassRoot=" + getLibraryClassRoot() + ", contentRoot=" + getContentRoot() + ", sourceRoot=" + getSourceRoot() + - ", orderEntries=" + Arrays.toString(getOrderEntries()) + "}"; } - @NotNull - private static OrderEntry createFakeOrderEntry(@NotNull final Module ownerModule) { - return new OrderEntry() { - @NotNull - @Override - public VirtualFile[] getFiles(OrderRootType type) { - throw new IncorrectOperationException(); - } - - @NotNull - @Override - public String[] getUrls(OrderRootType rootType) { - throw new IncorrectOperationException(); - } - - @NotNull - @Override - public String getPresentableName() { - throw new IncorrectOperationException(); - } - - @Override - public boolean isValid() { - throw new IncorrectOperationException(); - } - - @NotNull - @Override - public Module getOwnerModule() { - return ownerModule; - } - - @Override - public R accept(RootPolicy policy, @Nullable R initialValue) { - throw new IncorrectOperationException(); - } - - @Override - public int compareTo(@NotNull OrderEntry o) { - throw new IncorrectOperationException(); - } - - @Override - public boolean isSynthetic() { - throw new IncorrectOperationException(); - } - }; - } - - @Nullable - OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule) { - OrderEntry[] entries = getOrderEntries(); - if (entries.length < 10) { - for (OrderEntry entry : entries) { - if (entry.getOwnerModule() == ownerModule) return entry; - } - return null; - } - int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), BY_OWNER_MODULE); - return index < 0 ? null : entries[index]; - } - - @NotNull - List findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule) { - OrderEntry[] entries = getOrderEntries(); - if (entries.length == 1) { - OrderEntry entry = entries[0]; - return entry.getOwnerModule() == ownerModule ? Arrays.asList(entries) : Collections.emptyList(); - } - int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), BY_OWNER_MODULE); - if (index < 0) { - return Collections.emptyList(); - } - int firstIndex = index; - while (firstIndex-1 >= 0 && entries[firstIndex-1].getOwnerModule() == ownerModule) { - firstIndex--; - } - int lastIndex = index+1; - while (lastIndex < entries.length && entries[lastIndex].getOwnerModule() == ownerModule) { - lastIndex++; - } - - OrderEntry[] subArray = new OrderEntry[lastIndex - firstIndex]; - System.arraycopy(entries, firstIndex, subArray, 0, lastIndex - firstIndex); - - return Arrays.asList(subArray); - } - public boolean isInProject() { return !isExcluded(); } @@ -241,15 +117,12 @@ public abstract class DirectoryInfoImpl extends DirectoryInfo { return module; } - @TestOnly - void assertConsistency() { - OrderEntry[] entries = getOrderEntries(); - for (int i=1; i getOrderEntriesForFile(@NotNull VirtualFile fileOrDir) { - return getInfoForFileOrDirectory(fileOrDir).findAllOrderEntriesWithOwnerModule(myModule); + return myDirectoryIndex.findAllOrderEntriesWithOwnerModule(getInfoForFileOrDirectory(fileOrDir), myModule); } @Override public OrderEntry getOrderEntryForFile(@NotNull VirtualFile fileOrDir) { - return getInfoForFileOrDirectory(fileOrDir).findOrderEntryWithOwnerModule(myModule); + return myDirectoryIndex.findOrderEntryWithOwnerModule(getInfoForFileOrDirectory(fileOrDir), myModule); } @Override diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/NonProjectDirectoryInfo.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/NonProjectDirectoryInfo.java index 7937f08fc7b4..ce09ec2fb819 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/NonProjectDirectoryInfo.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/NonProjectDirectoryInfo.java @@ -16,14 +16,9 @@ package com.intellij.openapi.roots.impl; import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collections; -import java.util.List; - /** * @author nik */ @@ -53,22 +48,6 @@ class NonProjectDirectoryInfo extends DirectoryInfo { return false; } - @NotNull - @Override - public OrderEntry[] getOrderEntries() { - return OrderEntry.EMPTY_ARRAY; - } - - @Nullable - OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule) { - return null; - } - - @NotNull - List findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule) { - return Collections.emptyList(); - } - @Override public String toString() { return "DirectoryInfo: " + myDebugName; @@ -118,9 +97,6 @@ class NonProjectDirectoryInfo extends DirectoryInfo { return null; } - void assertConsistency() { - } - public int getSourceRootTypeId() { return 0; } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java index acb6598f55c8..1609c58eb5c6 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java @@ -95,7 +95,7 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn @Override @NotNull public List getOrderEntriesForFile(@NotNull VirtualFile file) { - return Arrays.asList(getInfoForFileOrDirectory(file).getOrderEntries()); + return Arrays.asList(myDirectoryIndex.getOrderEntries(getInfoForFileOrDirectory(file))); } @Override diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java index 1c72b61077df..165a77b411af 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java @@ -41,7 +41,15 @@ import org.jetbrains.jps.model.module.JpsModuleSourceRootType; import java.util.*; -public class RootIndex extends DirectoryIndex { +public class RootIndex { + public static final Comparator BY_OWNER_MODULE = new Comparator() { + @Override + public int compare(OrderEntry o1, OrderEntry o2) { + String name1 = o1.getOwnerModule().getName(); + String name2 = o2.getOwnerModule().getName(); + return name1.compareTo(name2); + } + }; private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.RootIndex"); private final Set myProjectExcludedRoots = ContainerUtil.newHashSet(); @@ -145,7 +153,6 @@ public class RootIndex extends DirectoryIndex { } } } - } } } @@ -171,7 +178,8 @@ public class RootIndex extends DirectoryIndex { if (orderEntry instanceof ModuleOrderEntry) { final Module depModule = ((ModuleOrderEntry)orderEntry).getModule(); if (depModule != null) { - VirtualFile[] importedClassRoots = OrderEnumerator.orderEntries(depModule).exportedOnly().recursively().classes().usingCache().getRoots(); + VirtualFile[] importedClassRoots = + OrderEnumerator.orderEntries(depModule).exportedOnly().recursively().classes().usingCache().getRoots(); for (VirtualFile importedClassRoot : importedClassRoots) { depEntries.putValue(importedClassRoot, orderEntry); } @@ -197,7 +205,9 @@ public class RootIndex extends DirectoryIndex { Set allRoots = rootInfo.getAllRoots(); for (VirtualFile file : allRoots) { List hierarchy = getHierarchy(file, allRoots, rootInfo); - result.put(file, hierarchy == null ? OrderEntry.EMPTY_ARRAY : calcOrderEntries(rootInfo, depEntries, libClassRootEntries, libSourceRootEntries, hierarchy)); + result.put(file, hierarchy == null + ? OrderEntry.EMPTY_ARRAY + : calcOrderEntries(rootInfo, depEntries, libClassRootEntries, libSourceRootEntries, hierarchy)); } myOrderEntries = result; return result; @@ -211,7 +221,8 @@ public class RootIndex extends DirectoryIndex { @Nullable VirtualFile libraryClassRoot = info.findLibraryRootInfo(hierarchy, false); @Nullable VirtualFile librarySourceRoot = info.findLibraryRootInfo(hierarchy, true); Set orderEntries = ContainerUtil.newLinkedHashSet(); - orderEntries.addAll(info.getLibraryOrderEntries(hierarchy, libraryClassRoot, librarySourceRoot, libClassRootEntries, libSourceRootEntries)); + orderEntries + .addAll(info.getLibraryOrderEntries(hierarchy, libraryClassRoot, librarySourceRoot, libClassRootEntries, libSourceRootEntries)); for (VirtualFile root : hierarchy) { orderEntries.addAll(depEntries.get(root)); } @@ -224,12 +235,11 @@ public class RootIndex extends DirectoryIndex { } OrderEntry[] array = orderEntries.toArray(new OrderEntry[orderEntries.size()]); - Arrays.sort(array, DirectoryInfoImpl.BY_OWNER_MODULE); + Arrays.sort(array, BY_OWNER_MODULE); return array; } - @Override public void checkConsistency() { for (VirtualFile file : myProjectExcludedRoots) { assert file.exists() : file.getPath() + " does not exist"; @@ -247,21 +257,14 @@ public class RootIndex extends DirectoryIndex { int id = myRootTypes.size(); if (id > DirectoryInfoImpl.MAX_ROOT_TYPE_ID) { - LOG.error("Too many different types of module source roots (" + id + ") registered: " + myRootTypes); + LOG.error("Too many different types of module source roots (" + id + ") registered: " + myRootTypes); } myRootTypes.add(rootType); myRootTypeId.put(rootType, id); return id; } - @Override - public DirectoryInfo getInfoForDirectory(@NotNull VirtualFile dir) { - DirectoryInfo info = getInfoForFile(dir); - return info.isInProject() ? info : null; - } - @NotNull - @Override public DirectoryInfo getInfoForFile(@NotNull VirtualFile file) { if (!file.isValid()) { return NonProjectDirectoryInfo.INVALID; @@ -314,13 +317,12 @@ public class RootIndex extends DirectoryIndex { return info; } - @Override @NotNull public Query getDirectoriesByPackageName(@NotNull final String packageName, final boolean includeLibrarySources) { List result = myDirectoriesByPackageNameCache.get(packageName); if (result == null) { result = ContainerUtil.newSmartList(); - + if (StringUtil.isNotEmpty(packageName) && !StringUtil.startsWithChar(packageName, '.')) { int i = packageName.lastIndexOf('.'); while (true) { @@ -361,7 +363,6 @@ public class RootIndex extends DirectoryIndex { return new CollectionQuery(result); } - @Override @Nullable public String getPackageName(@NotNull final VirtualFile dir) { if (dir.isDirectory()) { @@ -390,7 +391,6 @@ public class RootIndex extends DirectoryIndex { return parentPackageName.isEmpty() ? subdirName : parentPackageName + "." + subdirName; } - @Override @Nullable public JpsModuleSourceRootType getSourceRootType(@NotNull DirectoryInfo directoryInfo) { return myRootTypes.get(directoryInfo.getSourceRootTypeId()); @@ -497,8 +497,9 @@ public class RootIndex extends DirectoryIndex { if (source && libraryOrSdkSources.contains(root) && (!sourceOfLibraries.containsKey(root) || !librariesToIgnore.containsAll(sourceOfLibraries.get(root)))) { return root; - } else if (!source && libraryOrSdkClasses.contains(root) && - (!classOfLibraries.containsKey(root) || !librariesToIgnore.containsAll(classOfLibraries.get(root)))) { + } + else if (!source && libraryOrSdkClasses.contains(root) && + (!classOfLibraries.containsKey(root) || !librariesToIgnore.containsAll(classOfLibraries.get(root)))) { return root; } } @@ -579,8 +580,11 @@ public class RootIndex extends DirectoryIndex { } } + @NotNull - private Pair calcDirectoryInfo(@NotNull final VirtualFile root, @NotNull final List hierarchy, @NotNull RootInfo info) { + private static Pair calcDirectoryInfo(@NotNull final VirtualFile root, + @NotNull final List hierarchy, + @NotNull RootInfo info) { VirtualFile moduleContentRoot = info.findModuleRootInfo(hierarchy); VirtualFile libraryClassRoot = info.findLibraryRootInfo(hierarchy, false); VirtualFile librarySourceRoot = info.findLibraryRootInfo(hierarchy, true); @@ -600,23 +604,26 @@ public class RootIndex extends DirectoryIndex { int typeId = moduleSourceRoot != null ? info.rootTypeId.get(moduleSourceRoot) : 0; Module module = parentModuleForExcluded != null ? parentModuleForExcluded : info.contentRootOf.get(moduleContentRoot); - DirectoryInfo directoryInfo = new DirectoryInfoImpl(module, moduleContentRoot, sourceRoot, libraryClassRoot, inModuleSources, inLibrarySource, - parentModuleForExcluded != null, typeId) { - @NotNull - @Override - public OrderEntry[] getOrderEntries() { - OrderEntry[] entries = RootIndex.this.getOrderEntries().get(root); - return entries == null ? OrderEntry.EMPTY_ARRAY : entries; - } - }; + DirectoryInfo directoryInfo = + new DirectoryInfoImpl(root, module, moduleContentRoot, sourceRoot, libraryClassRoot, inModuleSources, inLibrarySource, + parentModuleForExcluded != null, typeId); String packagePrefix = info.calcPackagePrefix(root, hierarchy, moduleContentRoot, libraryClassRoot, librarySourceRoot); return Pair.create(directoryInfo, packagePrefix); } - - public interface InfoCache { - @Nullable DirectoryInfo getCachedInfo(@NotNull VirtualFile dir); - void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info); + + @NotNull + public OrderEntry[] getOrderEntries(@NotNull DirectoryInfo info) { + if (!(info instanceof DirectoryInfoImpl)) return OrderEntry.EMPTY_ARRAY; + OrderEntry[] entries = this.getOrderEntries().get(((DirectoryInfoImpl)info).getRoot()); + return entries == null ? OrderEntry.EMPTY_ARRAY : entries; } -} \ No newline at end of file + + public interface InfoCache { + @Nullable + DirectoryInfo getCachedInfo(@NotNull VirtualFile dir); + + void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info); + } +}