diff --git a/java/java-tests/testSrc/com/intellij/roots/DependencyScopeTest.java b/java/java-tests/testSrc/com/intellij/roots/DependencyScopeTest.java index 64602e2c72c3..cbdacc59c142 100644 --- a/java/java-tests/testSrc/com/intellij/roots/DependencyScopeTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/DependencyScopeTest.java @@ -78,7 +78,7 @@ public class DependencyScopeTest extends ModuleTestCase { public void testTestOnlyLibraryDependency() throws IOException { Module m = createModule("a.iml", StdModuleTypes.JAVA); addLibrary(m, DependencyScope.TEST); - VirtualFile libraryClass = myFixture.createFile("lib/Test.java", "public class Test { }"); + VirtualFile libraryClass = myFixture.createFile("lib/Test.class"); assertTrue(m.getModuleWithDependenciesAndLibrariesScope(true).contains(libraryClass)); assertFalse(m.getModuleWithDependenciesAndLibrariesScope(false).contains(libraryClass)); @@ -112,9 +112,12 @@ public class DependencyScopeTest extends ModuleTestCase { VirtualFile[] production = getProductionCompileClasspath(m); assertEmpty(production); - VirtualFile libraryClass = myFixture.createFile("lib/Test.java", "public class Test { }"); - assertTrue(m.getModuleWithDependenciesAndLibrariesScope(true).contains(libraryClass)); + VirtualFile libraryClass = myFixture.createFile("lib/Test.class"); + assertFalse(m.getModuleWithDependenciesAndLibrariesScope(true).contains(libraryClass)); assertFalse(m.getModuleWithDependenciesAndLibrariesScope(false).contains(libraryClass)); + + assertTrue(m.getModuleRuntimeScope(true).contains(libraryClass)); + assertTrue(m.getModuleRuntimeScope(false).contains(libraryClass)); } public void testProvidedModuleDependency() throws IOException { @@ -136,9 +139,12 @@ public class DependencyScopeTest extends ModuleTestCase { final VirtualFile[] compilationClasspath = getCompilationClasspath(m); assertOrderedEquals(compilationClasspath, libraryRoot); - VirtualFile libraryClass = myFixture.createFile("lib/Test.java", "public class Test { }"); + VirtualFile libraryClass = myFixture.createFile("lib/Test.class"); assertTrue(m.getModuleWithDependenciesAndLibrariesScope(true).contains(libraryClass)); assertTrue(m.getModuleWithDependenciesAndLibrariesScope(false).contains(libraryClass)); + + assertTrue(m.getModuleRuntimeScope(true).contains(libraryClass)); + assertFalse(m.getModuleRuntimeScope(false).contains(libraryClass)); } private static VirtualFile[] getRuntimeClasspath(Module m) { diff --git a/platform/lang-api/src/com/intellij/openapi/roots/OrderEnumerationHandler.java b/platform/lang-api/src/com/intellij/openapi/roots/OrderEnumerationHandler.java index d2641b960849..5bc61b53c972 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/OrderEnumerationHandler.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/OrderEnumerationHandler.java @@ -47,7 +47,9 @@ public abstract class OrderEnumerationHandler { return true; } - public boolean addCustomOutput(@NotNull ModuleOrderEntry orderEntry, + public boolean addCustomOutput(@NotNull Module forModule, + @NotNull ModuleRootModel orderEntryRootModel, + OrderRootType type, boolean productionOnly, boolean runtimeOnly, boolean compileOnly, diff --git a/platform/lang-api/src/com/intellij/openapi/roots/OrderEnumerator.java b/platform/lang-api/src/com/intellij/openapi/roots/OrderEnumerator.java index ddfa7fa98a14..03c4405eb725 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/OrderEnumerator.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/OrderEnumerator.java @@ -21,6 +21,7 @@ import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.NotNullFunction; import com.intellij.util.PathsList; import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; @@ -129,6 +130,12 @@ public abstract class OrderEnumerator { */ public abstract OrderRootsEnumerator roots(@NotNull OrderRootType rootType); + /** + * @param rootTypeProvider custom root type provider + * @return {@link OrderRootsEnumerator} instance for processing roots of the provided type + */ + public abstract OrderRootsEnumerator roots(@NotNull NotNullFunction rootTypeProvider); + /** * @return classes roots for all entries processed by this enumerator */ diff --git a/platform/lang-api/src/com/intellij/psi/search/SearchScope.java b/platform/lang-api/src/com/intellij/psi/search/SearchScope.java index 0bbcfc359cdd..4bb15984896c 100644 --- a/platform/lang-api/src/com/intellij/psi/search/SearchScope.java +++ b/platform/lang-api/src/com/intellij/psi/search/SearchScope.java @@ -34,7 +34,7 @@ public abstract class SearchScope { } public String getDisplayName() { - return PsiBundle.message("psi.search.scope.unknown"); + return PsiBundle.message("search.scope.unknown"); } @NotNull public abstract SearchScope intersectWith(@NotNull SearchScope scope2); diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java index b272e9bf6a52..8cee7855e168 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java @@ -31,7 +31,6 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleComponent; import com.intellij.openapi.module.ModuleType; -import com.intellij.openapi.module.impl.scopes.ModuleRuntimeClasspathScope; import com.intellij.openapi.module.impl.scopes.ModuleWithDependenciesScope; import com.intellij.openapi.module.impl.scopes.ModuleWithDependentsScope; import com.intellij.openapi.project.Project; @@ -66,14 +65,14 @@ public class ModuleImpl extends ComponentManagerImpl implements Module { @NonNls private static final String OPTION_WORKSPACE = "workspace"; @NonNls public static final String ELEMENT_TYPE = "type"; - private ModuleWithDependenciesScope myModuleWithLibrariesScope; - private ModuleWithDependenciesScope myModuleWithDependenciesScope; - private ModuleWithDependenciesScope myModuleWithDependenciesAndLibrariesScope; - private ModuleWithDependenciesScope myModuleWithDependenciesAndLibrariesNoTestsScope; - private ModuleWithDependentsScope myModuleWithDependentsScope; - private ModuleWithDependentsScope myModuleTestsWithDependentsScope; - private ModuleRuntimeClasspathScope myModuleTestsRuntimeClasspathScope; - private ModuleRuntimeClasspathScope myModuleRuntimeClasspathScope; + private GlobalSearchScope myModuleWithLibrariesScope; + private GlobalSearchScope myModuleWithDependenciesScope; + private GlobalSearchScope myModuleWithDependenciesAndLibrariesScope; + private GlobalSearchScope myModuleWithDependenciesAndLibrariesNoTestsScope; + private GlobalSearchScope myModuleWithDependentsScope; + private GlobalSearchScope myModuleTestsWithDependentsScope; + private GlobalSearchScope myModuleTestsRuntimeClasspathScope; + private GlobalSearchScope myModuleRuntimeClasspathScope; public static final Object MODULE_RENAMING_REQUESTOR = new Object(); private String myName; @@ -105,7 +104,7 @@ public class ModuleImpl extends ComponentManagerImpl implements Module { myName = moduleNameByFileName(PathUtil.getFileName(filePath)); MyVirtualFileListener myVirtualFileListener = new MyVirtualFileListener(); - VirtualFileManager.getInstance().addVirtualFileListener(myVirtualFileListener,this); + VirtualFileManager.getInstance().addVirtualFileListener(myVirtualFileListener, this); } public void loadModuleComponents() { @@ -116,14 +115,14 @@ public class ModuleImpl extends ComponentManagerImpl implements Module { } } - protected boolean isComponentSuitable(Map options) { + protected boolean isComponentSuitable(Map options) { if (!super.isComponentSuitable(options)) return false; if (options == null) return true; Set optionNames = options.keySet(); for (String optionName : optionNames) { if (Comparing.equal(OPTION_WORKSPACE, optionName)) continue; - if (!parseOptionValue(options.get(optionName)).contains( getOptionValue(optionName))) return false; + if (!parseOptionValue(options.get(optionName)).contains(getOptionValue(optionName))) return false; } return true; @@ -246,7 +245,7 @@ public class ModuleImpl extends ComponentManagerImpl implements Module { public GlobalSearchScope getModuleScope() { if (myModuleScope == null) { - myModuleScope = new ModuleWithDependenciesScope(this, false, false, true); + myModuleScope = new ModuleWithDependenciesScope(this, true, false, false, true); } return myModuleScope; @@ -254,14 +253,14 @@ public class ModuleImpl extends ComponentManagerImpl implements Module { public GlobalSearchScope getModuleWithLibrariesScope() { if (myModuleWithLibrariesScope == null) { - myModuleWithLibrariesScope = new ModuleWithDependenciesScope(this, true, false, true); + myModuleWithLibrariesScope = new ModuleWithDependenciesScope(this, true, true, false, true); } return myModuleWithLibrariesScope; } public GlobalSearchScope getModuleWithDependenciesScope() { if (myModuleWithDependenciesScope == null) { - myModuleWithDependenciesScope = new ModuleWithDependenciesScope(this, false, true, true); + myModuleWithDependenciesScope = new ModuleWithDependenciesScope(this, true, false, true, true); } return myModuleWithDependenciesScope; } @@ -269,13 +268,13 @@ public class ModuleImpl extends ComponentManagerImpl implements Module { public GlobalSearchScope getModuleWithDependenciesAndLibrariesScope(boolean includeTests) { if (includeTests) { if (myModuleWithDependenciesAndLibrariesScope == null) { - myModuleWithDependenciesAndLibrariesScope = new ModuleWithDependenciesScope(this, true, true, true); + myModuleWithDependenciesAndLibrariesScope = new ModuleWithDependenciesScope(this, true, true, true, true); } return myModuleWithDependenciesAndLibrariesScope; } else { if (myModuleWithDependenciesAndLibrariesNoTestsScope == null) { - myModuleWithDependenciesAndLibrariesNoTestsScope = new ModuleWithDependenciesScope(this, true, true, false); + myModuleWithDependenciesAndLibrariesNoTestsScope = new ModuleWithDependenciesScope(this, true, true, true, false); } return myModuleWithDependenciesAndLibrariesNoTestsScope; } @@ -298,13 +297,13 @@ public class ModuleImpl extends ComponentManagerImpl implements Module { public GlobalSearchScope getModuleRuntimeScope(boolean includeTests) { if (includeTests) { if (myModuleTestsRuntimeClasspathScope == null) { - myModuleTestsRuntimeClasspathScope = new ModuleRuntimeClasspathScope(this, true); + myModuleTestsRuntimeClasspathScope = new ModuleWithDependenciesScope(this, false, true, true, true); } return myModuleTestsRuntimeClasspathScope; } else { if (myModuleRuntimeClasspathScope == null) { - myModuleRuntimeClasspathScope = new ModuleRuntimeClasspathScope(this, false); + myModuleRuntimeClasspathScope = new ModuleWithDependenciesScope(this, false, true, true, false); } return myModuleRuntimeClasspathScope; } @@ -324,7 +323,7 @@ public class ModuleImpl extends ComponentManagerImpl implements Module { @SuppressWarnings({"HardCodedStringLiteral"}) public String toString() { if (myName == null) return "Module"; // was called before initialized - return "Module: '" + getName() + "' path: '" + getModuleFilePath()+"'"; + return "Module: '" + getName() + "' path: '" + getModuleFilePath() + "'"; } private static String moduleNameByFileName(@NotNull String fileName) { @@ -348,12 +347,9 @@ public class ModuleImpl extends ComponentManagerImpl implements Module { ModuleManagerImpl.getInstanceImpl(getProject()).fireModuleRenamedByVfsEvent(ModuleImpl.this); } } - } protected MutablePicoContainer createPicoContainer() { return Extensions.getArea(this).getPicoContainer(); } - - } diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleRuntimeClasspathScope.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleRuntimeClasspathScope.java deleted file mode 100644 index f675315619f3..000000000000 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleRuntimeClasspathScope.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2000-2009 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.module.impl.scopes; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.*; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiBundle; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NotNull; - -import java.util.LinkedHashSet; - -/** - * @author max - */ -public class ModuleRuntimeClasspathScope extends GlobalSearchScope { - private final ProjectFileIndex myIndex; - private final boolean myIncludeTests; - private final LinkedHashSet myEntries = new LinkedHashSet(); - private final Module myModule; - - public ModuleRuntimeClasspathScope(final Module module, boolean includeTests) { - super(module.getProject()); - myModule = module; - myIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex(); - myIncludeTests = includeTests; - buildEntries(module); - } - - public int hashCode() { - return myModule.hashCode(); - } - - public boolean equals(Object object) { - if (object == this) return true; - if (object.getClass() != ModuleRuntimeClasspathScope.class) return false; - - final ModuleRuntimeClasspathScope that = ((ModuleRuntimeClasspathScope)object); - return that.myModule == myModule && that.myIncludeTests == myIncludeTests; - } - - private void buildEntries(final Module module) { - ModuleRootManager.getInstance(module).orderEntries().recursively().process(new RootPolicy>() { - private boolean myJDKProcessed = false; - - public LinkedHashSet visitModuleSourceOrderEntry(final ModuleSourceOrderEntry moduleSourceOrderEntry, - final LinkedHashSet value) { - ContainerUtil.addAll(value, moduleSourceOrderEntry.getFiles(OrderRootType.SOURCES)); - return value; - } - - public LinkedHashSet visitLibraryOrderEntry(final LibraryOrderEntry libraryOrderEntry, - final LinkedHashSet value) { - ContainerUtil.addAll(value, libraryOrderEntry.getRootFiles(OrderRootType.CLASSES)); - return value; - } - - public LinkedHashSet visitJdkOrderEntry(final JdkOrderEntry jdkOrderEntry, final LinkedHashSet value) { - if (myJDKProcessed) return value; - myJDKProcessed = true; - ContainerUtil.addAll(value, jdkOrderEntry.getRootFiles(OrderRootType.CLASSES)); - return value; - } - }, myEntries); - - - } - - public boolean contains(VirtualFile file) { - if (!myIncludeTests && myIndex.isInTestSourceContent(file)) return false; - return myEntries.contains(getFileRoot(file)); - } - - private VirtualFile getFileRoot(VirtualFile file) { - if (myIndex.isLibraryClassFile(file)) { - return myIndex.getClassRootForFile(file); - } - if (myIndex.isInContent(file)) { - return myIndex.getSourceRootForFile(file); - } - return null; - } - - public int compare(VirtualFile file1, VirtualFile file2) { - final VirtualFile r1 = getFileRoot(file1); - final VirtualFile r2 = getFileRoot(file2); - for (VirtualFile root : myEntries) { - if (r1 == root) return 1; - if (r2 == root) return -1; - } - return 0; - } - - public boolean isSearchInModuleContent(@NotNull Module aModule) { - return true; - } - - public boolean isSearchInLibraries() { - return true; - } - - public String getDisplayName() { - return PsiBundle.message("runtime.scope.display.name", myModule.getName()); - } -} diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java index cf38009d5196..42be74b96ab0 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 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. @@ -15,189 +15,174 @@ */ package com.intellij.openapi.module.impl.scopes; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.*; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiBundle; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NonNls; +import com.intellij.util.NotNullFunction; +import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; +import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; -/** - * @author max - */ public class ModuleWithDependenciesScope extends GlobalSearchScope { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.module.impl.scopes.ModuleWithDependenciesScope"); - private final Module myModule; + + private final boolean myCompileClasspath; private final boolean myIncludeLibraries; private final boolean myIncludeOtherModules; private final boolean myIncludeTests; - private final ModuleFileIndex myFileIndex; private final ProjectFileIndex myProjectFileIndex; - private final Set myModules; - public ModuleWithDependenciesScope(Module module, boolean includeLibraries, boolean includeOtherModules, boolean includeTests) { + private final Set myModules = new LinkedHashSet(); + private final Set myRoots = new LinkedHashSet(); + + public ModuleWithDependenciesScope(Module module, + boolean compileClasspath, + boolean includeLibraries, + boolean includeOtherModules, + boolean includeTests) { super(module.getProject()); myModule = module; + + myCompileClasspath = compileClasspath; myIncludeLibraries = includeLibraries; myIncludeOtherModules = includeOtherModules; myIncludeTests = includeTests; - myFileIndex = ModuleRootManager.getInstance(myModule).getFileIndex(); myProjectFileIndex = ProjectRootManager.getInstance(getProject()).getFileIndex(); - if (myIncludeOtherModules) { - myModules = new LinkedHashSet(); - myModules.add(myModule); - Module[] dependencies = ModuleRootManager.getInstance(myModule).getDependencies(myIncludeTests); - ContainerUtil.addAll(myModules, dependencies); - for (Module dependency : dependencies) { - addExportedModules(dependency); - } + OrderEnumerator en = ModuleRootManager.getInstance(module).orderEntries(); + en.recursively(); + + if (myCompileClasspath) { + en.exportedOnly().compileOnly(); } else { - myModules = null; + en.runtimeOnly(); } - } + if (!myIncludeLibraries) en.withoutLibraries(); + if (!myIncludeOtherModules) en.withoutDepModules(); + if (!myIncludeTests) en.productionOnly(); - private void addExportedModules(Module module) { - OrderEntry[] orderEntries = ModuleRootManager.getInstance(module).getOrderEntries(); - for (OrderEntry orderEntry : orderEntries) { - if (!orderEntry.isValid()) { - continue; + en.forEach(new Processor() { + @Override + public boolean process(OrderEntry each) { + if (each instanceof ModuleOrderEntry) { + myModules.add(((ModuleOrderEntry)each).getModule()); + } + else if (each instanceof ModuleSourceOrderEntry) { + myModules.add(each.getOwnerModule()); + } + return true; } - if (orderEntry instanceof ModuleOrderEntry && ((ModuleOrderEntry)orderEntry).isExported()) { - if (!myIncludeTests) { - final DependencyScope scope = ((ModuleOrderEntry)orderEntry).getScope(); - if (!scope.isForProductionCompile() && !scope.isForProductionRuntime()) { - continue; - } - } - Module exportedModule = ((ModuleOrderEntry)orderEntry).getModule(); - if (!myModules.contains(exportedModule)) { //could be true in case of circular dependencies - myModules.add(exportedModule); - addExportedModules(exportedModule); - } + }); + + Collections.addAll(myRoots, en.roots(new NotNullFunction() { + @NotNull + @Override + public OrderRootType fun(OrderEntry entry) { + if (entry instanceof ModuleOrderEntry || entry instanceof ModuleSourceOrderEntry) return OrderRootType.SOURCES; + return OrderRootType.CLASSES; } - } - } - - public boolean contains(VirtualFile file) { - if (!myIncludeTests && myFileIndex.isInTestSourceContent(file)) return false; - - if (myModules != null) { - final Module module = myProjectFileIndex.getModuleForFile(file); - if (module != null) return myModules.contains(module) && - myFileIndex.getOrderEntryForFile(file) != null && - (myIncludeTests || !myProjectFileIndex.isInTestSourceContent(file)); - } - - final List entries = myFileIndex.getOrderEntriesForFile(file); - for (OrderEntry orderEntry : entries) { - if (myIncludeLibraries) { - if (orderEntry instanceof LibraryOrderEntry || - orderEntry instanceof JdkOrderEntry) { - if (!myProjectFileIndex.isInLibraryClasses(file)) { - continue; - } - } - if (orderEntry instanceof ExportableOrderEntry) { - DependencyScope scope = ((ExportableOrderEntry)orderEntry).getScope(); - if (!myIncludeTests && !scope.isForProductionCompile()) { - continue; - } - } - if (myIncludeOtherModules) { - return true; - } - else { - if (!(orderEntry instanceof ModuleOrderEntry)) return true; - } - } - else { - if (myIncludeOtherModules) { - if (orderEntry instanceof ModuleSourceOrderEntry || orderEntry instanceof ModuleOrderEntry) return true; - } - else { - if (orderEntry instanceof ModuleSourceOrderEntry) return true; - } - } - } - - return false; - } - - public int compare(VirtualFile file1, VirtualFile file2) { - OrderEntry orderEntry1 = myFileIndex.getOrderEntryForFile(file1); - LOG.assertTrue(orderEntry1 != null); - OrderEntry orderEntry2 = myFileIndex.getOrderEntryForFile(file2); - LOG.assertTrue(orderEntry2 != null); - int ret = orderEntry2.compareTo(orderEntry1); - if (ret != 0) return ret; - //prefer file which is closer to our module - if (myModules != null) { - for (Module module : myModules) { - ModuleFileIndex fileIndex = ModuleRootManager.getInstance(module).getFileIndex(); - ret = fileIndex.isInContent(file1) ? fileIndex.isInContent(file2) ? 0 : 1 : fileIndex.isInContent(file2) ? -1 : 0; - if (ret != 0) return ret; - } - } - return 0; - } - - public boolean isSearchInModuleContent(@NotNull Module aModule) { - if (myIncludeOtherModules) { - return myModules.contains(aModule); - } - else { - return aModule == myModule; - } - } - - public boolean isSearchInModuleContent(@NotNull final Module aModule, final boolean testSources) { - return isSearchInModuleContent(aModule) && (myIncludeTests || !testSources); - } - - public boolean isSearchInLibraries() { - return myIncludeLibraries; - } - - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ModuleWithDependenciesScope)) return false; - - final ModuleWithDependenciesScope moduleWithDependenciesScope = (ModuleWithDependenciesScope)o; - - if (!myModule.equals(moduleWithDependenciesScope.myModule)) return false; - if (myIncludeLibraries != moduleWithDependenciesScope.myIncludeLibraries) return false; - if (myIncludeOtherModules != moduleWithDependenciesScope.myIncludeOtherModules) return false; - if (myIncludeTests != moduleWithDependenciesScope.myIncludeTests) return false; - - return true; - } - - public int hashCode() { - return myModule.hashCode(); - } - - @NonNls - public String toString() { - return "Module with dependencies:" + myModule.getName() + - " include libraries:" + myIncludeLibraries + - " include other modules:" + myIncludeOtherModules + - " include tests:" + myIncludeTests; + }).getRoots()); } @Override public String getDisplayName() { - return PsiBundle.message("psi.search.scope.module", myModule.getName()); + return myCompileClasspath ? PsiBundle.message("search.scope.module", myModule.getName()) + : PsiBundle.message("search.scope.module.runtime", myModule.getName()); + } + + @Override + public boolean isSearchInModuleContent(@NotNull Module aModule) { + return myModules.contains(aModule); + } + + @Override + public boolean isSearchInModuleContent(@NotNull Module aModule, boolean testSources) { + return isSearchInModuleContent(aModule) && (myIncludeTests || !testSources); + } + + @Override + public boolean isSearchInLibraries() { + return myIncludeLibraries; + } + + @Override + public boolean contains(VirtualFile file) { + return myRoots.contains(getFileRoot(file)); + } + + @Override + public int compare(VirtualFile file1, VirtualFile file2) { + VirtualFile r1 = getFileRoot(file1); + VirtualFile r2 = getFileRoot(file2); + if (r1 == r2) return 0; + + if (r1 == null) return -1; + if (r2 == null) return 1; + + for (VirtualFile root : myRoots) { + if (r1 == root) return 1; + if (r2 == root) return -1; + } + return 0; + } + + @Nullable + private VirtualFile getFileRoot(VirtualFile file) { + if (myProjectFileIndex.isInContent(file)) { + return myProjectFileIndex.getSourceRootForFile(file); + } + return myProjectFileIndex.getClassRootForFile(file); + } + + @TestOnly + public Collection getRoots() { + return Collections.unmodifiableSet(myRoots); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ModuleWithDependenciesScope that = (ModuleWithDependenciesScope)o; + + if (myCompileClasspath != that.myCompileClasspath) return false; + if (myIncludeLibraries != that.myIncludeLibraries) return false; + if (myIncludeOtherModules != that.myIncludeOtherModules) return false; + if (myIncludeTests != that.myIncludeTests) return false; + if (myModule != null ? !myModule.equals(that.myModule) : that.myModule != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (myModule != null ? myModule.hashCode() : 0); + result = 31 * result + (myIncludeLibraries ? 1 : 0); + result = 31 * result + (myIncludeOtherModules ? 1 : 0); + result = 31 * result + (myIncludeTests ? 1 : 0); + result = 31 * result + (myCompileClasspath ? 1 : 0); + return result; + } + + @Override + public String toString() { + return "Module with dependencies:" + myModule.getName() + + " compile:" + myCompileClasspath + + " include libraries:" + myIncludeLibraries + + " include other modules:" + myIncludeOtherModules + + " include tests:" + myIncludeTests; } } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEnumeratorBase.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEnumeratorBase.java index 579272d74eb0..3229519978d5 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEnumeratorBase.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEnumeratorBase.java @@ -24,6 +24,7 @@ import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.NotNullFunction; import com.intellij.util.Processor; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; @@ -152,6 +153,11 @@ abstract class OrderEnumeratorBase extends OrderEnumerator { return new OrderRootsEnumeratorImpl(this, rootType); } + @Override + public OrderRootsEnumerator roots(@NotNull NotNullFunction rootTypeProvider) { + return new OrderRootsEnumeratorImpl(this, rootTypeProvider); + } + ModuleRootModel getRootModel(Module module) { if (myModulesProvider != null) { return myModulesProvider.getRootModel(module); @@ -301,10 +307,11 @@ abstract class OrderEnumeratorBase extends OrderEnumerator { return processor.myValue; } - boolean addCustomOutput(ModuleOrderEntry moduleOrderEntry, Collection result) { + boolean addCustomOutput(Module forModule, ModuleRootModel orderEntryRootModel, OrderRootType type, Collection result) { for (OrderEnumerationHandler handler : myCustomHandlers) { final List urls = new ArrayList(); - final boolean added = handler.addCustomOutput(moduleOrderEntry, myProductionOnly, myRuntimeOnly, myCompileOnly, urls); + final boolean added = + handler.addCustomOutput(forModule, orderEntryRootModel, type, myProductionOnly, myRuntimeOnly, myCompileOnly, urls); for (String url : urls) { ContainerUtil.addIfNotNull(VirtualFileManager.getInstance().findFileByUrl(url), result); } @@ -315,9 +322,9 @@ abstract class OrderEnumeratorBase extends OrderEnumerator { return false; } - boolean addCustomOutputUrls(ModuleOrderEntry moduleOrderEntry, Collection result) { + boolean addCustomOutputUrls(Module forModule, ModuleRootModel orderEntryRootModel, OrderRootType type, Collection result) { for (OrderEnumerationHandler handler : myCustomHandlers) { - if (handler.addCustomOutput(moduleOrderEntry, myProductionOnly, myRuntimeOnly, myCompileOnly, result)) { + if (handler.addCustomOutput(forModule, orderEntryRootModel, type, myProductionOnly, myRuntimeOnly, myCompileOnly, result)) { return true; } } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderRootsEnumeratorImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderRootsEnumeratorImpl.java index cd3b23e4b288..9fea5cbe55aa 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderRootsEnumeratorImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderRootsEnumeratorImpl.java @@ -37,13 +37,22 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.OrderRootsEnumeratorImpl"); private final OrderEnumeratorBase myOrderEnumerator; private final OrderRootType myRootType; + private final NotNullFunction myRootTypeProvider; private boolean myUsingCache; private NotNullFunction myCustomRootProvider; private boolean myWithoutSelfModuleOutput; - public OrderRootsEnumeratorImpl(OrderEnumeratorBase orderEnumerator, OrderRootType rootType) { + public OrderRootsEnumeratorImpl(OrderEnumeratorBase orderEnumerator, @NotNull OrderRootType rootType) { myOrderEnumerator = orderEnumerator; myRootType = rootType; + myRootTypeProvider = null; + } + + public OrderRootsEnumeratorImpl(OrderEnumeratorBase orderEnumerator, + @NotNull NotNullFunction rootTypeProvider) { + myOrderEnumerator = orderEnumerator; + myRootTypeProvider = rootTypeProvider; + myRootType = null; } @NotNull @@ -88,6 +97,7 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator { } private void checkCanUseCache() { + LOG.assertTrue(myRootTypeProvider == null, "Caching not supported for OrderRootsEnumerator with root type provider"); LOG.assertTrue(myCustomRootProvider == null, "Caching not supported for OrderRootsEnumerator with 'usingCustomRootProvider' option"); LOG.assertTrue(!myWithoutSelfModuleOutput, "Caching not supported for OrderRootsEnumerator with 'withoutSelfModuleOutput' option"); } @@ -97,21 +107,24 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator { myOrderEnumerator.forEach(new Processor() { @Override public boolean process(OrderEntry orderEntry) { + OrderRootType type = getRootType(orderEntry); + if (orderEntry instanceof ModuleSourceOrderEntry) { - collectModuleRoots(((ModuleSourceOrderEntry)orderEntry).getRootModel(), result); + collectModuleRoots(type, ((ModuleSourceOrderEntry)orderEntry).getRootModel(), result); } else if (orderEntry instanceof ModuleOrderEntry) { ModuleOrderEntry moduleOrderEntry = (ModuleOrderEntry)orderEntry; final Module module = moduleOrderEntry.getModule(); if (module != null) { - if (myRootType == OrderRootType.CLASSES && myOrderEnumerator.addCustomOutput(moduleOrderEntry, result)) { + ModuleRootModel rootModel = myOrderEnumerator.getRootModel(module); + if (myOrderEnumerator.addCustomOutput(orderEntry.getOwnerModule(), rootModel, type, result)) { return true; } - collectModuleRoots(myOrderEnumerator.getRootModel(module), result); + collectModuleRoots(type, rootModel, result); } } else { - Collections.addAll(result, myCustomRootProvider != null ? myCustomRootProvider.fun(orderEntry) : orderEntry.getFiles(myRootType)); + Collections.addAll(result, myCustomRootProvider != null ? myCustomRootProvider.fun(orderEntry) : orderEntry.getFiles(type)); } return true; } @@ -131,21 +144,24 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator { myOrderEnumerator.forEach(new Processor() { @Override public boolean process(OrderEntry orderEntry) { + OrderRootType type = getRootType(orderEntry); + if (orderEntry instanceof ModuleSourceOrderEntry) { - collectModuleRootsUrls(((ModuleSourceOrderEntry)orderEntry).getRootModel(), result); + collectModuleRootsUrls(type, ((ModuleSourceOrderEntry)orderEntry).getRootModel(), result); } else if (orderEntry instanceof ModuleOrderEntry) { ModuleOrderEntry moduleOrderEntry = (ModuleOrderEntry)orderEntry; final Module module = moduleOrderEntry.getModule(); if (module != null) { - if (myRootType == OrderRootType.CLASSES && myOrderEnumerator.addCustomOutputUrls(moduleOrderEntry, result)) { + ModuleRootModel rootModel = myOrderEnumerator.getRootModel(module); + if (myOrderEnumerator.addCustomOutputUrls(orderEntry.getOwnerModule(), rootModel, type, result)) { return true; } - collectModuleRootsUrls(myOrderEnumerator.getRootModel(module), result); + collectModuleRootsUrls(type, rootModel, result); } } else { - Collections.addAll(result, orderEntry.getUrls(myRootType)); + Collections.addAll(result, orderEntry.getUrls(type)); } return true; } @@ -191,12 +207,12 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator { return this; } - private void collectModuleRoots(ModuleRootModel rootModel, Collection result) { + private void collectModuleRoots(OrderRootType type, ModuleRootModel rootModel, Collection result) { final boolean productionOnly = myOrderEnumerator.isProductionOnly(); - if (myRootType.equals(OrderRootType.SOURCES)) { + if (type.equals(OrderRootType.SOURCES)) { Collections.addAll(result, rootModel.getSourceRoots(!productionOnly)); } - else if (myRootType.equals(OrderRootType.CLASSES)) { + else if (type.equals(OrderRootType.CLASSES)) { final CompilerModuleExtension extension = rootModel.getModuleExtension(CompilerModuleExtension.class); if (extension != null) { if (myWithoutSelfModuleOutput && myOrderEnumerator.isMainModuleModel(rootModel)) { @@ -211,12 +227,12 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator { } } - private void collectModuleRootsUrls(ModuleRootModel rootModel, Collection result) { + private void collectModuleRootsUrls(OrderRootType type, ModuleRootModel rootModel, Collection result) { final boolean productionOnly = myOrderEnumerator.isProductionOnly(); - if (myRootType.equals(OrderRootType.SOURCES)) { + if (type.equals(OrderRootType.SOURCES)) { Collections.addAll(result, rootModel.getSourceRootUrls(!productionOnly)); } - else if (myRootType.equals(OrderRootType.CLASSES)) { + else if (type.equals(OrderRootType.CLASSES)) { final CompilerModuleExtension extension = rootModel.getModuleExtension(CompilerModuleExtension.class); if (extension != null) { if (myWithoutSelfModuleOutput && myOrderEnumerator.isMainModuleModel(rootModel)) { @@ -231,4 +247,7 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator { } } + private OrderRootType getRootType(OrderEntry e) { + return myRootType != null ? myRootType : myRootTypeProvider.fun(e); + } } diff --git a/platform/platform-resources-en/src/messages/PsiBundle.properties b/platform/platform-resources-en/src/messages/PsiBundle.properties index 11f846335388..508794100df1 100644 --- a/platform/platform-resources-en/src/messages/PsiBundle.properties +++ b/platform/platform-resources-en/src/messages/PsiBundle.properties @@ -43,8 +43,10 @@ el.cannot.resolve.variable=Cannot resolve variable ''{0}'' #loc jsf.el.out.of.attribute=JSF EL out of attribute #loc jsf.method.call.is.nonstd.extension=Method call is nonstandard extension #loc -psi.search.scope.unknown= -psi.search.scope.module=Module ''{0}'' +search.scope.unknown= +search.scope.module=Module ''{0}'' +search.scope.module.runtime=Module ''{0}'' runtime scope + anonymous.class.derived.display=Anonymous class derived from {0} local.class.preposition=local anonymous.class.context.display=Anonymous in {0} @@ -85,7 +87,6 @@ invalid.regular.expression.message=Invalid regular expression {0} #psi reference provider options qualified.resolve.class.reference.provider.option=Tells reference provider to process only qualified class references (e.g. not resolve String as java.lang.String) default.path.evaluator.option=Tells reference provider how evaluate default path for given file -runtime.scope.display.name={0} runtime scope el.declare.variable.find.acceptable.class=Find acceptable class 0.is.not.an.identifier=''{0}'' is not an identifier. cannot.modify.a.read.only.directory=Cannot modify a read-only directory ''{0}''. diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenOrderEnumeratorHandler.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenOrderEnumeratorHandler.java index 3716950dc8f4..e0a1e6b2faaf 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenOrderEnumeratorHandler.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenOrderEnumeratorHandler.java @@ -95,20 +95,18 @@ public class MavenOrderEnumeratorHandler extends OrderEnumerationHandler { } @Override - public boolean addCustomOutput(@NotNull ModuleOrderEntry orderEntry, + public boolean addCustomOutput(@NotNull Module forModule, + @NotNull ModuleRootModel orderEntryRootModel, + OrderRootType type, boolean productionOnly, boolean runtimeOnly, boolean compileOnly, @NotNull Collection urls) { - Module ownerModule = orderEntry.getOwnerModule(); - - MavenProjectsManager manager = MavenProjectsManager.getInstance(ownerModule.getProject()); - MavenProject project = manager.findProject(ownerModule); + MavenProjectsManager manager = MavenProjectsManager.getInstance(forModule.getProject()); + MavenProject project = manager.findProject(forModule); if (project == null) return false; - Module depModule = orderEntry.getModule(); - if (depModule == null) return false; - + Module depModule = orderEntryRootModel.getModule(); MavenProject depProject = manager.findProject(depModule); if (depProject == null) return false; @@ -116,18 +114,29 @@ public class MavenOrderEnumeratorHandler extends OrderEnumerationHandler { if (!shouldAddArtifact(each, productionOnly, runtimeOnly, compileOnly)) continue; boolean isTestJar = MavenConstants.TYPE_TEST_JAR.equals(each.getType()) || "tests".equals(each.getClassifier()); - addOutput(depModule, isTestJar, urls); + addRoots(orderEntryRootModel, type, isTestJar, urls); } return true; } - private static void addOutput(Module module, boolean tests, Collection urls) { - CompilerModuleExtension ex = CompilerModuleExtension.getInstance(module); - if (ex == null) return; + private static void addRoots(ModuleRootModel rootModel, OrderRootType type, boolean tests, Collection result) { + if (type == OrderRootType.CLASSES) { + CompilerModuleExtension ex = rootModel.getModuleExtension(CompilerModuleExtension.class); + if (ex == null) return; - String output = tests ? ex.getCompilerOutputUrlForTests() : ex.getCompilerOutputUrl(); - if (output != null) { - urls.add(output); + String output = tests ? ex.getCompilerOutputUrlForTests() : ex.getCompilerOutputUrl(); + if (output != null) { + result.add(output); + } + } + else if (type == OrderRootType.SOURCES) { + for (ContentEntry eachEntry : rootModel.getContentEntries()) { + for (SourceFolder eachFolder : eachEntry.getSourceFolders()) { + if (eachFolder.isTestSource() == tests) { + result.add(eachFolder.getUrl()); + } + } + } } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java index 4309fb041e3a..1b6f8ae1e393 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java @@ -1095,7 +1095,7 @@ public class MavenProjectsTree { @NotNull MavenProgressIndicator process, @NotNull EmbedderTask task) throws MavenProcessCanceledException { MavenEmbedderWrapper embedder = embeddersManager.getEmbedder(embedderKind); - embedder.customizeForStrictResolve(getWorkspaceMap(), console, process); + embedder.customizeForResolve(getWorkspaceMap(), console, process); embedder.clearCachesFor(mavenProject.getMavenId()); try { task.run(embedder); diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenClasspathConfigurationTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenClasspathsAndSearchScopesTest.java similarity index 70% rename from plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenClasspathConfigurationTest.java rename to plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenClasspathsAndSearchScopesTest.java index ad4f0ead2c06..f080ef5fedaa 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenClasspathConfigurationTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenClasspathsAndSearchScopesTest.java @@ -19,30 +19,44 @@ import com.intellij.execution.configurations.JavaParameters; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.roots.CompilerModuleExtension; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.OrderEnumerator; +import com.intellij.openapi.module.impl.scopes.ModuleWithDependenciesScope; +import com.intellij.openapi.roots.*; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.*; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.PathsList; +import com.intellij.util.Processor; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.MavenImportingTestCase; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -public class MavenClasspathConfigurationTest extends MavenImportingTestCase { +public class MavenClasspathsAndSearchScopesTest extends MavenImportingTestCase { private enum Type {PRODUCTION, TESTS} private enum Scope {COMPILE, RUNTIME} + @Override + protected void setUpInWriteAction() throws Exception { + super.setUpInWriteAction(); + createProjectSubDirs("m1/src/main/java", + "m1/src/test/java", + + "m2/src/main/java", + "m2/src/test/java", + + "m3/src/main/java", + "m3/src/test/java", + + "m4/src/main/java", + "m4/src/test/java"); + } + public void testConfiguringModuleDependencies() throws Exception { VirtualFile m1 = createModulePom("m1", "test" + "m1" + @@ -90,12 +104,40 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { setupJdkForModules("m1", "m2", "m3", "m4"); + assertAllProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m2/src/main/java", + getProjectPath() + "/m3/src/main/java"); + assertAllTestsSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m1/src/test/java", + getProjectPath() + "/m2/src/main/java", + getProjectPath() + "/m3/src/main/java"); + + assertAllProductionClasspath("m1", + getProjectPath() + "/m1/target/classes", + getProjectPath() + "/m2/target/classes", + getProjectPath() + "/m3/target/classes"); assertAllTestsClasspath("m1", getProjectPath() + "/m1/target/test-classes", getProjectPath() + "/m1/target/classes", getProjectPath() + "/m2/target/classes", getProjectPath() + "/m3/target/classes"); + assertAllProductionSearchScope("m2", + getProjectPath() + "/m2/src/main/java", + getProjectPath() + "/m3/src/main/java", + getProjectPath() + "/m4/src/main/java"); + assertAllTestsSearchScope("m2", + getProjectPath() + "/m2/src/main/java", + getProjectPath() + "/m2/src/test/java", + getProjectPath() + "/m3/src/main/java", + getProjectPath() + "/m4/src/main/java"); + + assertAllProductionClasspath("m2", + getProjectPath() + "/m2/target/classes", + getProjectPath() + "/m3/target/classes", + getProjectPath() + "/m4/target/classes"); assertAllTestsClasspath("m2", getProjectPath() + "/m2/target/test-classes", getProjectPath() + "/m2/target/classes", @@ -126,10 +168,15 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { setupJdkForModules("m1", "m2"); + assertAllProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m2/src/main/java"); assertAllProductionClasspath("m1", getProjectPath() + "/m1/target/classes", getProjectPath() + "/m2/target/classes"); + assertAllProductionSearchScope("m2", + getProjectPath() + "/m2/src/main/java"); assertAllProductionClasspath("m2", getProjectPath() + "/m2/target/classes"); } @@ -166,11 +213,20 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { setupJdkForModules("m1", "m2", "m3"); + assertAllProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m2/src/test/java", + getProjectPath() + "/m3/src/test/java"); + assertAllTestsSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m1/src/test/java", + getProjectPath() + "/m2/src/test/java", + getProjectPath() + "/m3/src/test/java"); + assertAllProductionClasspath("m1", getProjectPath() + "/m1/target/classes", getProjectPath() + "/m2/target/test-classes", getProjectPath() + "/m3/target/test-classes"); - assertAllTestsClasspath("m1", getProjectPath() + "/m1/target/test-classes", getProjectPath() + "/m1/target/classes", @@ -212,9 +268,16 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { setupJdkForModules("m1", "m2", "m3"); + assertAllProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java"); + assertAllTestsSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m1/src/test/java", + getProjectPath() + "/m2/src/test/java", + getProjectPath() + "/m3/src/test/java"); + assertAllProductionClasspath("m1", getProjectPath() + "/m1/target/classes"); - assertAllTestsClasspath("m1", getProjectPath() + "/m1/target/test-classes", getProjectPath() + "/m1/target/classes", @@ -222,46 +285,6 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { getProjectPath() + "/m3/target/test-classes"); } - public void testConfiguringModuleDependenciesOnTestJarWithTestScopeAndRegularDependency() throws Exception { - VirtualFile m1 = createModulePom("m1", "test" + - "m1" + - "1" + - - "" + - " " + - " test" + - " m2" + - " 1" + - " " + - " " + - " test" + - " m2" + - " 1" + - " test-jar" + - " test" + - " " + - ""); - - VirtualFile m2 = createModulePom("m2", "test" + - "m2" + - "1"); - - importProjects(m1, m2); - assertModules("m1", "m2"); - - setupJdkForModules("m1", "m2"); - - assertAllProductionClasspath("m1", - getProjectPath() + "/m1/target/classes", - getProjectPath() + "/m2/target/classes"); - - assertAllTestsClasspath("m1", - getProjectPath() + "/m1/target/test-classes", - getProjectPath() + "/m1/target/classes", - getProjectPath() + "/m2/target/classes", - getProjectPath() + "/m2/target/test-classes"); - } - public void testConfiguringModuleDependenciesOnBothNormalAndTestJar() throws Exception { VirtualFile m1 = createModulePom("m1", "test" + "m1" + @@ -290,6 +313,17 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { setupJdkForModules("m1", "m2", "m2"); + assertAllProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m2/src/main/java", + getProjectPath() + "/m2/src/test/java"); + assertAllTestsSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m1/src/test/java", + getProjectPath() + "/m2/src/main/java", + getProjectPath() + "/m2/src/test/java"); + + assertAllProductionClasspath("m1", getProjectPath() + "/m1/target/classes", getProjectPath() + "/m2/target/classes", @@ -302,6 +336,55 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { getProjectPath() + "/m2/target/test-classes"); } + public void testConfiguringModuleDependenciesOnNormalAndTestJarWithTestScope() throws Exception { + VirtualFile m1 = createModulePom("m1", "test" + + "m1" + + "1" + + + "" + + " " + + " test" + + " m2" + + " 1" + + " " + + " " + + " test" + + " m2" + + " 1" + + " test-jar" + + " test" + + " " + + ""); + + VirtualFile m2 = createModulePom("m2", "test" + + "m2" + + "1"); + + importProjects(m1, m2); + assertModules("m1", "m2"); + + setupJdkForModules("m1", "m2"); + + assertAllProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m2/src/main/java"); + assertAllTestsSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m1/src/test/java", + getProjectPath() + "/m2/src/main/java", + getProjectPath() + "/m2/src/test/java"); + + assertAllProductionClasspath("m1", + getProjectPath() + "/m1/target/classes", + getProjectPath() + "/m2/target/classes"); + + assertAllTestsClasspath("m1", + getProjectPath() + "/m1/target/test-classes", + getProjectPath() + "/m1/target/classes", + getProjectPath() + "/m2/target/classes", + getProjectPath() + "/m2/target/test-classes"); + } + public void testOptionalLibraryDependencies() throws Exception { createRepositoryFile("jmock/jmock/1.0/jmock-1.0.jar"); VirtualFile m1 = createModulePom("m1", "test" + @@ -343,12 +426,40 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { setupJdkForModules("m1", "m2"); + assertAllProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m2/src/main/java", + getRepositoryPath() + "/jmock/jmock/1.0/jmock-1.0.jar"); + assertAllTestsSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m1/src/test/java", + getProjectPath() + "/m2/src/main/java", + getRepositoryPath() + "/jmock/jmock/1.0/jmock-1.0.jar"); + + assertAllProductionClasspath("m1", + getProjectPath() + "/m1/target/classes", + getProjectPath() + "/m2/target/classes", + getRepositoryPath() + "/jmock/jmock/1.0/jmock-1.0.jar"); assertAllTestsClasspath("m1", getProjectPath() + "/m1/target/test-classes", getProjectPath() + "/m1/target/classes", getProjectPath() + "/m2/target/classes", getRepositoryPath() + "/jmock/jmock/1.0/jmock-1.0.jar"); + assertAllProductionSearchScope("m2", + getProjectPath() + "/m2/src/main/java", + getRepositoryPath() + "/jmock/jmock/1.0/jmock-1.0.jar", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + assertAllTestsSearchScope("m2", + getProjectPath() + "/m2/src/main/java", + getProjectPath() + "/m2/src/test/java", + getRepositoryPath() + "/jmock/jmock/1.0/jmock-1.0.jar", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + + assertAllProductionClasspath("m2", + getProjectPath() + "/m2/target/classes", + getRepositoryPath() + "/jmock/jmock/1.0/jmock-1.0.jar", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); assertAllTestsClasspath("m2", getProjectPath() + "/m2/target/test-classes", getProjectPath() + "/m2/target/classes", @@ -356,74 +467,6 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); } - public void testDoNotChangeClasspathForRegularModules() throws Exception { - VirtualFile m1 = createModulePom("m1", "test" + - "m1" + - "1" + - - "" + - " " + - " test" + - " m2" + - " 1" + - " true" + - " " + - " " + - " junit" + - " junit" + - " 4.0" + - " true" + - " " + - ""); - - VirtualFile m2 = createModulePom("m2", "test" + - "m2" + - "1"); - - importProjects(m1, m2); - assertModules("m1", "m2"); - - final Module user = createModule("user"); - - new WriteCommandAction.Simple(myProject) { - @Override - protected void run() throws Throwable { - ModifiableRootModel model = ModuleRootManager.getInstance(user).getModifiableModel(); - model.addModuleOrderEntry(getModule("m1")); - VirtualFile out = user.getModuleFile().getParent().createChildDirectory(this, "output"); - VirtualFile testOut = user.getModuleFile().getParent().createChildDirectory(this, "test-output"); - model.getModuleExtension(CompilerModuleExtension.class).setCompilerOutputPath(out); - model.getModuleExtension(CompilerModuleExtension.class).setCompilerOutputPathForTests(testOut); - model.getModuleExtension(CompilerModuleExtension.class).inheritCompilerOutputPath(false); - model.commit(); - } - }.execute().throwException(); - - - assertModuleModuleDeps("m1", "m2"); - assertModuleLibDeps("m1", "Maven: junit:junit:4.0"); - - assertModuleModuleDeps("user", "m1"); - assertModuleLibDeps("user"); - - setupJdkForModules("m1", "m2", "user"); - - assertAllTestsClasspath("user", - getProjectPath() + "/user/test-output", - getProjectPath() + "/user/output", - getProjectPath() + "/m1/target/test-classes", - getProjectPath() + "/m1/target/classes", - getProjectPath() + "/m2/target/test-classes", - getProjectPath() + "/m2/target/classes", - getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); - - assertAllTestsClasspath("m1", - getProjectPath() + "/m1/target/test-classes", - getProjectPath() + "/m1/target/classes", - getProjectPath() + "/m2/target/classes", - getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); - } - public void testProvidedAndTestDependencies() throws Exception { createRepositoryFile("jmock/jmock/4.0/jmock-4.0.jar"); VirtualFile m1 = createModulePom("m1", "test" + @@ -471,13 +514,26 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { setupJdkForModules("m1", "m2", "m3"); + assertCompileProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m2/src/main/java", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + assertRuntimeProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java"); + assertAllTestsSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m1/src/test/java", + getProjectPath() + "/m2/src/main/java", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar", + getProjectPath() + "/m3/src/main/java", + getRepositoryPath() + "/jmock/jmock/4.0/jmock-4.0.jar"); + assertCompileProductionClasspath("m1", getProjectPath() + "/m1/target/classes", getProjectPath() + "/m2/target/classes", getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); assertRuntimeProductionClasspath("m1", getProjectPath() + "/m1/target/classes"); - assertAllTestsClasspath("m1", getProjectPath() + "/m1/target/test-classes", getProjectPath() + "/m1/target/classes", @@ -517,6 +573,18 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { setupJdkForModules("m1", "m2"); + assertCompileProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java"); + assertRuntimeProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m2/src/main/java", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + assertAllTestsSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m1/src/test/java", + getProjectPath() + "/m2/src/main/java", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + assertCompileProductionClasspath("m1", getProjectPath() + "/m1/target/classes"); @@ -574,27 +642,44 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { setupJdkForModules("m1", "m2"); + assertAllProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m2/src/main/java"); + assertAllTestsSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m1/src/test/java", + getProjectPath() + "/m2/src/main/java"); + assertAllProductionClasspath("m1", getProjectPath() + "/m1/target/classes", getProjectPath() + "/m2/target/classes"); - assertAllTestsClasspath("m1", getProjectPath() + "/m1/target/test-classes", getProjectPath() + "/m1/target/classes", getProjectPath() + "/m2/target/classes"); + assertCompileProductionSearchScope("m2", + getProjectPath() + "/m2/src/main/java", + getRepositoryPath() + "/jmock/jmock/1.0/jmock-1.0.jar"); + assertRuntimeProductionSearchScope("m2", + getProjectPath() + "/m2/src/main/java"); + assertAllTestsSearchScope("m2", + getProjectPath() + "/m2/src/main/java", + getProjectPath() + "/m2/src/test/java", + getRepositoryPath() + "/jmock/jmock/1.0/jmock-1.0.jar", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + assertCompileProductionClasspath("m2", getProjectPath() + "/m2/target/classes", getRepositoryPath() + "/jmock/jmock/1.0/jmock-1.0.jar"); assertRuntimeProductionClasspath("m2", getProjectPath() + "/m2/target/classes"); - - assertRuntimeTestsClasspath("m2", - getProjectPath() + "/m2/target/test-classes", - getProjectPath() + "/m2/target/classes", - getRepositoryPath() + "/jmock/jmock/1.0/jmock-1.0.jar", - getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + assertAllTestsClasspath("m2", + getProjectPath() + "/m2/target/test-classes", + getProjectPath() + "/m2/target/classes", + getRepositoryPath() + "/jmock/jmock/1.0/jmock-1.0.jar", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); } public void testDoNotIncludeConflictingTransitiveDependenciesInTheClasspath() throws Exception { @@ -647,6 +732,13 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { setupJdkForModules("m1", "m2", "m3"); + assertAllTestsSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m1/src/test/java", + getProjectPath() + "/m2/src/main/java", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar", + getProjectPath() + "/m3/src/main/java"); + assertAllTestsClasspath("m1", getProjectPath() + "/m1/target/test-classes", getProjectPath() + "/m1/target/classes", @@ -699,10 +791,19 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { setupJdkForModules("m1"); + assertAllProductionSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + assertAllTestsSearchScope("m1", + getProjectPath() + "/m1/src/main/java", + getProjectPath() + "/m1/src/test/java", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar", + f1.getPath(), + f2.getPath()); + assertAllProductionClasspath("m1", getProjectPath() + "/m1/target/classes", getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); - assertAllTestsClasspath("m1", getProjectPath() + "/m1/target/test-classes", getProjectPath() + "/m1/target/classes", @@ -711,6 +812,101 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { f2.getPath()); } + public void testDoNotChangeClasspathForRegularModules() throws Exception { + VirtualFile m1 = createModulePom("m1", "test" + + "m1" + + "1" + + + "" + + " " + + " test" + + " m2" + + " 1" + + " runtime" + + " true" + + " " + + " " + + " junit" + + " junit" + + " 4.0" + + " provided" + + " true" + + " " + + ""); + + VirtualFile m2 = createModulePom("m2", "test" + + "m2" + + "1"); + + importProjects(m1, m2); + assertModules("m1", "m2"); + + final Module user = createModule("user"); + + new WriteCommandAction.Simple(myProject) { + @Override + protected void run() throws Throwable { + ModifiableRootModel model = ModuleRootManager.getInstance(user).getModifiableModel(); + model.addModuleOrderEntry(getModule("m1")); + VirtualFile out = user.getModuleFile().getParent().createChildDirectory(this, "output"); + VirtualFile testOut = user.getModuleFile().getParent().createChildDirectory(this, "test-output"); + model.getModuleExtension(CompilerModuleExtension.class).setCompilerOutputPath(out); + model.getModuleExtension(CompilerModuleExtension.class).setCompilerOutputPathForTests(testOut); + model.getModuleExtension(CompilerModuleExtension.class).inheritCompilerOutputPath(false); + model.commit(); + } + }.execute().throwException(); + + + assertModuleModuleDeps("m1", "m2"); + assertModuleLibDeps("m1", "Maven: junit:junit:4.0"); + + assertModuleModuleDeps("user", "m1"); + assertModuleLibDeps("user"); + + setupJdkForModules("m1", "m2", "user"); + + // todo check search scopes + + assertCompileProductionClasspath("user", + getProjectPath() + "/user/output", + getProjectPath() + "/m1/target/classes", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + + assertRuntimeProductionClasspath("user", + getProjectPath() + "/user/output", + getProjectPath() + "/m1/target/classes", + getProjectPath() + "/m2/target/classes"); + + assertCompileTestsClasspath("user", + getProjectPath() + "/user/test-output", + getProjectPath() + "/user/output", + getProjectPath() + "/m1/target/test-classes", + getProjectPath() + "/m1/target/classes", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + + assertRuntimeTestsClasspath("user", + getProjectPath() + "/user/test-output", + getProjectPath() + "/user/output", + getProjectPath() + "/m1/target/test-classes", + getProjectPath() + "/m1/target/classes", + getProjectPath() + "/m2/target/test-classes", + getProjectPath() + "/m2/target/classes", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + + assertCompileProductionClasspath("m1", + getProjectPath() + "/m1/target/classes", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + assertRuntimeProductionClasspath("m1", + getProjectPath() + "/m1/target/classes", + getProjectPath() + "/m2/target/classes"); + assertAllTestsClasspath("m1", + getProjectPath() + "/m1/target/test-classes", + getProjectPath() + "/m1/target/classes", + getProjectPath() + "/m2/target/classes", + getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar"); + } + private void assertAllProductionClasspath(String moduleName, String... paths) throws Exception { assertCompileProductionClasspath(moduleName, paths); assertRuntimeProductionClasspath(moduleName, paths); @@ -737,25 +933,91 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { assertClasspath(moduleName, Scope.RUNTIME, Type.TESTS, paths); } - private void assertClasspath(String moduleName, Scope scope, Type type, String... paths) throws Exception { + private void assertClasspath(String moduleName, Scope scope, Type type, String... expectedPaths) throws Exception { createOutputDirectories(); - PathsList actualPaths; + + PathsList actualPathsList; + Module module = getModule(moduleName); + if (scope == Scope.RUNTIME) { JavaParameters params = new JavaParameters(); - params.configureByModule(getModule(moduleName), type == Type.TESTS ? JavaParameters.CLASSES_AND_TESTS : JavaParameters.CLASSES_ONLY); - actualPaths = params.getClassPath(); + params.configureByModule(module, type == Type.TESTS ? JavaParameters.CLASSES_AND_TESTS : JavaParameters.CLASSES_ONLY); + actualPathsList = params.getClassPath(); } else { - OrderEnumerator en = OrderEnumerator.orderEntries(getModule(moduleName)).recursively().withoutSdk().compileOnly(); + OrderEnumerator en = OrderEnumerator.orderEntries(module).recursively().withoutSdk().compileOnly(); if (type == Type.PRODUCTION) en.productionOnly(); - actualPaths = en.classes().getPathsList(); + actualPathsList = en.classes().getPathsList(); } + assertPaths(expectedPaths, actualPathsList.getPathList()); + } + + private void assertAllProductionSearchScope(String moduleName, String... paths) throws Exception { + assertCompileProductionSearchScope(moduleName, paths); + assertRuntimeProductionSearchScope(moduleName, paths); + } + + private void assertAllTestsSearchScope(String moduleName, String... paths) throws Exception { + assertCompileTestsSearchScope(moduleName, paths); + assertRuntimeTestsSearchScope(moduleName, paths); + } + + private void assertCompileProductionSearchScope(String moduleName, String... paths) throws Exception { + assertSearchScope(moduleName, Scope.COMPILE, Type.PRODUCTION, paths); + } + + private void assertCompileTestsSearchScope(String moduleName, String... paths) throws Exception { + assertSearchScope(moduleName, Scope.COMPILE, Type.TESTS, paths); + } + + private void assertRuntimeProductionSearchScope(String moduleName, String... paths) throws Exception { + assertSearchScope(moduleName, Scope.RUNTIME, Type.PRODUCTION, paths); + } + + private void assertRuntimeTestsSearchScope(String moduleName, String... paths) throws Exception { + assertSearchScope(moduleName, Scope.RUNTIME, Type.TESTS, paths); + } + + + private void assertSearchScope(String moduleName, Scope scope, Type type, String... expectedPaths) throws Exception { + createOutputDirectories(); + Module module = getModule(moduleName); + + GlobalSearchScope searchScope = scope == Scope.COMPILE ? module.getModuleWithDependenciesAndLibrariesScope(type == Type.TESTS) + : module.getModuleRuntimeScope(type == Type.TESTS); + + final List entries = new ArrayList(((ModuleWithDependenciesScope)searchScope).getRoots()); + + OrderEnumerator.orderEntries(module).recursively().compileOnly().forEach(new Processor() { + @Override + public boolean process(OrderEntry orderEntry) { + if (orderEntry instanceof JdkOrderEntry) { + entries.removeAll(Arrays.asList(orderEntry.getFiles(OrderRootType.CLASSES))); + } + return true; + } + }); + + List actualPaths = new ArrayList(); + for (VirtualFile each : entries) { + if (each.getFileSystem() == JarFileSystem.getInstance()) { + actualPaths.add(JarFileSystem.getInstance().getVirtualFileForJar(each).getPath()); + } + else { + actualPaths.add(each.getPath()); + } + } + + assertPaths(expectedPaths, actualPaths); + } + + private void assertPaths(String[] expectedPaths, List actualPaths) { List systemPaths = new ArrayList(); - for (String each : paths) { + for (String each : expectedPaths) { systemPaths.add(FileUtil.toSystemDependentName(each)); } - assertOrderedElementsAreEqual(actualPaths.getPathList(), systemPaths); + assertOrderedElementsAreEqual(actualPaths, systemPaths); } private void createRepositoryFile(String filePath) throws IOException { @@ -765,7 +1027,7 @@ public class MavenClasspathConfigurationTest extends MavenImportingTestCase { private void createOutputDirectories() { for (Module module : ModuleManager.getInstance(myProject).getModules()) { - final CompilerModuleExtension extension = CompilerModuleExtension.getInstance(module); + CompilerModuleExtension extension = CompilerModuleExtension.getInstance(module); if (extension != null) { createDirectoryIfDoesntExist(extension.getCompilerOutputUrl()); createDirectoryIfDoesntExist(extension.getCompilerOutputUrlForTests());