diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt index a968d6b071e..d39efae47ac 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt @@ -25,13 +25,16 @@ import com.intellij.psi.util.CachedValuesManager import com.intellij.util.PathUtil import com.intellij.util.SmartList import org.jetbrains.jps.model.java.JavaSourceRootType +import org.jetbrains.jps.model.module.JpsModuleSourceRootType import org.jetbrains.kotlin.analyzer.CombinedModuleInfo import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.analyzer.TrackableModuleInfo import org.jetbrains.kotlin.caches.project.LibraryModuleInfo +import org.jetbrains.kotlin.config.KotlinSourceRootType import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.idea.configuration.BuildSystemType import org.jetbrains.kotlin.idea.configuration.getBuildSystemType +import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware import org.jetbrains.kotlin.idea.facet.KotlinFacetType import org.jetbrains.kotlin.idea.facet.KotlinFacetType.Companion.ID import org.jetbrains.kotlin.idea.framework.getLibraryPlatform @@ -217,10 +220,10 @@ fun Module.testSourceInfo(): ModuleTestSourceInfo? = if (hasTestRoots()) ModuleT internal fun Module.correspondingModuleInfos(): List = listOf(testSourceInfo(), productionSourceInfo()).filterNotNull() -private fun Module.hasProductionRoots() = hasRootsOfType(JavaSourceRootType.SOURCE) -private fun Module.hasTestRoots() = hasRootsOfType(JavaSourceRootType.TEST_SOURCE) +private fun Module.hasProductionRoots() = hasRootsOfType(JavaSourceRootType.SOURCE) || hasRootsOfType(KotlinSourceRootType.Source) +private fun Module.hasTestRoots() = hasRootsOfType(JavaSourceRootType.TEST_SOURCE) || hasRootsOfType(KotlinSourceRootType.TestSource) -private fun Module.hasRootsOfType(sourceRootType: JavaSourceRootType): Boolean = +private fun Module.hasRootsOfType(sourceRootType: JpsModuleSourceRootType<*>): Boolean = rootManager.contentEntries.any { it.getSourceFolders(sourceRootType).isNotEmpty() } private abstract class ModuleSourceScope(val module: Module) : GlobalSearchScope(module.project), GlobalSearchScopeWithModuleSources { @@ -241,7 +244,7 @@ private class ModuleProductionSourceScope(module: Module) : ModuleSourceScope(mo override fun hashCode(): Int = 31 * module.hashCode() override fun contains(file: VirtualFile) = - moduleFileIndex.isInSourceContentWithoutInjected(file) && !moduleFileIndex.isInTestSourceContent(file) + moduleFileIndex.isInSourceContentWithoutInjected(file) && !moduleFileIndex.isInTestSourceContentKotlinAware(file) override fun toString() = "ModuleProductionSourceScope($module)" } @@ -257,7 +260,7 @@ private class ModuleTestSourceScope(module: Module) : ModuleSourceScope(module) // KT-6206 override fun hashCode(): Int = 37 * module.hashCode() - override fun contains(file: VirtualFile) = moduleFileIndex.isInTestSourceContent(file) + override fun contains(file: VirtualFile) = moduleFileIndex.isInTestSourceContentKotlinAware(file) override fun toString() = "ModuleTestSourceScope($module)" } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt index 424f0cbf72e..0551df2d446 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.asJava.classes.FakeLightClassForFileOfPackage import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.elements.KtLightElement import org.jetbrains.kotlin.idea.caches.lightClasses.KtLightClassForDecompiledDeclaration +import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager import org.jetbrains.kotlin.idea.core.script.scriptRelatedModuleName import org.jetbrains.kotlin.idea.util.ProjectRootsUtil @@ -298,7 +299,7 @@ private fun getModuleRelatedModuleInfo(projectFileIndex: ProjectFileIndex, virtu val module = projectFileIndex.getModuleForFile(virtualFile) if (module != null && !module.isDisposed) { val moduleFileIndex = ModuleRootManager.getInstance(module).fileIndex - if (moduleFileIndex.isInTestSourceContent(virtualFile)) { + if (moduleFileIndex.isInTestSourceContentKotlinAware(virtualFile)) { return module.testSourceInfo() } else if (moduleFileIndex.isInSourceContentWithoutInjected(virtualFile)) { return module.productionSourceInfo() diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/modules/ModuleHighlightUtil2.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/modules/ModuleHighlightUtil2.java index 37686de9851..053f070e51d 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/modules/ModuleHighlightUtil2.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/modules/ModuleHighlightUtil2.java @@ -30,6 +30,7 @@ import com.intellij.psi.impl.light.LightJavaModule; import kotlin.collections.ArraysKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.idea.core.FileIndexUtilsKt; import java.io.IOException; import java.io.InputStream; @@ -79,7 +80,7 @@ public class ModuleHighlightUtil2 { else { Module module = index.getModuleForFile(file); if (module != null) { - boolean isTest = index.isInTestSourceContent(file); + boolean isTest = FileIndexUtilsKt.isInTestSourceContentKotlinAware(index, file); VirtualFile modularRoot = ArraysKt.singleOrNull(ModuleRootManager.getInstance(module).getSourceRoots(isTest), root -> root.findChild(MODULE_INFO_FILE) != null); if (modularRoot != null) { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/fileIndexUtils.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/fileIndexUtils.kt new file mode 100644 index 00000000000..427fa2cf4b7 --- /dev/null +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/fileIndexUtils.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.core + +import com.intellij.openapi.roots.FileIndex +import com.intellij.openapi.vfs.VirtualFile +import org.jetbrains.jps.model.java.JavaResourceRootType +import org.jetbrains.jps.model.java.JavaSourceRootType +import org.jetbrains.jps.model.module.JpsModuleSourceRootType +import org.jetbrains.kotlin.config.KotlinResourceRootType +import org.jetbrains.kotlin.config.KotlinSourceRootType + +private val testRootTypes: Set> = setOf( + JavaSourceRootType.TEST_SOURCE, + JavaResourceRootType.TEST_RESOURCE, + KotlinSourceRootType.TestSource, + KotlinResourceRootType.TestResource +) + +fun FileIndex.isInTestSourceContentKotlinAware(fileOrDir: VirtualFile) = isUnderSourceRootOfType(fileOrDir, testRootTypes) \ No newline at end of file diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt index a48d69e1e40..7739cef497a 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt @@ -47,6 +47,7 @@ import org.jetbrains.kotlin.idea.framework.detectLibraryKind import org.jetbrains.kotlin.idea.inspections.gradle.findAll import org.jetbrains.kotlin.idea.inspections.gradle.findKotlinPluginVersion import org.jetbrains.kotlin.idea.inspections.gradle.getResolvedKotlinStdlibVersionByModuleData +import org.jetbrains.kotlin.idea.roots.migrateNonJvmSourceFolders import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData import java.io.File @@ -221,6 +222,10 @@ private fun configureFacetByGradleModule( kotlinFacet.noVersionAutoAdvance() + if (platformKind != null && platformKind !is TargetPlatformKind.Jvm) { + migrateNonJvmSourceFolders(modelsProvider.getModifiableRootModel(ideModule)) + } + return kotlinFacet } diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt.as31 b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt.as31 index 032a789dea8..ac49db4dc29 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt.as31 +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt.as31 @@ -51,6 +51,7 @@ import org.jetbrains.kotlin.idea.framework.detectLibraryKind import org.jetbrains.kotlin.idea.inspections.gradle.findAll import org.jetbrains.kotlin.idea.inspections.gradle.findKotlinPluginVersion import org.jetbrains.kotlin.idea.inspections.gradle.getResolvedKotlinStdlibVersionByModuleData +import org.jetbrains.kotlin.idea.roots.migrateNonJvmSourceFolders import org.jetbrains.kotlin.psi.UserDataProperty import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData @@ -228,6 +229,10 @@ fun configureFacetByGradleModule( kotlinFacet.noVersionAutoAdvance() + if (platformKind != null && platformKind !is TargetPlatformKind.Jvm) { + migrateNonJvmSourceFolders(modelsProvider.getModifiableRootModel(ideModule)) + } + return kotlinFacet } diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt index bf5b85f2f78..8bb9190f17d 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt @@ -25,6 +25,11 @@ import com.intellij.openapi.roots.LibraryOrderEntry import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.impl.libraries.LibraryEx +import com.intellij.openapi.util.io.FileUtil +import com.intellij.util.PathUtil +import org.jetbrains.jps.model.java.JavaResourceRootType +import org.jetbrains.jps.model.java.JavaSourceRootType +import org.jetbrains.jps.model.module.JpsModuleSourceRootType import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments @@ -50,6 +55,12 @@ internal val GradleImportingTestCase.facetSettings: KotlinFacetSettings internal val GradleImportingTestCase.testFacetSettings: KotlinFacetSettings get() = facetSettings("project_test") +internal fun GradleImportingTestCase.getSourceRootInfos(moduleName: String): List>> { + return ModuleRootManager.getInstance(getModule(moduleName)).contentEntries.flatMap { + it.sourceFolders.map { it.url.replace(projectPath, "") to it.rootType } + } +} + class GradleFacetImportTest : GradleImportingTestCase() { @Test fun testJvmImport() { @@ -114,12 +125,25 @@ class GradleFacetImportTest : GradleImportingTestCase() { } assertAllModulesConfigured() + + Assert.assertEquals( + listOf("file:///src/main/java" to JavaSourceRootType.SOURCE, + "file:///src/main/kotlin" to JavaSourceRootType.SOURCE, + "file:///src/main/resources" to JavaResourceRootType.RESOURCE), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/java" to JavaSourceRootType.TEST_SOURCE, + "file:///src/test/kotlin" to JavaSourceRootType.TEST_SOURCE, + "file:///src/test/resources" to JavaResourceRootType.TEST_RESOURCE), + getSourceRootInfos("project_test") + ) } @Test fun testJvmImportWithPlugin() { createProjectSubFile( - "build.gradle", """ + "build.gradle", """ buildscript { repositories { mavenCentral() @@ -223,6 +247,19 @@ compileTestKotlin { compilerSettings!!.additionalArguments ) } + + Assert.assertEquals( + listOf("file:///src/main/java" to JavaSourceRootType.SOURCE, + "file:///src/main/kotlin" to JavaSourceRootType.SOURCE, + "file:///src/main/resources" to JavaResourceRootType.RESOURCE), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/java" to JavaSourceRootType.TEST_SOURCE, + "file:///src/test/kotlin" to JavaSourceRootType.TEST_SOURCE, + "file:///src/test/resources" to JavaResourceRootType.TEST_RESOURCE), + getSourceRootInfos("project_test") + ) } @Test @@ -300,6 +337,19 @@ compileTestKotlin { } assertAllModulesConfigured() + + Assert.assertEquals( + listOf("file:///src/main/java" to JavaSourceRootType.SOURCE, + "file:///src/main/kotlin" to JavaSourceRootType.SOURCE, + "file:///src/main/resources" to JavaResourceRootType.RESOURCE), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/java" to JavaSourceRootType.TEST_SOURCE, + "file:///src/test/kotlin" to JavaSourceRootType.TEST_SOURCE, + "file:///src/test/resources" to JavaResourceRootType.TEST_RESOURCE), + getSourceRootInfos("project_test") + ) } @Test @@ -378,6 +428,19 @@ compileTestKotlin { compilerSettings!!.additionalArguments ) } + + Assert.assertEquals( + listOf("file:///src/main/java" to JavaSourceRootType.SOURCE, + "file:///src/main/kotlin" to JavaSourceRootType.SOURCE, + "file:///src/main/resources" to JavaResourceRootType.RESOURCE), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/java" to JavaSourceRootType.TEST_SOURCE, + "file:///src/test/kotlin" to JavaSourceRootType.TEST_SOURCE, + "file:///src/test/resources" to JavaResourceRootType.TEST_RESOURCE), + getSourceRootInfos("project_test") + ) } @Test @@ -538,6 +601,19 @@ compileTestKotlin { Assert.assertTrue(ModuleRootManager.getInstance(getModule("project_main")).sdk!!.sdkType is KotlinSdkType) Assert.assertTrue(ModuleRootManager.getInstance(getModule("project_test")).sdk!!.sdkType is KotlinSdkType) + Assert.assertEquals( + listOf("file:///src/main/java" to KotlinSourceRootType.Source, + "file:///src/main/kotlin" to KotlinSourceRootType.Source, + "file:///src/main/resources" to KotlinResourceRootType.Resource), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/java" to KotlinSourceRootType.TestSource, + "file:///src/test/kotlin" to KotlinSourceRootType.TestSource, + "file:///src/test/resources" to KotlinResourceRootType.TestResource), + getSourceRootInfos("project_test") + ) + assertAllModulesConfigured() } @@ -588,6 +664,19 @@ compileTestKotlin { assertEquals(JSLibraryKind, stdlib.kind) assertAllModulesConfigured() + + Assert.assertEquals( + listOf("file:///src/main/java" to KotlinSourceRootType.Source, + "file:///src/main/kotlin" to KotlinSourceRootType.Source, + "file:///src/main/resources" to KotlinResourceRootType.Resource), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/java" to KotlinSourceRootType.TestSource, + "file:///src/test/kotlin" to KotlinSourceRootType.TestSource, + "file:///src/test/resources" to KotlinResourceRootType.TestResource), + getSourceRootInfos("project_test") + ) } @Test @@ -671,6 +760,19 @@ compileTestKotlin { } assertAllModulesConfigured() + + Assert.assertEquals( + listOf("file:///src/main/java" to KotlinSourceRootType.Source, + "file:///src/main/kotlin" to KotlinSourceRootType.Source, + "file:///src/main/resources" to KotlinResourceRootType.Resource), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/java" to KotlinSourceRootType.TestSource, + "file:///src/test/kotlin" to KotlinSourceRootType.TestSource, + "file:///src/test/resources" to KotlinResourceRootType.TestResource), + getSourceRootInfos("project_test") + ) } @Test @@ -737,6 +839,19 @@ compileTestKotlin { Assert.assertEquals("1.1", apiLevel!!.versionString) Assert.assertEquals(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6], targetPlatformKind) } + + Assert.assertEquals( + listOf("file:///src/main/java" to JavaSourceRootType.SOURCE, + "file:///src/main/kotlin" to JavaSourceRootType.SOURCE, + "file:///src/main/resources" to JavaResourceRootType.RESOURCE), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/java" to JavaSourceRootType.TEST_SOURCE, + "file:///src/test/kotlin" to JavaSourceRootType.TEST_SOURCE, + "file:///src/test/resources" to JavaResourceRootType.TEST_RESOURCE), + getSourceRootInfos("project_test") + ) } @Test @@ -780,6 +895,19 @@ compileTestKotlin { val libraries = rootManager.orderEntries.filterIsInstance().mapNotNull { it.library as LibraryEx } assertEquals(JSLibraryKind, libraries.single { it.name?.contains("kotlin-stdlib-js") == true }.kind) assertEquals(CommonLibraryKind, libraries.single { it.name?.contains("kotlin-stdlib-common") == true }.kind) + + Assert.assertEquals( + listOf("file:///src/main/java" to KotlinSourceRootType.Source, + "file:///src/main/kotlin" to KotlinSourceRootType.Source, + "file:///src/main/resources" to KotlinResourceRootType.Resource), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/java" to KotlinSourceRootType.TestSource, + "file:///src/test/kotlin" to KotlinSourceRootType.TestSource, + "file:///src/test/resources" to KotlinResourceRootType.TestResource), + getSourceRootInfos("project_test") + ) } @Test @@ -825,6 +953,19 @@ compileTestKotlin { val rootManager = ModuleRootManager.getInstance(getModule("project_main")) val stdlib = rootManager.orderEntries.filterIsInstance().single().library assertEquals(CommonLibraryKind, (stdlib as LibraryEx).kind) + + Assert.assertEquals( + listOf("file:///src/main/java" to KotlinSourceRootType.Source, + "file:///src/main/kotlin" to KotlinSourceRootType.Source, + "file:///src/main/resources" to KotlinResourceRootType.Resource), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/java" to KotlinSourceRootType.TestSource, + "file:///src/test/kotlin" to KotlinSourceRootType.TestSource, + "file:///src/test/resources" to KotlinResourceRootType.TestResource), + getSourceRootInfos("project_test") + ) } @Test @@ -869,6 +1010,16 @@ compileTestKotlin { val rootManager = ModuleRootManager.getInstance(getModule("project")) val stdlib = rootManager.orderEntries.filterIsInstance().mapTo(HashSet()) { it.library }.single() assertEquals(CommonLibraryKind, (stdlib as LibraryEx).kind) + + Assert.assertEquals( + listOf("file:///src/main/java" to KotlinSourceRootType.Source, + "file:///src/main/kotlin" to KotlinSourceRootType.Source, + "file:///src/test/java" to KotlinSourceRootType.TestSource, + "file:///src/test/kotlin" to KotlinSourceRootType.TestSource, + "file:///src/main/resources" to KotlinResourceRootType.Resource, + "file:///src/test/resources" to KotlinResourceRootType.TestResource), + getSourceRootInfos("project") + ) } @Test @@ -901,6 +1052,19 @@ compileTestKotlin { Assert.assertEquals("1.1", apiLevel!!.versionString) Assert.assertEquals(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6], targetPlatformKind) } + + Assert.assertEquals( + listOf("file:///src/main/java" to JavaSourceRootType.SOURCE, + "file:///src/main/kotlin" to JavaSourceRootType.SOURCE, + "file:///src/main/resources" to JavaResourceRootType.RESOURCE), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/java" to JavaSourceRootType.TEST_SOURCE, + "file:///src/test/kotlin" to JavaSourceRootType.TEST_SOURCE, + "file:///src/test/resources" to JavaResourceRootType.TEST_RESOURCE), + getSourceRootInfos("project_test") + ) } @Test @@ -933,6 +1097,19 @@ compileTestKotlin { Assert.assertEquals("1.1", apiLevel!!.versionString) Assert.assertEquals(TargetPlatformKind.JavaScript, targetPlatformKind) } + + Assert.assertEquals( + listOf("file:///src/main/java" to KotlinSourceRootType.Source, + "file:///src/main/kotlin" to KotlinSourceRootType.Source, + "file:///src/main/resources" to KotlinResourceRootType.Resource), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/java" to KotlinSourceRootType.TestSource, + "file:///src/test/kotlin" to KotlinSourceRootType.TestSource, + "file:///src/test/resources" to KotlinResourceRootType.TestResource), + getSourceRootInfos("project_test") + ) } @Test @@ -1889,6 +2066,17 @@ compileTestKotlin { Assert.assertTrue(ModuleRootManager.getInstance(getModule("project_main")).sdk!!.sdkType is KotlinSdkType) Assert.assertTrue(ModuleRootManager.getInstance(getModule("project_test")).sdk!!.sdkType is KotlinSdkType) + + Assert.assertEquals( + listOf("file:///src/main/kotlin" to KotlinSourceRootType.Source, + "file:///src/main/resources" to KotlinResourceRootType.Resource), + getSourceRootInfos("project_main") + ) + Assert.assertEquals( + listOf("file:///src/test/kotlin" to KotlinSourceRootType.TestSource, + "file:///src/test/resources" to KotlinResourceRootType.TestResource), + getSourceRootInfos("project_test") + ) } private fun assertAllModulesConfigured() { diff --git a/idea/idea-jps-common/build.gradle.kts b/idea/idea-jps-common/build.gradle.kts index d8b043d5136..469913e8e29 100644 --- a/idea/idea-jps-common/build.gradle.kts +++ b/idea/idea-jps-common/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { compile(project(":compiler:cli-common")) compile(project(":compiler:frontend.java")) compileOnly(intellijDep()) + compileOnly(intellijDep("jps-standalone")) { includeJars("jps-model") } } sourceSets { diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinCommonJpsModelSerializerExtension.java b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinCommonJpsModelSerializerExtension.java new file mode 100644 index 00000000000..f421a872dc5 --- /dev/null +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinCommonJpsModelSerializerExtension.java @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.config; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; +import org.jetbrains.jps.model.serialization.module.JpsModuleSourceRootPropertiesSerializer; + +import java.util.Arrays; +import java.util.List; + +public class KotlinCommonJpsModelSerializerExtension extends JpsModelSerializerExtension { + @NotNull + @Override + public List> getModuleSourceRootPropertiesSerializers() { + return Arrays.asList( + KotlinSourceRootPropertiesSerializer.Source.INSTANCE, + KotlinSourceRootPropertiesSerializer.TestSource.INSTANCE, + KotlinResourceRootPropertiesSerializer.Resource.INSTANCE, + KotlinResourceRootPropertiesSerializer.TestResource.INSTANCE + ); + } +} \ No newline at end of file diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinResourceRootType.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinResourceRootType.kt new file mode 100644 index 00000000000..757957c14df --- /dev/null +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinResourceRootType.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.config + +import org.jetbrains.jps.model.ex.JpsElementTypeBase +import org.jetbrains.jps.model.java.JavaResourceRootProperties +import org.jetbrains.jps.model.java.JpsJavaExtensionService +import org.jetbrains.jps.model.module.JpsModuleSourceRootType + +sealed class KotlinResourceRootType : JpsElementTypeBase(), + JpsModuleSourceRootType { + object Resource : KotlinResourceRootType() + object TestResource : KotlinResourceRootType() + + override fun createDefaultProperties() = + JpsJavaExtensionService.getInstance().createResourceRootProperties("", false) +} \ No newline at end of file diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinSourceRootType.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinSourceRootType.kt new file mode 100644 index 00000000000..680ffeaa67c --- /dev/null +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinSourceRootType.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.config + +import org.jetbrains.jps.model.ex.JpsElementTypeBase +import org.jetbrains.jps.model.java.JavaSourceRootProperties +import org.jetbrains.jps.model.java.JpsJavaExtensionService +import org.jetbrains.jps.model.module.JpsModuleSourceRootType + +sealed class KotlinSourceRootType : JpsElementTypeBase(), JpsModuleSourceRootType { + object Source : KotlinSourceRootType() + object TestSource : KotlinSourceRootType() + + override fun createDefaultProperties() = JpsJavaExtensionService.getInstance().createSourceRootProperties("") +} + diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/moduleSourceRootPropertiesSerializers.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/moduleSourceRootPropertiesSerializers.kt new file mode 100644 index 00000000000..77d487c457d --- /dev/null +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/moduleSourceRootPropertiesSerializers.kt @@ -0,0 +1,85 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.config + +import org.jdom.Element +import org.jetbrains.jps.model.java.JavaResourceRootProperties +import org.jetbrains.jps.model.java.JavaSourceRootProperties +import org.jetbrains.jps.model.java.JpsJavaExtensionService +import org.jetbrains.jps.model.module.JpsModuleSourceRootType +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer +import org.jetbrains.jps.model.serialization.module.JpsModuleSourceRootPropertiesSerializer + +private val IS_GENERATED_ATTRIBUTE = "generated" +private val RELATIVE_OUTPUT_PATH_ATTRIBUTE = "relativeOutputPath" + +val KOTLIN_SOURCE_ROOT_TYPE_ID = "kotlin-source" +val KOTLIN_TEST_ROOT_TYPE_ID = "kotlin-test" +val KOTLIN_RESOURCE_ROOT_TYPE_ID = "kotlin-resource" +val KOTLIN_TEST_RESOURCE_ROOT_TYPE_ID = "kotlin-test-resource" + +// Based on org.jetbrains.jps.model.serialization.java.JpsJavaModelSerializerExtension.JavaSourceRootPropertiesSerializer class +sealed class KotlinSourceRootPropertiesSerializer( + type: JpsModuleSourceRootType, + typeId: String +) : JpsModuleSourceRootPropertiesSerializer(type, typeId) { + object Source : KotlinSourceRootPropertiesSerializer( + KotlinSourceRootType.Source, + KOTLIN_SOURCE_ROOT_TYPE_ID + ) + + object TestSource : KotlinSourceRootPropertiesSerializer( + KotlinSourceRootType.TestSource, + KOTLIN_TEST_ROOT_TYPE_ID + ) + + override fun loadProperties(sourceRootTag: Element): JavaSourceRootProperties { + val packagePrefix = sourceRootTag.getAttributeValue(JpsModuleRootModelSerializer.PACKAGE_PREFIX_ATTRIBUTE) ?: "" + val isGenerated = sourceRootTag.getAttributeValue(IS_GENERATED_ATTRIBUTE)?.toBoolean() ?: false + return JpsJavaExtensionService.getInstance().createSourceRootProperties(packagePrefix, isGenerated) + } + + override fun saveProperties(properties: JavaSourceRootProperties, sourceRootTag: Element) { + val packagePrefix = properties.packagePrefix + if (packagePrefix.isNotEmpty()) { + sourceRootTag.setAttribute(JpsModuleRootModelSerializer.PACKAGE_PREFIX_ATTRIBUTE, packagePrefix) + } + if (properties.isForGeneratedSources) { + sourceRootTag.setAttribute(IS_GENERATED_ATTRIBUTE, "true") + } + } +} + +// Based on org.jetbrains.jps.model.serialization.java.JpsJavaModelSerializerExtension.JavaResourceRootPropertiesSerializer +sealed class KotlinResourceRootPropertiesSerializer( + type: JpsModuleSourceRootType, + typeId: String +) : JpsModuleSourceRootPropertiesSerializer(type, typeId) { + object Resource : KotlinResourceRootPropertiesSerializer( + KotlinResourceRootType.Resource, + KOTLIN_RESOURCE_ROOT_TYPE_ID + ) + object TestResource : KotlinResourceRootPropertiesSerializer( + KotlinResourceRootType.TestResource, + KOTLIN_TEST_RESOURCE_ROOT_TYPE_ID + ) + + override fun loadProperties(sourceRootTag: Element): JavaResourceRootProperties { + val relativeOutputPath = sourceRootTag.getAttributeValue(RELATIVE_OUTPUT_PATH_ATTRIBUTE) ?: "" + val isGenerated = sourceRootTag.getAttributeValue(IS_GENERATED_ATTRIBUTE)?.toBoolean() ?: false + return JpsJavaExtensionService.getInstance().createResourceRootProperties(relativeOutputPath, isGenerated) + } + + override fun saveProperties(properties: JavaResourceRootProperties, sourceRootTag: Element) { + val relativeOutputPath = properties.relativeOutputPath + if (relativeOutputPath.isNotEmpty()) { + sourceRootTag.setAttribute(RELATIVE_OUTPUT_PATH_ATTRIBUTE, relativeOutputPath) + } + if (properties.isForGeneratedSources) { + sourceRootTag.setAttribute(IS_GENERATED_ATTRIBUTE, "true") + } + } +} \ No newline at end of file diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/coverage/KotlinCoverageExtension.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/coverage/KotlinCoverageExtension.kt index 8e898872e31..9bf72f8141e 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/coverage/KotlinCoverageExtension.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/coverage/KotlinCoverageExtension.kt @@ -33,6 +33,7 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiFile import com.intellij.psi.PsiNamedElement import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil +import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware import org.jetbrains.kotlin.idea.run.KotlinRunConfiguration import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.psi.KtClassOrObject @@ -152,7 +153,7 @@ class KotlinCoverageExtension : JavaCoverageEngineExtension() { val module = ModuleUtilCore.findModuleForPsiElement(file) if (module == null) return null val fileIndex = ProjectRootManager.getInstance(file.project).fileIndex - val inTests = fileIndex.isInTestSourceContent(file.virtualFile) + val inTests = fileIndex.isInTestSourceContentKotlinAware(file.virtualFile) val compilerOutputExtension = CompilerModuleExtension.getInstance(module) return if (inTests) compilerOutputExtension!!.compilerOutputPathForTests diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/framework/KotlinModuleBuilder.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/framework/KotlinModuleBuilder.kt index 39ddc881f21..671bef03322 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/framework/KotlinModuleBuilder.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/framework/KotlinModuleBuilder.kt @@ -21,7 +21,9 @@ import com.intellij.ide.util.projectWizard.ModuleWizardStep import com.intellij.ide.util.projectWizard.SettingsStep import com.intellij.ide.util.projectWizard.WizardContext import com.intellij.openapi.projectRoots.SdkTypeId +import com.intellij.openapi.roots.ModifiableRootModel import com.intellij.openapi.roots.ui.configuration.ModulesProvider +import org.jetbrains.kotlin.idea.roots.migrateNonJvmSourceFolders import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import javax.swing.Icon @@ -45,4 +47,11 @@ class KotlinModuleBuilder( is JvmPlatform -> super.isSuitableSdkType(sdkType) else -> sdkType is KotlinSdkType } + + override fun setupRootModel(rootModel: ModifiableRootModel) { + super.setupRootModel(rootModel) + if (targetPlatform !is JvmPlatform) { + migrateNonJvmSourceFolders(rootModel) + } + } } diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt index 230e6d16347..5a7a802539a 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgu import org.jetbrains.kotlin.idea.configuration.BuildSystemType import org.jetbrains.kotlin.idea.configuration.findApplicableConfigurator import org.jetbrains.kotlin.idea.configuration.getBuildSystemType +import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware import org.jetbrains.kotlin.idea.facet.KotlinFacet import org.jetbrains.kotlin.idea.facet.getRuntimeLibraryVersion import org.jetbrains.kotlin.idea.util.projectStructure.allModules @@ -54,7 +55,7 @@ sealed class EnableUnsupportedFeatureFix( else null } - val forTests = ModuleRootManager.getInstance(module).fileIndex.isInTestSourceContent(file.virtualFile) + val forTests = ModuleRootManager.getInstance(module).fileIndex.isInTestSourceContentKotlinAware(file.virtualFile) findApplicableConfigurator(module).updateLanguageVersion( module, diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/run/KotlinRunConfiguration.java b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/run/KotlinRunConfiguration.java index 0381b90bfbc..20074000e9b 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/run/KotlinRunConfiguration.java +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/run/KotlinRunConfiguration.java @@ -55,6 +55,7 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration; import org.jetbrains.kotlin.asJava.elements.KtLightMethod; import org.jetbrains.kotlin.idea.MainFunctionDetector; import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils; +import org.jetbrains.kotlin.idea.core.FileIndexUtilsKt; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.KtDeclaration; import org.jetbrains.kotlin.psi.KtDeclarationContainer; @@ -367,7 +368,7 @@ public class KotlinRunConfiguration extends JetRunConfiguration { ModuleFileIndex fileIndex = ModuleRootManager.getInstance(classModule).getFileIndex(); if (fileIndex.isInSourceContent(virtualFileForMainFun)) { - if (fileIndex.isInTestSourceContent(virtualFileForMainFun)) { + if (FileIndexUtilsKt.isInTestSourceContentKotlinAware(fileIndex, virtualFileForMainFun)) { return JavaParameters.JDK_AND_CLASSES_AND_TESTS; } else { diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt index e7c9f67481f..6fc58d0388e 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt @@ -29,6 +29,7 @@ import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.impl.libraries.LibraryEx import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.util.AsyncResult +import com.intellij.util.PairConsumer import com.intellij.util.PathUtil import org.jdom.Element import org.jdom.Text @@ -49,6 +50,7 @@ import org.jetbrains.kotlin.idea.facet.* import org.jetbrains.kotlin.idea.framework.detectLibraryKind import org.jetbrains.kotlin.idea.framework.libraryKind import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator +import org.jetbrains.kotlin.idea.project.targetPlatform import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.addIfNotNull import java.io.File @@ -314,17 +316,35 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ val toBeAdded = directories.map { it.second }.toSet() val state = module.kotlinImporterComponent + val isNonJvmModule = mavenProject + .plugins + .asSequence() + .filter { it.isKotlinPlugin() } + .flatMap { it.executions.asSequence() } + .flatMap { it.goals.asSequence() } + .any { it !in PomFile.KotlinGoals.JvmGoals } + + val prodSourceRootType: JpsModuleSourceRootType<*> = if (isNonJvmModule) KotlinSourceRootType.Source else JavaSourceRootType.SOURCE + val testSourceRootType: JpsModuleSourceRootType<*> = if (isNonJvmModule) KotlinSourceRootType.TestSource else JavaSourceRootType.TEST_SOURCE + for ((type, dir) in directories) { if (rootModel.getSourceFolder(File(dir)) == null) { val jpsType: JpsModuleSourceRootType<*> = when (type) { - SourceType.TEST -> JavaSourceRootType.TEST_SOURCE - SourceType.PROD -> JavaSourceRootType.SOURCE + SourceType.TEST -> testSourceRootType + SourceType.PROD -> prodSourceRootType } rootModel.addSourceFolder(dir, jpsType) } } + if (isNonJvmModule) { + mavenProject.sources.forEach { rootModel.addSourceFolder(it, KotlinSourceRootType.Source) } + mavenProject.testSources.forEach { rootModel.addSourceFolder(it, KotlinSourceRootType.TestSource) } + mavenProject.resources.forEach { rootModel.addSourceFolder(it.directory, KotlinResourceRootType.Resource) } + mavenProject.testResources.forEach { rootModel.addSourceFolder(it.directory, KotlinResourceRootType.TestResource) } + } + state.addedSources.filter { it !in toBeAdded }.forEach { rootModel.unregisterAll(it, true, true) state.addedSources.remove(it) diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt.173 b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt.173 index f2b1fd00f76..428fc0bef98 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt.173 +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt.173 @@ -29,6 +29,7 @@ import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.impl.libraries.LibraryEx import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.util.AsyncResult +import com.intellij.util.PairConsumer import com.intellij.util.PathUtil import org.jdom.Element import org.jdom.Text @@ -49,6 +50,7 @@ import org.jetbrains.kotlin.idea.facet.* import org.jetbrains.kotlin.idea.framework.detectLibraryKind import org.jetbrains.kotlin.idea.framework.libraryKind import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator +import org.jetbrains.kotlin.idea.project.targetPlatform import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.addIfNotNull import java.io.File @@ -314,17 +316,35 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ val toBeAdded = directories.map { it.second }.toSet() val state = module.kotlinImporterComponent + val isNonJvmModule = mavenProject + .plugins + .asSequence() + .filter { it.isKotlinPlugin() } + .flatMap { it.executions.asSequence() } + .flatMap { it.goals.asSequence() } + .any { it !in PomFile.KotlinGoals.JvmGoals } + + val prodSourceRootType: JpsModuleSourceRootType<*> = if (isNonJvmModule) KotlinSourceRootType.Source else JavaSourceRootType.SOURCE + val testSourceRootType: JpsModuleSourceRootType<*> = if (isNonJvmModule) KotlinSourceRootType.TestSource else JavaSourceRootType.TEST_SOURCE + for ((type, dir) in directories) { if (rootModel.getSourceFolder(File(dir)) == null) { val jpsType: JpsModuleSourceRootType<*> = when (type) { - SourceType.TEST -> JavaSourceRootType.TEST_SOURCE - SourceType.PROD -> JavaSourceRootType.SOURCE + SourceType.TEST -> testSourceRootType + SourceType.PROD -> prodSourceRootType } rootModel.addSourceFolder(dir, jpsType) } } + if (isNonJvmModule) { + mavenProject.sources.forEach { rootModel.addSourceFolder(it, KotlinSourceRootType.Source) } + mavenProject.testSources.forEach { rootModel.addSourceFolder(it, KotlinSourceRootType.TestSource) } + mavenProject.resources.forEach { rootModel.addSourceFolder(it.directory, KotlinResourceRootType.Resource) } + mavenProject.testResources.forEach { rootModel.addSourceFolder(it.directory, KotlinResourceRootType.TestResource) } + } + state.addedSources.filter { it !in toBeAdded }.forEach { rootModel.unregisterAll(it, true, true) state.addedSources.remove(it) diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/PomFile.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/PomFile.kt index 7f2aacd98cb..8e9845e0c02 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/PomFile.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/PomFile.kt @@ -39,6 +39,7 @@ import org.jetbrains.idea.maven.project.MavenProject import org.jetbrains.idea.maven.project.MavenProjectsManager import org.jetbrains.idea.maven.utils.MavenArtifactScope import org.jetbrains.jps.model.java.JavaSourceRootType +import org.jetbrains.kotlin.config.KotlinSourceRootType import org.jetbrains.kotlin.idea.configuration.RepositoryDescription import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType @@ -506,12 +507,11 @@ class PomFile private constructor(private val xmlFile: XmlFile, val domModel: Ma private fun GenericDomValue.isEmpty() = !exists() || stringValue.isNullOrEmpty() private fun SourceFolder.isRelatedSourceRoot(isTest: Boolean): Boolean { - val relevantRootType = when { - isTest -> JavaSourceRootType.TEST_SOURCE - else -> JavaSourceRootType.SOURCE + return if (isTest) { + rootType == JavaSourceRootType.TEST_SOURCE || rootType == KotlinSourceRootType.TestSource + } else { + rootType == JavaSourceRootType.SOURCE || rootType == KotlinSourceRootType.Source } - - return rootType === relevantRootType } @Suppress("Unused") @@ -548,6 +548,8 @@ class PomFile private constructor(private val xmlFile: XmlFile, val domModel: Ma const val Js = "js" const val TestJs = "test-js" const val MetaData = "metadata" + + val JvmGoals = listOf(Compile, TestCompile) } companion object { diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/inspections/KotlinMavenUnresolvedReferenceQuickFixProvider.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/inspections/KotlinMavenUnresolvedReferenceQuickFixProvider.kt index d3f4fc2c331..677eddd6598 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/inspections/KotlinMavenUnresolvedReferenceQuickFixProvider.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/inspections/KotlinMavenUnresolvedReferenceQuickFixProvider.kt @@ -32,6 +32,7 @@ import org.jetbrains.idea.maven.dom.MavenDomUtil import org.jetbrains.idea.maven.indices.MavenArtifactSearchDialog import org.jetbrains.idea.maven.project.MavenProjectsManager import org.jetbrains.idea.maven.utils.MavenArtifactScope +import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware import org.jetbrains.kotlin.idea.maven.PomFile import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.idea.util.application.runWriteAction @@ -100,7 +101,7 @@ class AddMavenDependencyQuickFix( if (ids.isEmpty()) return runWriteAction { - val isTestSource = ProjectRootManager.getInstance(project).fileIndex.isInTestSourceContent(virtualFile) + val isTestSource = ProjectRootManager.getInstance(project).fileIndex.isInTestSourceContentKotlinAware(virtualFile) val scope = if (isTestSource) MavenArtifactScope.TEST else null PomFile.forFileOrNull(xmlFile)?.let { pom -> diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenInspectionTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenInspectionTest.kt index 17fe0277790..e9af9635f3e 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenInspectionTest.kt +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenInspectionTest.kt @@ -30,6 +30,7 @@ import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiManager import com.intellij.psi.search.FileTypeIndex import org.jetbrains.jps.model.java.JavaSourceRootType +import org.jetbrains.kotlin.config.KotlinSourceRootType import org.jetbrains.kotlin.idea.inspections.runInspection import org.jetbrains.kotlin.idea.maven.inspections.KotlinMavenPluginPhaseInspection import org.jetbrains.kotlin.idea.refactoring.toPsiDirectory @@ -177,10 +178,12 @@ abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() { } private fun mkJavaFile() { + val contentEntry = getContentRoots(myProject.allModules().single().name).single() val sourceFolder = - getContentRoots(myProject.allModules().single().name).single().getSourceFolders(JavaSourceRootType.SOURCE).single() + contentEntry.getSourceFolders(JavaSourceRootType.SOURCE).singleOrNull() ?: + contentEntry.getSourceFolders(KotlinSourceRootType.Source).singleOrNull() ApplicationManager.getApplication().runWriteAction { - val javaFile = sourceFolder.file?.toPsiDirectory(myProject)?.createFile("Test.java") ?: throw IllegalStateException() + val javaFile = sourceFolder?.file?.toPsiDirectory(myProject)?.createFile("Test.java") ?: throw IllegalStateException() javaFile.viewProvider.document!!.setText("class Test {}\n") } diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt index d7d7bb20a90..588e0d9b019 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt @@ -26,6 +26,8 @@ import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.impl.libraries.LibraryEx import com.intellij.util.PathUtil import junit.framework.TestCase +import org.jetbrains.jps.model.java.JavaResourceRootType +import org.jetbrains.jps.model.java.JavaSourceRootType import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.config.* @@ -490,6 +492,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { compilerSettings!!.additionalArguments ) } + + assertContentFolders("project", JavaSourceRootType.SOURCE, "src/main/kotlin") + assertContentFolders("project", JavaSourceRootType.TEST_SOURCE, "src/test/java") + assertContentFolders("project", JavaResourceRootType.RESOURCE, "src/main/resources") + assertContentFolders("project", JavaResourceRootType.TEST_RESOURCE, "src/test/resources") } fun testJavaParameters() { @@ -601,6 +608,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { Assert.assertEquals("JVM 1.8", targetPlatformKind!!.description) Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget) } + + assertContentFolders("project", JavaSourceRootType.SOURCE, "src/main/kotlin") + assertContentFolders("project", JavaSourceRootType.TEST_SOURCE, "src/test/java") + assertContentFolders("project", JavaResourceRootType.RESOURCE, "src/main/resources") + assertContentFolders("project", JavaResourceRootType.TEST_RESOURCE, "src/test/resources") } fun testJsFacetConfiguration() { @@ -684,6 +696,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { assertEquals(JSLibraryKind, (stdlib as LibraryEx).kind) Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType) + + assertContentFolders("project", KotlinSourceRootType.Source, "src/main/kotlin") + assertContentFolders("project", KotlinSourceRootType.TestSource, "src/test/java") + assertContentFolders("project", KotlinResourceRootType.Resource, "src/main/resources") + assertContentFolders("project", KotlinResourceRootType.TestResource, "src/test/resources") } fun testJsCustomOutputPaths() { @@ -989,6 +1006,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { assertImporterStatePresent() Assert.assertEquals(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6], facetSettings.targetPlatformKind) + + assertContentFolders("project", JavaSourceRootType.SOURCE, "src/main/kotlin") + assertContentFolders("project", JavaSourceRootType.TEST_SOURCE, "src/test/java") + assertContentFolders("project", JavaResourceRootType.RESOURCE, "src/main/resources") + assertContentFolders("project", JavaResourceRootType.TEST_RESOURCE, "src/test/resources") } fun testJvmDetectionByGoalWithJsStdlib() { @@ -1089,6 +1111,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { assertImporterStatePresent() Assert.assertEquals(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6], facetSettings.targetPlatformKind) + + assertContentFolders("project", JavaSourceRootType.SOURCE, "src/main/kotlin") + assertContentFolders("project", JavaSourceRootType.TEST_SOURCE, "src/test/java") + assertContentFolders("project", JavaResourceRootType.RESOURCE, "src/main/resources") + assertContentFolders("project", JavaResourceRootType.TEST_RESOURCE, "src/test/resources") } fun testJsDetectionByGoalWithJvmStdlib() { @@ -1141,6 +1168,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind) Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType) + + assertContentFolders("project", KotlinSourceRootType.Source, "src/main/kotlin") + assertContentFolders("project", KotlinSourceRootType.TestSource, "src/test/java") + assertContentFolders("project", KotlinResourceRootType.Resource, "src/main/resources") + assertContentFolders("project", KotlinResourceRootType.TestResource, "src/test/resources") } fun testJsDetectionByGoalWithJsStdlib() { @@ -1193,6 +1225,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind) Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType) + + assertContentFolders("project", KotlinSourceRootType.Source, "src/main/kotlin") + assertContentFolders("project", KotlinSourceRootType.TestSource, "src/test/java") + assertContentFolders("project", KotlinResourceRootType.Resource, "src/main/resources") + assertContentFolders("project", KotlinResourceRootType.TestResource, "src/test/resources") } fun testJsDetectionByGoalWithCommonStdlib() { @@ -1245,6 +1282,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind) Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType) + + assertContentFolders("project", KotlinSourceRootType.Source, "src/main/kotlin") + assertContentFolders("project", KotlinSourceRootType.TestSource, "src/test/java") + assertContentFolders("project", KotlinResourceRootType.Resource, "src/main/resources") + assertContentFolders("project", KotlinResourceRootType.TestResource, "src/test/resources") } fun testJsAndCommonStdlibKinds() { @@ -1305,6 +1347,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { val libraries = rootManager.orderEntries.filterIsInstance().map { it.library as LibraryEx } assertEquals(JSLibraryKind, libraries.single { it.name?.contains("kotlin-stdlib-js") == true }.kind) assertEquals(CommonLibraryKind, libraries.single { it.name?.contains("kotlin-stdlib-common") == true }.kind) + + assertContentFolders("project", KotlinSourceRootType.Source, "src/main/kotlin") + assertContentFolders("project", KotlinSourceRootType.TestSource, "src/test/java") + assertContentFolders("project", KotlinResourceRootType.Resource, "src/main/resources") + assertContentFolders("project", KotlinResourceRootType.TestResource, "src/test/resources") } fun testCommonDetectionByGoalWithJvmStdlib() { @@ -1351,6 +1398,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { Assert.assertEquals(TargetPlatformKind.Common, facetSettings.targetPlatformKind) Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType) + + assertContentFolders("project", KotlinSourceRootType.Source, "src/main/kotlin") + assertContentFolders("project", KotlinSourceRootType.TestSource, "src/test/java") + assertContentFolders("project", KotlinResourceRootType.Resource, "src/main/resources") + assertContentFolders("project", KotlinResourceRootType.TestResource, "src/test/resources") } fun testCommonDetectionByGoalWithJsStdlib() { @@ -1397,6 +1449,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { Assert.assertEquals(TargetPlatformKind.Common, facetSettings.targetPlatformKind) Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType) + + assertContentFolders("project", KotlinSourceRootType.Source, "src/main/kotlin") + assertContentFolders("project", KotlinSourceRootType.TestSource, "src/test/java") + assertContentFolders("project", KotlinResourceRootType.Resource, "src/main/resources") + assertContentFolders("project", KotlinResourceRootType.TestResource, "src/test/resources") } fun testCommonDetectionByGoalWithCommonStdlib() { @@ -1447,6 +1504,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { assertEquals(CommonLibraryKind, (stdlib as LibraryEx).kind) Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType) + + assertContentFolders("project", KotlinSourceRootType.Source, "src/main/kotlin") + assertContentFolders("project", KotlinSourceRootType.TestSource, "src/test/java") + assertContentFolders("project", KotlinResourceRootType.Resource, "src/main/resources") + assertContentFolders("project", KotlinResourceRootType.TestResource, "src/test/resources") } fun testJvmDetectionByConflictingGoalsAndJvmStdlib() { @@ -1497,6 +1559,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { assertImporterStatePresent() Assert.assertEquals(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6], facetSettings.targetPlatformKind) + + assertContentFolders("project", KotlinSourceRootType.Source, "src/main/kotlin") + assertContentFolders("project", KotlinSourceRootType.TestSource, "src/test/java") + assertContentFolders("project", KotlinResourceRootType.Resource, "src/main/resources") + assertContentFolders("project", KotlinResourceRootType.TestResource, "src/test/resources") } fun testJsDetectionByConflictingGoalsAndJsStdlib() { @@ -1547,6 +1614,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { assertImporterStatePresent() Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind) + + assertContentFolders("project", KotlinSourceRootType.Source, "src/main/kotlin") + assertContentFolders("project", KotlinSourceRootType.TestSource, "src/test/java") + assertContentFolders("project", KotlinResourceRootType.Resource, "src/main/resources") + assertContentFolders("project", KotlinResourceRootType.TestResource, "src/test/resources") } fun testCommonDetectionByConflictingGoalsAndCommonStdlib() { @@ -1597,6 +1669,11 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { assertImporterStatePresent() Assert.assertEquals(TargetPlatformKind.Common, facetSettings.targetPlatformKind) + + assertContentFolders("project", KotlinSourceRootType.Source, "src/main/kotlin") + assertContentFolders("project", KotlinSourceRootType.TestSource, "src/test/java") + assertContentFolders("project", KotlinResourceRootType.Resource, "src/main/resources") + assertContentFolders("project", KotlinResourceRootType.TestResource, "src/test/resources") } fun testNoPluginsInAdditionalArgs() { diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenImportingTestCase.java b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenImportingTestCase.java index 7350f2228db..6debfc30aa9 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenImportingTestCase.java +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenImportingTestCase.java @@ -121,7 +121,7 @@ public abstract class MavenImportingTestCase extends MavenTestCase { } protected void assertSources(String moduleName, String... expectedSources) { - doAssertContentFolders(moduleName, JavaSourceRootType.SOURCE, expectedSources); + assertContentFolders(moduleName, JavaSourceRootType.SOURCE, expectedSources); } protected void assertGeneratedSources(String moduleName, String... expectedSources) { @@ -138,15 +138,15 @@ public abstract class MavenImportingTestCase extends MavenTestCase { } protected void assertResources(String moduleName, String... expectedSources) { - doAssertContentFolders(moduleName, JavaResourceRootType.RESOURCE, expectedSources); + assertContentFolders(moduleName, JavaResourceRootType.RESOURCE, expectedSources); } protected void assertTestSources(String moduleName, String... expectedSources) { - doAssertContentFolders(moduleName, JavaSourceRootType.TEST_SOURCE, expectedSources); + assertContentFolders(moduleName, JavaSourceRootType.TEST_SOURCE, expectedSources); } protected void assertTestResources(String moduleName, String... expectedSources) { - doAssertContentFolders(moduleName, JavaResourceRootType.TEST_RESOURCE, expectedSources); + assertContentFolders(moduleName, JavaResourceRootType.TEST_RESOURCE, expectedSources); } protected void assertExcludes(String moduleName, String... expectedExcludes) { @@ -159,7 +159,7 @@ public abstract class MavenImportingTestCase extends MavenTestCase { doAssertContentFolders(root, Arrays.asList(root.getExcludeFolders()), expectedExcudes); } - private void doAssertContentFolders(String moduleName, @NotNull JpsModuleSourceRootType rootType, String... expected) { + protected void assertContentFolders(String moduleName, @NotNull JpsModuleSourceRootType rootType, String... expected) { ContentEntry contentRoot = getContentRoot(moduleName); doAssertContentFolders(contentRoot, contentRoot.getSourceFolders(rootType), expected); } diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 2aeb0bba032..a609be49e03 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -817,6 +817,13 @@ + + + + + + + org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisIntention Kotlin diff --git a/idea/src/META-INF/plugin.xml.172 b/idea/src/META-INF/plugin.xml.172 index 908c4ac8b9b..b080fc933e1 100644 --- a/idea/src/META-INF/plugin.xml.172 +++ b/idea/src/META-INF/plugin.xml.172 @@ -817,6 +817,13 @@ + + + + + + + org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisIntention Kotlin diff --git a/idea/src/META-INF/plugin.xml.173 b/idea/src/META-INF/plugin.xml.173 index 7ec614803c8..5347e06f10e 100644 --- a/idea/src/META-INF/plugin.xml.173 +++ b/idea/src/META-INF/plugin.xml.173 @@ -817,6 +817,13 @@ + + + + + + + org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisIntention Kotlin diff --git a/idea/src/META-INF/plugin.xml.182 b/idea/src/META-INF/plugin.xml.182 index e3c37e65634..0b4a36feea1 100644 --- a/idea/src/META-INF/plugin.xml.182 +++ b/idea/src/META-INF/plugin.xml.182 @@ -818,6 +818,13 @@ + + + + + + + org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisIntention Kotlin diff --git a/idea/src/META-INF/plugin.xml.as31 b/idea/src/META-INF/plugin.xml.as31 index f3ed228e07b..990c654f37f 100644 --- a/idea/src/META-INF/plugin.xml.as31 +++ b/idea/src/META-INF/plugin.xml.as31 @@ -817,6 +817,13 @@ + + + + + + + org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisIntention Kotlin diff --git a/idea/src/META-INF/plugin.xml.as32 b/idea/src/META-INF/plugin.xml.as32 index 85bc38ec488..fa030a8cf8f 100644 --- a/idea/src/META-INF/plugin.xml.as32 +++ b/idea/src/META-INF/plugin.xml.as32 @@ -817,6 +817,13 @@ + + + + + + + org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisIntention Kotlin diff --git a/idea/src/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelSerializerExtension b/idea/src/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelSerializerExtension new file mode 100644 index 00000000000..986ad37d92b --- /dev/null +++ b/idea/src/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelSerializerExtension @@ -0,0 +1 @@ +org.jetbrains.kotlin.config.KotlinCommonJpsModelSerializerExtension \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt index 4ea094ac94f..bb1e554d44a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt @@ -46,6 +46,7 @@ import org.jetbrains.kotlin.idea.caches.project.moduleInfo import org.jetbrains.kotlin.idea.caches.resolve.* import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMemberDescriptor import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde +import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.project.TargetPlatformDetector import org.jetbrains.kotlin.idea.refactoring.getUsageContext @@ -201,7 +202,7 @@ class MoveConflictChecker( conflicts: MultiMap) { val targetModule = targetScope.getModule(project) ?: return - val isInTestSources = ModuleRootManager.getInstance(targetModule).fileIndex.isInTestSourceContent(targetScope) + val isInTestSources = ModuleRootManager.getInstance(targetModule).fileIndex.isInTestSourceContentKotlinAware(targetScope) NextUsage@ for (usage in usages) { val element = usage.element ?: continue if (PsiTreeUtil.getParentOfType(element, PsiImportStatement::class.java, false) != null) continue diff --git a/idea/src/org/jetbrains/kotlin/idea/roots/projectRootUtils.kt b/idea/src/org/jetbrains/kotlin/idea/roots/projectRootUtils.kt new file mode 100644 index 00000000000..06f884bf9b9 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/roots/projectRootUtils.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.roots + +import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.roots.SourceFolder +import org.jetbrains.jps.model.JpsElement +import org.jetbrains.jps.model.ex.JpsElementBase +import org.jetbrains.jps.model.java.JavaResourceRootType +import org.jetbrains.jps.model.java.JavaSourceRootType +import org.jetbrains.jps.model.module.JpsModuleSourceRootType +import org.jetbrains.kotlin.config.KotlinResourceRootType +import org.jetbrains.kotlin.config.KotlinSourceRootType + +private fun SourceFolder.getOrCreateProperties() = + jpsElement.getProperties(rootType)?.also { (it as? JpsElementBase<*>)?.setParent(null) } ?: rootType.createDefaultProperties() + +private fun SourceFolder.getNewSourceRootTypeWithProperties(): Pair, JpsElement>? { + val currentRootType = rootType + @Suppress("UNCHECKED_CAST") + val newSourceRootType: JpsModuleSourceRootType = when (currentRootType) { + JavaSourceRootType.SOURCE -> KotlinSourceRootType.Source + JavaSourceRootType.TEST_SOURCE -> KotlinSourceRootType.TestSource + JavaResourceRootType.RESOURCE -> KotlinResourceRootType.Resource + JavaResourceRootType.TEST_RESOURCE -> KotlinResourceRootType.TestResource + else -> return null + } as JpsModuleSourceRootType + return newSourceRootType to getOrCreateProperties() +} + +fun migrateNonJvmSourceFolders(modifiableRootModel: ModifiableRootModel) { + for (contentEntry in modifiableRootModel.contentEntries) { + for (sourceFolder in contentEntry.sourceFolders) { + val (newSourceRootType, properties) = sourceFolder.getNewSourceRootTypeWithProperties() ?: continue + val url = sourceFolder.url + contentEntry.removeSourceFolder(sourceFolder) + contentEntry.addSourceFolder(url, newSourceRootType, properties) + } + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/roots/ui/KotlinContentEntriesEditor.kt b/idea/src/org/jetbrains/kotlin/idea/roots/ui/KotlinContentEntriesEditor.kt new file mode 100644 index 00000000000..ec4fff39bb0 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/roots/ui/KotlinContentEntriesEditor.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.roots.ui + +import com.intellij.openapi.roots.ContentEntry +import com.intellij.openapi.roots.ui.configuration.* +import com.intellij.openapi.vfs.VirtualFile +import org.jetbrains.kotlin.config.KotlinResourceRootType +import org.jetbrains.kotlin.config.KotlinSourceRootType + +class KotlinContentEntriesEditor( + moduleName: String, + state: ModuleConfigurationState +) : CommonContentEntriesEditor( + moduleName, + state, + KotlinSourceRootType.Source, + KotlinSourceRootType.TestSource, + KotlinResourceRootType.Resource, + KotlinResourceRootType.TestResource +) { + private val javaEditor by lazy { + object : JavaContentEntriesEditor(moduleName, state) { + public override fun addContentEntries(files: Array?) = super.addContentEntries(files) + } + } + + override fun createContentEntryEditor(contentEntryUrl: String): ContentEntryEditor { + return object : JavaContentEntryEditor(contentEntryUrl, editHandlers) { + override fun getModel() = this@KotlinContentEntriesEditor.model + } + } + + override fun addContentEntries(files: Array?): MutableList = javaEditor.addContentEntries(files) +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/roots/ui/KotlinSourceRootEditHandler.kt b/idea/src/org/jetbrains/kotlin/idea/roots/ui/KotlinSourceRootEditHandler.kt new file mode 100644 index 00000000000..343d0c79b84 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/roots/ui/KotlinSourceRootEditHandler.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.roots.ui + +import com.intellij.openapi.roots.ui.configuration.* +import org.jetbrains.jps.model.JpsElement +import org.jetbrains.jps.model.java.JavaResourceRootProperties +import org.jetbrains.jps.model.java.JavaSourceRootProperties +import org.jetbrains.jps.model.module.JpsModuleSourceRootType +import org.jetbrains.kotlin.config.KotlinResourceRootType +import org.jetbrains.kotlin.config.KotlinSourceRootType + +sealed class KotlinModuleSourceRootEditHandler( + rootType: JpsModuleSourceRootType, + private val delegate: ModuleSourceRootEditHandler +) : ModuleSourceRootEditHandler(rootType) { + class Source : KotlinModuleSourceRootEditHandler( + KotlinSourceRootType.Source, + JavaModuleSourceRootEditHandler() + ) + + class TestSource : KotlinModuleSourceRootEditHandler( + KotlinSourceRootType.TestSource, + JavaTestSourceRootEditHandler() + ) + + class Resource : KotlinModuleSourceRootEditHandler( + KotlinResourceRootType.Resource, + JavaResourceRootEditHandler() + ) + + class TestResource : KotlinModuleSourceRootEditHandler( + KotlinResourceRootType.TestResource, + JavaTestResourceRootEditHandler() + ) + + override fun getUnmarkRootButtonText() = delegate.unmarkRootButtonText + + override fun getRootIcon() = delegate.rootIcon + + override fun getRootsGroupTitle() = delegate.rootsGroupTitle + + override fun getMarkRootShortcutSet() = delegate.markRootShortcutSet + + override fun getRootTypeName() = delegate.rootTypeName + + override fun getRootsGroupColor() = delegate.rootsGroupColor + + override fun getFolderUnderRootIcon() = delegate.folderUnderRootIcon +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/roots/ui/NonJvmKotlinModuleEditorsProvider.kt b/idea/src/org/jetbrains/kotlin/idea/roots/ui/NonJvmKotlinModuleEditorsProvider.kt new file mode 100644 index 00000000000..0f0a0d6575a --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/roots/ui/NonJvmKotlinModuleEditorsProvider.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.roots.ui + +import com.intellij.openapi.module.JavaModuleType +import com.intellij.openapi.module.ModuleConfigurationEditor +import com.intellij.openapi.module.ModuleType +import com.intellij.openapi.roots.ui.configuration.* +import org.jetbrains.kotlin.idea.project.TargetPlatformDetector +import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform + +class NonJvmKotlinModuleEditorsProvider : ModuleConfigurationEditorProviderEx { + override fun isCompleteEditorSet() = true + + override fun createEditors(state: ModuleConfigurationState): Array { + val rootModel = state.rootModel + val module = rootModel.module + if (ModuleType.get(module) !is JavaModuleType) return ModuleConfigurationEditor.EMPTY + val targetPlatform = TargetPlatformDetector.getPlatform(module) + if (targetPlatform is JvmPlatform) return ModuleConfigurationEditor.EMPTY + + val moduleName = module.name + return arrayOf( + KotlinContentEntriesEditor(moduleName, state), + object : OutputEditor(state) {}, // Work around protected constructor + ClasspathEditor(state) + ) + } +} \ No newline at end of file diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinSourceFileCollector.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinSourceFileCollector.kt index 742fb4fdde6..f5e38e66f5a 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinSourceFileCollector.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinSourceFileCollector.kt @@ -21,9 +21,6 @@ import com.intellij.util.containers.MultiMap import org.jetbrains.jps.builders.DirtyFilesHolder import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor import org.jetbrains.jps.incremental.ModuleBuildTarget -import org.jetbrains.jps.model.java.JavaSourceRootProperties -import org.jetbrains.jps.model.java.JavaSourceRootType -import org.jetbrains.jps.model.module.JpsModuleSourceRoot import java.io.File diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuilderTarget.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuilderTarget.kt index 0eb6112c94d..d911e923906 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuilderTarget.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuilderTarget.kt @@ -16,10 +16,12 @@ import org.jetbrains.jps.model.java.JavaSourceRootType import org.jetbrains.jps.model.java.JpsJavaClasspathKind import org.jetbrains.jps.model.java.JpsJavaExtensionService import org.jetbrains.jps.model.module.JpsModule +import org.jetbrains.jps.model.module.JpsModuleSourceRootType import org.jetbrains.jps.util.JpsPathUtil import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment +import org.jetbrains.kotlin.config.KotlinSourceRootType import org.jetbrains.kotlin.jps.build.FSOperationsHelper import org.jetbrains.kotlin.jps.build.KotlinSourceFileCollector import org.jetbrains.kotlin.jps.model.kotlinFacet @@ -33,6 +35,13 @@ import java.io.File * Properties and actions for Kotlin test / production module build target. */ abstract class KotlinModuleBuilderTarget(val context: CompileContext, val jpsModuleBuildTarget: ModuleBuildTarget) { + val sourceRootTypes: Collection> + get() = if (isTests) { + listOf(JavaSourceRootType.TEST_SOURCE, KotlinSourceRootType.TestSource) + } else { + listOf(JavaSourceRootType.SOURCE, KotlinSourceRootType.Source) + } + val module: JpsModule get() = jpsModuleBuildTarget.module @@ -116,16 +125,18 @@ abstract class KotlinModuleBuilderTarget(val context: CompileContext, val jpsMod .getOrCreateCompilerConfiguration(module.project) .compilerExcludes - val sourceRootType = if (isTests) JavaSourceRootType.TEST_SOURCE else JavaSourceRootType.SOURCE - module.getSourceRoots(sourceRootType).forEach { - it.file.walkTopDown() - .onEnter { it !in moduleExcludes } - .filterTo(receiver) { - !compilerExcludes.isExcluded(it) && - it.isFile && - KotlinSourceFileCollector.isKotlinSourceFile(it) - } - } + module + .sourceRoots + .filter { it.rootType in sourceRootTypes } + .forEach { + it.file.walkTopDown() + .onEnter { it !in moduleExcludes } + .filterTo(receiver) { + !compilerExcludes.isExcluded(it) && + it.isFile && + KotlinSourceFileCollector.isKotlinSourceFile(it) + } + } } override fun toString() = jpsModuleBuildTarget.toString()