diff --git a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemImportingTestCase.java b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemImportingTestCase.java index 47a8fe561760..7c6345417e28 100644 --- a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemImportingTestCase.java +++ b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemImportingTestCase.java @@ -569,6 +569,26 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest }); } + @Nullable + protected SourceFolder findSource(@NotNull String moduleName, @NotNull String sourcePath) { + return findSource(getRootManager(moduleName), sourcePath); + } + + @Nullable + protected SourceFolder findSource(@NotNull ModuleRootModel moduleRootManager, @NotNull String sourcePath) { + ContentEntry[] contentRoots = moduleRootManager.getContentEntries(); + Module module = moduleRootManager.getModule(); + String rootUrl = getAbsolutePath(ExternalSystemApiUtil.getExternalProjectPath(module)); + for (ContentEntry contentRoot : contentRoots) { + for (SourceFolder f : contentRoot.getSourceFolders()) { + String folderPath = getAbsolutePath(f.getUrl()); + String rootPath = getAbsolutePath(rootUrl + "/" + sourcePath); + if (folderPath.equals(rootPath)) return f; + } + } + return null; + } + //protected void assertProblems(String... expectedProblems) { // final List actualProblems = new ArrayList(); // UIUtil.invokeAndWaitIfNeeded(new Runnable() { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java index 0ab1b0c63b9c..4afe27c52b90 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java @@ -281,6 +281,11 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver } PathPrefixTreeMap contentRootIndex = new PathPrefixTreeMapImpl<>(); + for (DataNode contentRootDataNode : ExternalSystemApiUtil.findAll(ideModule, ProjectKeys.CONTENT_ROOT)) { + ContentRootData contentRootData = contentRootDataNode.getData(); + contentRootIndex.set(contentRootData.getRootPath(), contentRootData); + } + DomainObjectSet contentRoots = gradleModule.getContentRoots(); if (contentRoots == null) return; for (IdeaContentRoot gradleContentRoot : contentRoots) { @@ -332,8 +337,15 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver } } } + Set existsContentRoots = new LinkedHashSet<>(); + for (DataNode contentRootDataNode : ExternalSystemApiUtil.findAll(ideModule, ProjectKeys.CONTENT_ROOT)) { + ContentRootData contentRootData = contentRootDataNode.getData(); + existsContentRoots.add(contentRootData.getRootPath()); + } for (ContentRootData ideContentRoot : contentRootIndex.getValues()) { - ideModule.createChild(ProjectKeys.CONTENT_ROOT, ideContentRoot); + if (!existsContentRoots.contains(ideContentRoot.getRootPath())) { + ideModule.createChild(ProjectKeys.CONTENT_ROOT, ideContentRoot); + } } } diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleBuildScriptBuilderEx.kt b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleBuildScriptBuilderEx.kt index cec128d9c497..82d0cb00b22a 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleBuildScriptBuilderEx.kt +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleBuildScriptBuilderEx.kt @@ -3,7 +3,6 @@ package org.jetbrains.plugins.gradle.importing import com.intellij.openapi.util.io.FileUtil import java.io.File -import java.lang.RuntimeException class GradleBuildScriptBuilderEx : GradleBuildScriptBuilder() { fun withGradleIdeaExtPluginIfCan(version: String) = apply { @@ -40,6 +39,10 @@ class GradleBuildScriptBuilderEx : GradleBuildScriptBuilder() { applyPlugin("'java'") } + fun withIdeaPlugin() = apply { + applyPlugin("'idea'") + } + fun withKotlinPlugin(version: String) = apply { addBuildScriptPrefix("ext.kotlin_version = '$version'") addBuildScriptRepository("mavenCentral()") diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleFoldersImportingTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleFoldersImportingTest.java index e1b8094902cb..e1b98fb78bc5 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleFoldersImportingTest.java +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleFoldersImportingTest.java @@ -20,9 +20,11 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.SourceFolder; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.ThreeState; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.java.JavaSourceRootType; import org.jetbrains.plugins.gradle.tooling.annotation.TargetVersions; import org.junit.Test; @@ -441,6 +443,103 @@ public class GradleFoldersImportingTest extends GradleImportingTestCase { assertModuleGroupPath("project3", "rootName", "project1", "project3"); } + @Test + public void testSourceFoldersOutOfContentRootWithModuleResolving() throws Exception { + createProjectSubFile("src/main/java/A.java", "class A {}"); + createProjectSubFile("../outer1/src/main/java/A.java", "class A {}"); + createProjectSubFile("../outer1/src/main/kotlin/A.kt", "class A {}"); + createProjectSubFile("../outer2/src/main/java/A.java", "class A {}"); + createProjectSubFile("../outer3/A.java", "class A {}"); + createProjectSubFile("build/generated/A.java", "class A {}"); + createProjectSubFile("../outer4/generated/A.java", "class A {}"); + GradleBuildScriptBuilder buildScript = new GradleBuildScriptBuilderEx() + .withJavaPlugin() + .withIdeaPlugin() + .addPrefix("sourceSets {") + .addPrefix(" generated.java.srcDirs += \"${buildDir}/generated\"") + .addPrefix(" generated.java.srcDirs += '../outer4/generated'") + .addPrefix(" main.java.srcDirs += '../outer1/src/main/java'") + .addPrefix(" main.java.srcDirs += '../outer1/src/main/kotlin'") + .addPrefix(" main.java.srcDirs += '../outer2/src/main/java'") + .addPrefix(" main.java.srcDirs += '../outer3'") + .addPrefix("}") + .addPrefix("idea {") + .addPrefix(" module {") + .addPrefix(" inheritOutputDirs = true") + .addPrefix(" generatedSourceDirs += file(\"${buildDir}/generated\")") + .addPrefix(" generatedSourceDirs += file('../outer4/generated')") + .addPrefix(" }") + .addPrefix("}"); + getCurrentExternalProjectSettings().setResolveModulePerSourceSet(true); + importProject(buildScript.generate()); + assertModules("project", "project.main", "project.test", "project.generated"); + assertContentEntryExists("project", ""); + assertContentEntryExists("project.main", + "../outer1", + "../outer2", + "../outer3"); + assertContentEntryExists("project.generated", + "build/generated", + "../outer4"); + assertSourceExists("project.main", + "src/main/java", + "../outer1/src/main/java", + "../outer1/src/main/kotlin", + "../outer2/src/main/java", + "../outer3"); + assertSourceExists("project.generated", + "build/generated", + "../outer4/generated"); + } + + @Test + public void testSourceFoldersOutOfContentRootWithoutModuleResolving() throws Exception { + createProjectSubFile("src/main/java/A.java", "class A {}"); + createProjectSubFile("../outer1/src/main/java/A.java", "class A {}"); + createProjectSubFile("../outer1/src/main/kotlin/A.kt", "class A {}"); + createProjectSubFile("../outer2/src/main/java/A.java", "class A {}"); + createProjectSubFile("../outer3/A.java", "class A {}"); + createProjectSubFile("build/generated/A.java", "class A {}"); + createProjectSubFile("../outer4/generated/A.java", "class A {}"); + GradleBuildScriptBuilder buildScript = new GradleBuildScriptBuilderEx() + .withJavaPlugin() + .withIdeaPlugin() + .addPrefix("sourceSets {") + .addPrefix(" generated.java.srcDirs += \"${buildDir}/generated\"") + .addPrefix(" generated.java.srcDirs += '../outer4/generated'") + .addPrefix(" main.java.srcDirs += '../outer1/src/main/java'") + .addPrefix(" main.java.srcDirs += '../outer1/src/main/kotlin'") + .addPrefix(" main.java.srcDirs += '../outer2/src/main/java'") + .addPrefix(" main.java.srcDirs += '../outer3'") + .addPrefix("}") + .addPrefix("idea {") + .addPrefix(" module {") + .addPrefix(" inheritOutputDirs = true") + .addPrefix(" generatedSourceDirs += file(\"${buildDir}/generated\")") + .addPrefix(" generatedSourceDirs += file('../outer4/generated')") + .addPrefix(" }") + .addPrefix("}"); + getCurrentExternalProjectSettings().setResolveModulePerSourceSet(false); + importProject(buildScript.generate()); + assertModules("project"); + assertContentEntryExists("project", + "", + "../outer1/src/main/java", + "../outer1/src/main/kotlin", + "../outer2", + "../outer3", + "build/generated", + "../outer4"); + assertSourceExists("project", + "src/main/java", + "../outer1/src/main/java", + "../outer1/src/main/kotlin", + "../outer2/src/main/java", + "../outer3", + "build/generated", + "../outer4/generated"); + } + protected void assertDefaultGradleJavaProjectFolders(@NotNull String mainModuleName) { assertExcludes(mainModuleName, ".gradle", "build", "out"); final String mainSourceSetModuleName = mainModuleName + ".main"; @@ -475,4 +574,32 @@ public class GradleFoldersImportingTest extends GradleImportingTestCase { String rootUrl = contentRoots.length > 1 ? ExternalSystemApiUtil.getExternalProjectPath(fooModule) : null; doAssertContentFolders(rootUrl, contentRoots, JavaSourceRootType.TEST_SOURCE, expected); } + + @Nullable + protected ContentEntry findContentEntry(@NotNull String moduleName, @NotNull String contentPath) { + ModuleRootManager moduleRootManager = getRootManager(moduleName); + Module module = moduleRootManager.getModule(); + String rootPath = getAbsolutePath(ExternalSystemApiUtil.getExternalProjectPath(module)); + String expectedContentPath = getAbsolutePath(rootPath + "/" + contentPath); + ContentEntry[] contentEntries = moduleRootManager.getContentEntries(); + for (ContentEntry contentEntry : contentEntries) { + String actualContentPath = getAbsolutePath(contentEntry.getUrl()); + if (actualContentPath.equals(expectedContentPath)) return contentEntry; + } + return null; + } + + protected void assertContentEntryExists(@NotNull String moduleName, @NotNull String... contentPaths) { + for (String contentPath : contentPaths) { + ContentEntry contentEntry = findContentEntry(moduleName, contentPath); + assertNotNull("Content entry " + contentPath + " not found in module " + moduleName, contentEntry); + } + } + + protected void assertSourceExists(@NotNull String moduleName, @NotNull String... sourcePaths) { + for (String sourcePath : sourcePaths) { + SourceFolder sourceFolder = findSource(moduleName, sourcePath); + assertNotNull("Source folder " + sourcePath + " not found in module " + moduleName, sourceFolder); + } + } } diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleSettingsImportingTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleSettingsImportingTest.java index 895a72fbf0d3..59142a28151b 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleSettingsImportingTest.java +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleSettingsImportingTest.java @@ -28,12 +28,14 @@ import com.intellij.openapi.externalSystem.service.project.manage.SourceFolderMa import com.intellij.openapi.externalSystem.service.project.manage.SourceFolderManagerImpl; import com.intellij.openapi.externalSystem.service.project.settings.FacetConfigurationImporter; import com.intellij.openapi.externalSystem.service.project.settings.RunConfigurationImporter; -import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ex.ProjectManagerEx; -import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.SourceFolder; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.Version; import com.intellij.openapi.util.io.FileUtil; @@ -49,7 +51,6 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import org.intellij.lang.annotations.Language; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.service.settings.GradleSettingsService; import org.jetbrains.plugins.gradle.settings.GradleSettings; import org.jetbrains.plugins.gradle.settings.TestRunner; @@ -761,26 +762,6 @@ public class GradleSettingsImportingTest extends GradleImportingTestCase { assertNotNull("Source folder " + sourcePath + " not found in module " + moduleName, sourceFolder); assertEquals(packagePrefix, sourceFolder.getPackagePrefix()); } - - @Nullable - protected SourceFolder findSource(@NotNull String moduleName, @NotNull String sourcePath) { - return findSource(getRootManager(moduleName), sourcePath); - } - - @Nullable - protected SourceFolder findSource(@NotNull ModuleRootModel moduleRootManager, @NotNull String sourcePath) { - ContentEntry[] contentRoots = moduleRootManager.getContentEntries(); - Module module = moduleRootManager.getModule(); - String rootUrl = getAbsolutePath(ExternalSystemApiUtil.getExternalProjectPath(module)); - for (ContentEntry contentRoot : contentRoots) { - for (SourceFolder f : contentRoot.getSourceFolders()) { - String folderPath = getAbsolutePath(f.getUrl()); - String rootPath = getAbsolutePath(rootUrl + "/" + sourcePath); - if (folderPath.equals(rootPath)) return f; - } - } - return null; - } }