From 6936e225d66e1bdad30d5787fee3218d1817028f Mon Sep 17 00:00:00 2001 From: Nikolay Chashnikov Date: Mon, 13 Jul 2020 12:47:32 +0300 Subject: [PATCH] [workspace model] implement ModifiableModuleModel::loadModule method Otherwise "Import Module from iml file" action doesn't work (WM-T-70). GitOrigin-RevId: d338dcb0b427dbb8ebda047eab85387939ab3401 --- .../detached-module/.idea/modules.xml | 8 +++++ .../detached-module/bar/bar.iml | 7 ++++ .../detached-module/foo/foo.iml | 7 ++++ .../configurationStore/LoadProjectTest.kt | 31 +++++++++++++++++ .../configurationStore/SaveProjectTest.kt | 12 ++++++- .../module/ModifiableModuleModelBridge.kt | 33 +++++++++++++++---- .../module/ModuleManagerComponentBridge.kt | 17 +++------- 7 files changed, 95 insertions(+), 20 deletions(-) create mode 100644 java/java-tests/testData/configurationStore/detached-module/.idea/modules.xml create mode 100644 java/java-tests/testData/configurationStore/detached-module/bar/bar.iml create mode 100644 java/java-tests/testData/configurationStore/detached-module/foo/foo.iml diff --git a/java/java-tests/testData/configurationStore/detached-module/.idea/modules.xml b/java/java-tests/testData/configurationStore/detached-module/.idea/modules.xml new file mode 100644 index 000000000000..7ba1dabc4578 --- /dev/null +++ b/java/java-tests/testData/configurationStore/detached-module/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/java/java-tests/testData/configurationStore/detached-module/bar/bar.iml b/java/java-tests/testData/configurationStore/detached-module/bar/bar.iml new file mode 100644 index 000000000000..70ec6cce375a --- /dev/null +++ b/java/java-tests/testData/configurationStore/detached-module/bar/bar.iml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/java/java-tests/testData/configurationStore/detached-module/foo/foo.iml b/java/java-tests/testData/configurationStore/detached-module/foo/foo.iml new file mode 100644 index 000000000000..70ec6cce375a --- /dev/null +++ b/java/java-tests/testData/configurationStore/detached-module/foo/foo.iml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/configurationStore/LoadProjectTest.kt b/java/java-tests/testSrc/com/intellij/java/configurationStore/LoadProjectTest.kt index f05dd6fcaf95..42cbcb0ad7cc 100644 --- a/java/java-tests/testSrc/com/intellij/java/configurationStore/LoadProjectTest.kt +++ b/java/java-tests/testSrc/com/intellij/java/configurationStore/LoadProjectTest.kt @@ -2,6 +2,7 @@ package com.intellij.java.configurationStore import com.intellij.openapi.application.ex.PathManagerEx +import com.intellij.openapi.application.runWriteActionAndWait import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project import com.intellij.openapi.roots.OrderRootType @@ -37,6 +38,36 @@ class LoadProjectTest { loadProjectAndCheckResults("single-module") { project -> val module = ModuleManager.getInstance(project).modules.single() assertThat(module.name).isEqualTo("foo") + assertThat(module.moduleTypeName).isEqualTo("EMPTY_MODULE") + } + } + + @Test + fun `load detached module`() { + loadProjectAndCheckResults("detached-module") { project -> + val fooModule = ModuleManager.getInstance(project).modules.single() + assertThat(fooModule.name).isEqualTo("foo") + val barModule = runWriteActionAndWait { ModuleManager.getInstance(project).loadModule("${project.basePath}/bar/bar.iml") } + assertThat(barModule.name).isEqualTo("bar") + assertThat(barModule.moduleTypeName).isEqualTo("EMPTY_MODULE") + assertThat(ModuleManager.getInstance(project).modules).containsExactlyInAnyOrder(fooModule, barModule) + } + } + + @Test + fun `load detached module via modifiable model`() { + loadProjectAndCheckResults("detached-module") { project -> + val fooModule = ModuleManager.getInstance(project).modules.single() + assertThat(fooModule.name).isEqualTo("foo") + runWriteActionAndWait { + val model = ModuleManager.getInstance(project).modifiableModel + model.loadModule("${project.basePath}/bar/bar.iml") + model.commit() + } + val barModule = ModuleManager.getInstance(project).findModuleByName("bar") + assertThat(barModule).isNotNull() + assertThat(barModule!!.moduleTypeName).isEqualTo("EMPTY_MODULE") + assertThat(ModuleManager.getInstance(project).modules).containsExactlyInAnyOrder(fooModule, barModule) } } diff --git a/java/java-tests/testSrc/com/intellij/java/configurationStore/SaveProjectTest.kt b/java/java-tests/testSrc/com/intellij/java/configurationStore/SaveProjectTest.kt index a147268970f1..edbbcc013b96 100644 --- a/java/java-tests/testSrc/com/intellij/java/configurationStore/SaveProjectTest.kt +++ b/java/java-tests/testSrc/com/intellij/java/configurationStore/SaveProjectTest.kt @@ -6,10 +6,10 @@ import com.intellij.openapi.application.runReadAction import com.intellij.openapi.application.runWriteActionAndWait import com.intellij.openapi.components.stateStore import com.intellij.openapi.roots.OrderRootType -import com.intellij.openapi.util.io.systemIndependentPath import com.intellij.openapi.vfs.VfsUtil import com.intellij.testFramework.ApplicationRule import com.intellij.testFramework.rules.ProjectModelRule +import com.intellij.testFramework.runInEdtAndWait import com.intellij.util.io.assertMatches import com.intellij.util.io.directoryContentOf import com.intellij.util.io.systemIndependentPath @@ -43,6 +43,16 @@ class SaveProjectTest { projectModel.baseProjectDir.root.assertMatches(directoryContentOf(testDataRoot.resolve("single-module"))) } + @Test + fun `save detached module`() = runBlocking { + projectModel.createModule("foo") + val module = projectModel.createModule("bar") + saveProjectState() + runInEdtAndWait { projectModel.moduleManager.disposeModule(module) } + saveProjectState() + projectModel.baseProjectDir.root.assertMatches(directoryContentOf(testDataRoot.resolve("detached-module"))) + } + @Test fun `save single library`() = runBlocking { projectModel.addProjectLevelLibrary("foo") { diff --git a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModifiableModuleModelBridge.kt b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModifiableModuleModelBridge.kt index 945e1f4dba0d..2940be7bc320 100644 --- a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModifiableModuleModelBridge.kt +++ b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModifiableModuleModelBridge.kt @@ -16,6 +16,7 @@ import com.intellij.projectModel.ProjectModelBundle import com.intellij.util.PathUtil import com.intellij.workspaceModel.ide.NonPersistentEntitySource import com.intellij.workspaceModel.ide.WorkspaceModel +import com.intellij.workspaceModel.ide.configLocation import com.intellij.workspaceModel.ide.getInstance import com.intellij.workspaceModel.ide.impl.jps.serialization.JpsProjectEntitiesLoader import com.intellij.workspaceModel.ide.impl.legacyBridge.LegacyBridgeModifiableBase @@ -25,6 +26,8 @@ import com.intellij.workspaceModel.ide.legacyBridge.ModuleBridge import com.intellij.workspaceModel.storage.VirtualFileUrlManager import com.intellij.workspaceModel.storage.WorkspaceEntityStorageBuilder import com.intellij.workspaceModel.storage.bridgeEntities.* +import java.io.File +import java.io.IOException internal class ModifiableModuleModelBridge( private val project: Project, @@ -92,10 +95,13 @@ internal class ModifiableModuleModelBridge( source = entitySource ) - val moduleInstance = moduleManager.createModuleInstance(moduleEntity, entityStorageOnDiff, diff = diff, isNew = true) - diff.mutableModuleMap.addMapping(moduleEntity, moduleInstance) - myModulesToAdd[moduleName] = moduleInstance + return createModuleInstance(moduleEntity, true) + } + private fun createModuleInstance(moduleEntity: ModuleEntity, isNew: Boolean): ModuleBridge { + val moduleInstance = moduleManager.createModuleInstance(moduleEntity, entityStorageOnDiff, diff = diff, isNew = isNew) + diff.mutableModuleMap.addMapping(moduleEntity, moduleInstance) + myModulesToAdd[moduleEntity.name] = moduleInstance return moduleInstance } @@ -125,9 +131,24 @@ internal class ModifiableModuleModelBridge( } } - // TODO Actually load module content - override fun loadModule(filePath: String): Module = - newModule(filePath, "") + override fun loadModule(filePath: String): Module { + val moduleName = getModuleNameByFilePath(filePath) + if (findModuleByName(moduleName) != null) { + error("Module name '$moduleName' already exists. Trying to load module: $filePath") + } + + removeUnloadedModule(moduleName) + + val builder = WorkspaceEntityStorageBuilder.create() + JpsProjectEntitiesLoader.loadModule(File(filePath), project.configLocation!!, builder, virtualFileManager) + diff.addDiff(builder) + val moduleEntity = diff.entities(ModuleEntity::class.java).find { it.name == moduleName } + if (moduleEntity == null) { + throw IOException("Failed to load module from $filePath") + } + + return createModuleInstance(moduleEntity, false) + } override fun disposeModule(module: Module) { if (Disposer.isDisposing(module.project)) { diff --git a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleManagerComponentBridge.kt b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleManagerComponentBridge.kt index 991ed7a641ee..85a6d18db4d3 100644 --- a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleManagerComponentBridge.kt +++ b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleManagerComponentBridge.kt @@ -431,19 +431,10 @@ class ModuleManagerComponentBridge(private val project: Project) : ModuleManager override fun getModuleGrouper(model: ModifiableModuleModel?): ModuleGrouper = createGrouper(project, model) override fun loadModule(filePath: String): Module { - val moduleName = getModuleNameByFilePath(filePath) - if (findModuleByName(moduleName) != null) { - error("Module name '$moduleName' already exists. Trying to load module: $filePath") - } - - val moduleFile = File(filePath) - - WorkspaceModel.getInstance(project).updateProjectModel { builder -> - JpsProjectEntitiesLoader.loadModule(moduleFile, project.configLocation!!, builder, virtualFileManager) - } - - return findModuleByName(moduleName) - ?: error("Module '$moduleName' was not found after loading: $filePath") + val model = modifiableModel + val module = model.loadModule(filePath) + model.commit() + return module } override fun getUnloadedModuleDescription(moduleName: String): UnloadedModuleDescription? = unloadedModules[moduleName]