diff --git a/platform/lang-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/facet/ModifiableFacetModelBridgeImpl.kt b/platform/lang-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/facet/ModifiableFacetModelBridgeImpl.kt index 6091a577bff2..fe1a6909c2b6 100644 --- a/platform/lang-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/facet/ModifiableFacetModelBridgeImpl.kt +++ b/platform/lang-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/facet/ModifiableFacetModelBridgeImpl.kt @@ -11,10 +11,11 @@ import com.intellij.openapi.project.isExternalStorageEnabled import com.intellij.openapi.roots.ProjectModelExternalSource import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.JDOMUtil -import com.intellij.util.containers.ContainerUtil import com.intellij.platform.workspaceModel.jps.CustomModuleEntitySource import com.intellij.platform.workspaceModel.jps.JpsFileEntitySource import com.intellij.platform.workspaceModel.jps.JpsImportedEntitySource +import com.intellij.platform.workspaceModel.jps.JpsProjectFileEntitySource +import com.intellij.util.containers.ContainerUtil import com.intellij.workspaceModel.ide.WorkspaceModel import com.intellij.workspaceModel.ide.impl.legacyBridge.facet.FacetModelBridge.Companion.facetMapping import com.intellij.workspaceModel.ide.impl.legacyBridge.facet.FacetModelBridge.Companion.mutableFacetMapping @@ -22,6 +23,7 @@ import com.intellij.workspaceModel.ide.impl.legacyBridge.module.findModuleEntity import com.intellij.workspaceModel.ide.legacyBridge.ModifiableFacetModelBridge import com.intellij.workspaceModel.ide.legacyBridge.ModuleBridge import com.intellij.workspaceModel.ide.legacyBridge.WorkspaceFacetContributor +import com.intellij.workspaceModel.storage.EntitySource import com.intellij.workspaceModel.storage.EntityStorage import com.intellij.workspaceModel.storage.MutableEntityStorage import com.intellij.workspaceModel.storage.WorkspaceEntity @@ -144,11 +146,52 @@ class ModifiableFacetModelBridgeImpl(private val initialStorage: EntityStorage, diff.mutableFacetMapping().removeMapping(facetEntity) diff.mutableFacetMapping().addMapping(newEntity, facet) } - allFacets.filter { it is FacetBridge<*> } - .forEach { facet -> + val (facetBridges, commonFacets) = allFacets.partition { it is FacetBridge<*> } + facetBridges.forEach { facet -> facet as FacetBridge<*> facet.updateInStorage(diff) } + commonFacets.forEach { facet -> + mapping.getEntities(facet).forEach { facetEntity -> + + // Update external system of existing facets + facetEntity as FacetEntity + val facetExternalSource = facet.externalSource + val newSource = getUpdatedEntitySource(facetExternalSource, facetEntity) + if (newSource != null) { + diff.modifyEntity(facetEntity) { + this.entitySource = newSource + } + } + } + } + } + + /** + * This method returns an updates entity source to have the sam external source as [facetExternalSource] + * I'll return null if no update required + */ + private fun getUpdatedEntitySource(facetExternalSource: ProjectModelExternalSource?, + facetEntity: FacetEntity): EntitySource? { + val entitySource = facetEntity.entitySource + val newSource = if (facetExternalSource == null) { + if (entitySource is JpsImportedEntitySource) { + entitySource.internalFile + } + else null + } + else { + if (entitySource !is JpsImportedEntitySource) { + if (entitySource is JpsProjectFileEntitySource.FileInDirectory) JpsImportedEntitySource(entitySource, facetExternalSource.id, + moduleBridge.project.isExternalStorageEnabled) + else null + } + else { + if (facetExternalSource.id == entitySource.externalSystemId) null + else entitySource.copy(externalSystemId = facetExternalSource.id) + } + } + return newSource } override fun getAllFacets(): Array> { diff --git a/platform/workspaceModel/jps/src/com/intellij/platform/workspaceModel/jps/jpsEntitySources.kt b/platform/workspaceModel/jps/src/com/intellij/platform/workspaceModel/jps/jpsEntitySources.kt index b7923f82316c..1e05f5054287 100644 --- a/platform/workspaceModel/jps/src/com/intellij/platform/workspaceModel/jps/jpsEntitySources.kt +++ b/platform/workspaceModel/jps/src/com/intellij/platform/workspaceModel/jps/jpsEntitySources.kt @@ -101,6 +101,9 @@ data class JpsImportedEntitySource(val internalFile: JpsFileEntitySource, get() = internalFile.virtualFileUrl } +val EntitySource.externalSystemId: String? + get() = (this as? JpsImportedEntitySource)?.externalSystemId + internal class FileInDirectorySerializer : Serializer(false, true) { override fun write(kryo: Kryo, output: Output, o: JpsProjectFileEntitySource.FileInDirectory) { kryo.writeClassAndObject(output, o.directory) diff --git a/plugins/kotlin/maven/tests/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenImporterTest.kt b/plugins/kotlin/maven/tests/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenImporterTest.kt index 9a8b402e80e7..28aff4a7fabd 100644 --- a/plugins/kotlin/maven/tests/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenImporterTest.kt +++ b/plugins/kotlin/maven/tests/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenImporterTest.kt @@ -2,8 +2,11 @@ package org.jetbrains.kotlin.idea.maven import com.intellij.application.options.CodeStyle +import com.intellij.facet.FacetManager import com.intellij.notification.Notification +import com.intellij.openapi.application.invokeAndWaitIfNeeded import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil +import com.intellij.openapi.module.Module import com.intellij.openapi.projectRoots.JavaSdk import com.intellij.openapi.projectRoots.ProjectJdkTable import com.intellij.openapi.roots.CompilerModuleExtension @@ -36,6 +39,7 @@ import org.jetbrains.kotlin.idea.compiler.configuration.KotlinJpsPluginSettings import org.jetbrains.kotlin.idea.compiler.configuration.KotlinPluginLayout import org.jetbrains.kotlin.idea.core.util.toPsiFile import org.jetbrains.kotlin.idea.facet.KotlinFacet +import org.jetbrains.kotlin.idea.facet.KotlinFacetType import org.jetbrains.kotlin.idea.formatter.KotlinObsoleteCodeStyle import org.jetbrains.kotlin.idea.formatter.KotlinStyleGuideCodeStyle import org.jetbrains.kotlin.idea.formatter.kotlinCodeStyleDefaults @@ -1042,6 +1046,74 @@ abstract class AbstractKotlinMavenImporterTest : KotlinMavenImportingTestCase() Assert.assertEquals("c:/program files/jdk1.8", (compilerArguments as K2JVMCompilerArguments).classpath) } } + + /** + * This test check that the facet, that was created in older version of IJ and misses external source tag, + * is marked with external source after reimport + */ + @Test + fun testFacetGetsExternalSource() { + createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") + + + val module = invokeAndWaitIfNeeded { + runWriteAction { + val module = createModule("project") + FacetManager.getInstance(module).addFacet(KotlinFacetType.INSTANCE, "Kotlin", null) + module + } + } + + TestCase.assertNull(FacetManager.getInstance(module).allFacets.single().externalSource?.id) + + importProject( + """ + test + project + 1.0.0 + + + + org.jetbrains.kotlin + kotlin-stdlib + $kotlinVersion + + + + + src/main/kotlin + + + + org.jetbrains.kotlin + kotlin-maven-plugin + + + + compile + compile + + compile + + + + + + -jvm-target 1.8 -Xcoroutines=enable -classpath "c:\program files\jdk1.8" + + + + + + """ + ) + + assertModules("project") + assertImporterStatePresent() + + val externalSource = FacetManager.getInstance(module).allFacets.single().externalSource + TestCase.assertEquals("Maven", externalSource?.id) + } } class JvmDetectionByGoalWithJvmStdlib6 : AbstractKotlinMavenImporterTest() { diff --git a/plugins/kotlin/project-configuration/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt b/plugins/kotlin/project-configuration/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt index 4004a465dd12..9cc01935dfe4 100644 --- a/plugins/kotlin/project-configuration/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt +++ b/plugins/kotlin/project-configuration/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt @@ -6,8 +6,8 @@ import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider import com.intellij.openapi.module.Module import com.intellij.openapi.roots.ExternalProjectSystemRegistry -import org.jetbrains.kotlin.idea.base.projectStructure.ExternalCompilerVersionProvider import org.jetbrains.kotlin.idea.base.codeInsight.tooling.tooling +import org.jetbrains.kotlin.idea.base.projectStructure.ExternalCompilerVersionProvider import org.jetbrains.kotlin.idea.compiler.configuration.IdeKotlinVersion import org.jetbrains.kotlin.platform.IdePlatformKind import org.jetbrains.kotlin.platform.TargetPlatform @@ -43,6 +43,7 @@ fun Module.getOrCreateConfiguredFacet( val externalSource = externalSystemId?.let { ExternalProjectSystemRegistry.getInstance().getSourceById(it) } facetModel.addFacet(this, externalSource) } + facet.externalSource = externalSystemId?.let { ExternalProjectSystemRegistry.getInstance().getSourceById(it) } facet.configuration.settings.useProjectSettings = useProjectSettings facet.configure() if (commitModel) {