[workspace model] implement ModifiableModuleModel::loadModule method

Otherwise "Import Module from iml file" action doesn't work (WM-T-70).

GitOrigin-RevId: d338dcb0b427dbb8ebda047eab85387939ab3401
This commit is contained in:
Nikolay Chashnikov
2020-07-13 16:08:32 +00:00
committed by intellij-monorepo-bot
parent f5da1d445c
commit 6936e225d6
7 changed files with 95 additions and 20 deletions
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/foo/foo.iml" filepath="$PROJECT_DIR$/foo/foo.iml" />
</modules>
</component>
</project>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
@@ -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)
}
}
@@ -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") {
@@ -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)) {
@@ -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]