diff --git a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexForUnloadedModuleTest.java b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexForUnloadedModuleTest.java index c28cce2aea28..3b245ae96a0a 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexForUnloadedModuleTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexForUnloadedModuleTest.java @@ -39,7 +39,14 @@ public class DirectoryIndexForUnloadedModuleTest extends DirectoryIndexTestCase ModuleManager.getInstance(myProject).setUnloadedModules(Arrays.asList("unloaded")); - assertExcluded(file, null); - assertExcluded(contentRoot, null); + assertFromUnloadedModule(file, "unloaded"); + assertFromUnloadedModule(contentRoot, "unloaded"); + } + + private void assertFromUnloadedModule(VirtualFile file, String moduleName) { + DirectoryInfo info = myIndex.getInfoForFile(file); + assertTrue(info.toString(), info.isExcluded(file)); + assertNull(info.getModule()); + assertEquals(moduleName, info.getUnloadedModuleName()); } } diff --git a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTestCase.java b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTestCase.java index 27128fb133c9..99bb734327db 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTestCase.java +++ b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTestCase.java @@ -55,11 +55,13 @@ public abstract class DirectoryIndexTestCase extends IdeaTestCase { DirectoryInfo info = myIndex.getInfoForFile(file); assertFalse(info.toString(), info.isInProject(file)); assertFalse(info.toString(), info.isExcluded(file)); + assertNull(info.toString(), info.getUnloadedModuleName()); } protected void assertExcluded(VirtualFile file, Module module) { DirectoryInfo info = myIndex.getInfoForFile(file); assertTrue(info.toString(), info.isExcluded(file)); + assertNull(info.toString(), info.getUnloadedModuleName()); assertEquals(module, info.getModule()); } @@ -78,6 +80,7 @@ public abstract class DirectoryIndexTestCase extends IdeaTestCase { protected DirectoryInfo assertInProject(VirtualFile file) { DirectoryInfo info = myIndex.getInfoForFile(file); assertTrue(file.toString(), info.isInProject(file)); + assertNull(info.toString(), info.getUnloadedModuleName()); myIndex.assertConsistency(info); return info; } 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 ef32ee53416c..11ed94d90067 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 @@ -86,4 +86,12 @@ public abstract class DirectoryInfo { @Nullable public abstract Module getModule(); + + /** + * Return name of an unloaded module to which content this file or directory belongs + * or {@code null} if it doesn't belong to an unloaded module. + * @see com.intellij.openapi.module.UnloadedModuleDescription + */ + @Nullable + public abstract String getUnloadedModuleName(); } 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 da320f5ff395..967eb591a2c9 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 @@ -34,9 +34,10 @@ public class DirectoryInfoImpl extends DirectoryInfo { protected final boolean myInLibrarySource; protected final boolean myExcluded; private final byte mySourceRootTypeId; + private final String myUnloadedModuleName; DirectoryInfoImpl(@NotNull VirtualFile root, Module module, VirtualFile contentRoot, VirtualFile sourceRoot, VirtualFile libraryClassRoot, - boolean inModuleSource, boolean inLibrarySource, boolean isExcluded, int sourceRootTypeId) { + boolean inModuleSource, boolean inLibrarySource, boolean isExcluded, int sourceRootTypeId, @Nullable String unloadedModuleName) { myRoot = root; this.module = module; this.libraryClassRoot = libraryClassRoot; @@ -45,6 +46,7 @@ public class DirectoryInfoImpl extends DirectoryInfo { myInModuleSource = inModuleSource; myInLibrarySource = inLibrarySource; myExcluded = isExcluded; + myUnloadedModuleName = unloadedModuleName; if (sourceRootTypeId > MAX_ROOT_TYPE_ID) { throw new IllegalArgumentException( "Module source root type id " + sourceRootTypeId + " exceeds the maximum allowable value (" + MAX_ROOT_TYPE_ID + ")"); @@ -135,6 +137,11 @@ public class DirectoryInfoImpl extends DirectoryInfo { return mySourceRootTypeId; } + @Override + public String getUnloadedModuleName() { + return myUnloadedModuleName; + } + @NotNull public VirtualFile getRoot() { return myRoot; diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoWithExcludePatterns.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoWithExcludePatterns.java index 93652236b50c..0332838a3df1 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoWithExcludePatterns.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoWithExcludePatterns.java @@ -34,8 +34,9 @@ public class DirectoryInfoWithExcludePatterns extends DirectoryInfoImpl { VirtualFile libraryClassRoot, boolean inModuleSource, boolean inLibrarySource, boolean isExcluded, int sourceRootTypeId, @Nullable FileTypeAssocTable contentExcludePatterns, - @Nullable FileTypeAssocTable libraryExcludePatterns) { - super(root, module, contentRoot, sourceRoot, libraryClassRoot, inModuleSource, inLibrarySource, isExcluded, sourceRootTypeId); + @Nullable FileTypeAssocTable libraryExcludePatterns, + @Nullable String unloadedModuleName) { + super(root, module, contentRoot, sourceRoot, libraryClassRoot, inModuleSource, inLibrarySource, isExcluded, sourceRootTypeId, unloadedModuleName); myContentExcludePatterns = contentExcludePatterns; myLibraryExcludePatterns = libraryExcludePatterns; LOG.assertTrue(myContentExcludePatterns != null || myLibraryExcludePatterns != null, 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 c910d07c0704..cbf608fc5f2e 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 @@ -113,6 +113,11 @@ class NonProjectDirectoryInfo extends DirectoryInfo { return null; } + @Override + public String getUnloadedModuleName() { + return null; + } + public int getSourceRootTypeId() { return 0; } 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 43ade59c593f..5da3e9f7a1f6 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 @@ -207,7 +207,10 @@ public class RootIndex { } for (UnloadedModuleDescription description : moduleManager.getUnloadedModuleDescriptions()) { for (VirtualFilePointer pointer : description.getContentRoots()) { - ContainerUtil.addIfNotNull(info.excludedFromProject, pointer.getFile()); + VirtualFile contentRoot = pointer.getFile(); + if (contentRoot != null) { + info.contentRootOfUnloaded.put(contentRoot, description.getName()); + } } } return info; @@ -563,6 +566,7 @@ public class RootIndex { @NotNull final Set libraryOrSdkSources = ContainerUtil.newHashSet(); @NotNull final Set libraryOrSdkClasses = ContainerUtil.newHashSet(); @NotNull final Map contentRootOf = ContainerUtil.newHashMap(); + @NotNull final Map contentRootOfUnloaded = ContainerUtil.newHashMap(); @NotNull final MultiMap sourceRootOf = MultiMap.createSet(); @NotNull final TObjectIntHashMap rootTypeId = new TObjectIntHashMap<>(); @NotNull final MultiMap excludedFromLibraries = MultiMap.createSmart(); @@ -578,6 +582,7 @@ public class RootIndex { LinkedHashSet result = ContainerUtil.newLinkedHashSet(); result.addAll(classAndSourceRoots); result.addAll(contentRootOf.keySet()); + result.addAll(contentRootOfUnloaded.keySet()); result.addAll(excludedFromLibraries.keySet()); result.addAll(excludedFromModule.keySet()); result.addAll(excludedFromProject); @@ -604,7 +609,7 @@ public class RootIndex { if (module != null && (excludedFrom != module || underExcludedSourceRoot && sourceRootOwners.contains(module))) { return root; } - if (excludedFrom != null || excludedFromProject.contains(root)) { + if (excludedFrom != null || excludedFromProject.contains(root) || contentRootOfUnloaded.containsKey(root)) { if (sourceRootOwners != null) { underExcludedSourceRoot = true; } @@ -643,7 +648,7 @@ public class RootIndex { @Nullable private VirtualFile findNearestContentRootForExcluded(@NotNull List hierarchy) { for (VirtualFile root : hierarchy) { - if (contentRootOf.containsKey(root)) { + if (contentRootOf.containsKey(root) || contentRootOfUnloaded.containsKey(root)) { return root; } } @@ -809,15 +814,16 @@ public class RootIndex { int typeId = moduleSourceRoot != null ? info.rootTypeId.get(moduleSourceRoot) : 0; Module module = info.contentRootOf.get(nearestContentRoot); + String unloadedModuleName = info.contentRootOfUnloaded.get(nearestContentRoot); FileTypeAssocTable contentExcludePatterns = moduleContentRoot != null ? info.excludeFromContentRootTables.get(moduleContentRoot) : null; FileTypeAssocTable libraryExcludePatterns = getLibraryExclusionPatterns(librarySourceRootInfo); DirectoryInfo directoryInfo = contentExcludePatterns != null || libraryExcludePatterns != null ? new DirectoryInfoWithExcludePatterns(root, module, nearestContentRoot, sourceRoot, libraryClassRoot, inModuleSources, inLibrarySource, !inProject, typeId, - contentExcludePatterns, libraryExcludePatterns) + contentExcludePatterns, libraryExcludePatterns, unloadedModuleName) : new DirectoryInfoImpl(root, module, nearestContentRoot, sourceRoot, libraryClassRoot, inModuleSources, - inLibrarySource, !inProject, typeId); + inLibrarySource, !inProject, typeId, unloadedModuleName); String packagePrefix = info.calcPackagePrefix(root, hierarchy, moduleContentRoot, libraryClassRoot, librarySourceRoot);