diff --git a/java/java-tests/testSrc/com/intellij/roots/OrderEnumeratorTest.java b/java/java-tests/testSrc/com/intellij/roots/OrderEnumeratorTest.java
index 91dbbe4e0630..dd1aa2d6c6c8 100644
--- a/java/java-tests/testSrc/com/intellij/roots/OrderEnumeratorTest.java
+++ b/java/java-tests/testSrc/com/intellij/roots/OrderEnumeratorTest.java
@@ -38,6 +38,9 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase {
assertClassRoots(orderEntries(myModule).withoutSdk().productionOnly(), output);
assertSourceRoots(orderEntries(myModule), srcRoot, testRoot);
assertSourceRoots(orderEntries(myModule).productionOnly(), srcRoot);
+
+ assertEnumeratorRoots(orderEntries(myModule).withoutSdk().classes().withoutSelfModuleOutput(), output);
+ assertEnumeratorRoots(orderEntries(myModule).withoutSdk().productionOnly().classes().withoutSelfModuleOutput());
}
public void testLibraryScope() throws Exception {
@@ -61,6 +64,7 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase {
assertClassRoots(orderEntries(myModule).withoutSdk().recursively(), testOutput, output, getJDomJar());
assertSourceRoots(orderEntries(myModule), srcRoot, testRoot);
assertSourceRoots(orderEntries(myModule).recursively(), srcRoot, testRoot, getJDomSources());
+ assertEnumeratorRoots(orderEntries(myModule).withoutSdk().recursively().classes().withoutSelfModuleOutput(), testOutput, output, getJDomJar());
}
public void testModuleDependencyScope() throws Exception {
diff --git a/platform/lang-api/src/com/intellij/openapi/roots/OrderRootsEnumerator.java b/platform/lang-api/src/com/intellij/openapi/roots/OrderRootsEnumerator.java
index cd3a21be4720..67e74e9f9bae 100644
--- a/platform/lang-api/src/com/intellij/openapi/roots/OrderRootsEnumerator.java
+++ b/platform/lang-api/src/com/intellij/openapi/roots/OrderRootsEnumerator.java
@@ -62,6 +62,15 @@ public interface OrderRootsEnumerator {
*/
OrderRootsEnumerator usingCache();
+ /**
+ * This method makes sense only when dependencies of a module are processed (i.e. the enumerator instance is obtained by using {@link OrderEnumerator#orderEntries(com.intellij.openapi.module.Module)} or
+ * {@link ModuleRootModel#orderEntries()}). It instructs the enumerator to skip the output of the main module (if {@link com.intellij.openapi.roots.OrderEnumerator#productionOnly()}
+ * option is not specified then only the test output will be skipped)
+ *
+ * @return this instance
+ */
+ OrderRootsEnumerator withoutSelfModuleOutput();
+
/**
* Use provider to obtain roots of an library or jdk order entry instead of {@link OrderEntry#getFiles(OrderRootType)} method. Note that
* this option won't affect result of {@link #getUrls()} method
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleOrderEnumerator.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleOrderEnumerator.java
index 4fe6590f41ee..9b640737255b 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleOrderEnumerator.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleOrderEnumerator.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.util.Processor;
import gnu.trove.THashSet;
@@ -37,5 +38,9 @@ public class ModuleOrderEnumerator extends OrderEnumeratorBase {
processEntries(myRootModel, processor, myRecursively ? new THashSet() : null, true);
}
+ @Override
+ public boolean isMainModuleModel(@NotNull ModuleRootModel rootModel) {
+ return rootModel.equals(myRootModel);
+ }
}
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 be89e9ac2a29..b64eaad9ae9b 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
@@ -306,6 +306,10 @@ abstract class OrderEnumeratorBase extends OrderEnumerator {
return false;
}
+ public boolean isMainModuleModel(@NotNull ModuleRootModel rootModel) {
+ return false;
+ }
+
private class OrderEntryProcessor implements Processor {
private R myValue;
private final RootPolicy myPolicy;
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 816e7127a3a2..98fd65880537 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
@@ -39,6 +39,7 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator {
private final OrderRootType myRootType;
private boolean myUsingCache;
private NotNullFunction myCustomRootProvider;
+ private boolean myWithoutSelfModuleOutput;
public OrderRootsEnumeratorImpl(OrderEnumeratorBase orderEnumerator, OrderRootType rootType) {
myOrderEnumerator = orderEnumerator;
@@ -88,6 +89,7 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator {
private void checkCanUseCache() {
LOG.assertTrue(myCustomRootProvider == null, "Caching not supported for OrderRootsEnumerator with 'usingCustomRootProvider' option");
+ LOG.assertTrue(!myWithoutSelfModuleOutput, "Caching not supported for OrderRootsEnumerator with 'withoutSelfModuleOutput' option");
}
private Collection computeRoots() {
@@ -163,6 +165,12 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator {
return this;
}
+ @Override
+ public OrderRootsEnumerator withoutSelfModuleOutput() {
+ myWithoutSelfModuleOutput = true;
+ return this;
+ }
+
@Override
public OrderRootsEnumerator usingCustomRootProvider(@NotNull NotNullFunction provider) {
myCustomRootProvider = provider;
@@ -170,25 +178,41 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator {
}
private void collectModuleRoots(ModuleRootModel rootModel, Collection result) {
+ final boolean productionOnly = myOrderEnumerator.isProductionOnly();
if (myRootType.equals(OrderRootType.SOURCES)) {
- Collections.addAll(result, rootModel.getSourceRoots(!myOrderEnumerator.isProductionOnly()));
+ Collections.addAll(result, rootModel.getSourceRoots(!productionOnly));
}
else if (myRootType.equals(OrderRootType.CLASSES)) {
final CompilerModuleExtension extension = rootModel.getModuleExtension(CompilerModuleExtension.class);
if (extension != null) {
- Collections.addAll(result, extension.getOutputRoots(!myOrderEnumerator.isProductionOnly()));
+ if (myWithoutSelfModuleOutput && myOrderEnumerator.isMainModuleModel(rootModel)) {
+ if (!productionOnly) {
+ Collections.addAll(result, extension.getOutputRoots(false));
+ }
+ }
+ else {
+ Collections.addAll(result, extension.getOutputRoots(!productionOnly));
+ }
}
}
}
private void collectModuleRootsUrls(ModuleRootModel rootModel, Collection result) {
+ final boolean productionOnly = myOrderEnumerator.isProductionOnly();
if (myRootType.equals(OrderRootType.SOURCES)) {
- Collections.addAll(result, rootModel.getSourceRootUrls(!myOrderEnumerator.isProductionOnly()));
+ Collections.addAll(result, rootModel.getSourceRootUrls(!productionOnly));
}
else if (myRootType.equals(OrderRootType.CLASSES)) {
final CompilerModuleExtension extension = rootModel.getModuleExtension(CompilerModuleExtension.class);
if (extension != null) {
- Collections.addAll(result, extension.getOutputRootUrls(!myOrderEnumerator.isProductionOnly()));
+ if (myWithoutSelfModuleOutput && myOrderEnumerator.isMainModuleModel(rootModel)) {
+ if (!productionOnly) {
+ Collections.addAll(result, extension.getOutputRootUrls(false));
+ }
+ }
+ else {
+ Collections.addAll(result, extension.getOutputRootUrls(!productionOnly));
+ }
}
}
}