diff --git a/platform/ide-core/api-dump-unreviewed.txt b/platform/ide-core/api-dump-unreviewed.txt index c5c80a52b296..d2dd152793e7 100644 --- a/platform/ide-core/api-dump-unreviewed.txt +++ b/platform/ide-core/api-dump-unreviewed.txt @@ -688,7 +688,7 @@ com.intellij.ide.workspace.ImportedProjectSettings - a:canImportFromFile(com.intellij.openapi.vfs.VirtualFile):Z - a:getSubprojectIcon():javax.swing.Icon - a:getSubprojects(com.intellij.openapi.project.Project):java.util.List -- a:importFromProject(com.intellij.openapi.project.Project,Z):com.intellij.ide.workspace.ImportedProjectSettings +- a:importFromProject(com.intellij.openapi.project.Project):com.intellij.ide.workspace.ImportedProjectSettings - a:removeSubprojects(java.util.List):V - suppressGenericImportFor(com.intellij.openapi.module.Module):Z *f:com.intellij.ide.workspace.SubprojectHandler$Companion @@ -696,7 +696,7 @@ com.intellij.ide.workspace.ImportedProjectSettings - f:getEP_NAME():com.intellij.openapi.extensions.ExtensionPointName com.intellij.ide.workspace.WorkspaceSettingsImporter - sf:Companion:com.intellij.ide.workspace.WorkspaceSettingsImporter$Companion -- a:importFromProject(com.intellij.openapi.project.Project,Z):com.intellij.ide.workspace.ImportedProjectSettings +- a:importFromProject(com.intellij.openapi.project.Project):com.intellij.ide.workspace.ImportedProjectSettings f:com.intellij.ide.workspace.WorkspaceSettingsImporter$Companion - f:getEP_NAME():com.intellij.openapi.extensions.ExtensionPointName f:com.intellij.navigation.NavigationItemFileStatus diff --git a/platform/ide-core/src/com/intellij/ide/workspace/SubprojectHandler.kt b/platform/ide-core/src/com/intellij/ide/workspace/SubprojectHandler.kt index 10c0ab817544..3853f805d42e 100644 --- a/platform/ide-core/src/com/intellij/ide/workspace/SubprojectHandler.kt +++ b/platform/ide-core/src/com/intellij/ide/workspace/SubprojectHandler.kt @@ -18,7 +18,7 @@ interface SubprojectHandler { fun getSubprojects(project: Project): List fun canImportFromFile(file: VirtualFile): Boolean fun removeSubprojects(subprojects: List) - fun importFromProject(project: Project, newWorkspace: Boolean): ImportedProjectSettings? + fun importFromProject(project: Project): ImportedProjectSettings? fun suppressGenericImportFor(module: Module): Boolean = false @@ -30,7 +30,7 @@ interface WorkspaceSettingsImporter { val EP_NAME: ExtensionPointName = ExtensionPointName.create("com.intellij.workspace.settingsImporter") } - fun importFromProject(project: Project, newWorkspace: Boolean): ImportedProjectSettings? + fun importFromProject(project: Project): ImportedProjectSettings? } interface ImportedProjectSettings { diff --git a/platform/lang-impl/src/com/intellij/ide/workspace/CreateWorkspaceAction.kt b/platform/lang-impl/src/com/intellij/ide/workspace/CreateWorkspaceAction.kt index 3a79f97feb23..798e776e2224 100644 --- a/platform/lang-impl/src/com/intellij/ide/workspace/CreateWorkspaceAction.kt +++ b/platform/lang-impl/src/com/intellij/ide/workspace/CreateWorkspaceAction.kt @@ -5,6 +5,7 @@ import com.intellij.ide.impl.OpenProjectTask import com.intellij.ide.impl.TrustedPaths import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.EDT import com.intellij.openapi.components.ComponentManagerEx import com.intellij.openapi.progress.blockingContext @@ -13,9 +14,13 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.project.ProjectManager import com.intellij.openapi.project.ex.ProjectManagerEx import com.intellij.openapi.project.impl.ProjectManagerImpl +import com.intellij.openapi.startup.StartupManager import com.intellij.util.concurrency.annotations.RequiresEdt import com.intellij.util.containers.addIfNotNull -import kotlinx.coroutines.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.job +import kotlinx.coroutines.withContext import java.nio.file.Files import java.nio.file.Path @@ -38,33 +43,30 @@ internal open class CreateWorkspaceAction: BaseWorkspaceAction(false) { } @RequiresEdt -internal fun createWorkspace(project: Project): Boolean { +internal fun createWorkspace(project: Project) { val subprojects = SubprojectHandler.getAllSubprojects(project).associateBy { it.projectPath } val dialog = NewWorkspaceDialog(project, subprojects.values, true) - if (!dialog.showAndGet()) return false + if (!dialog.showAndGet()) return - val settings = importSettingsFromProject(project, true) - getCoroutineScope(project).launch { - createAndOpenWorkspaceProject(project, dialog.projectPath, dialog.projectName) { workspace -> - for (importedSetting in settings) { - importedSetting.applyTo(workspace) - } - dialog.projectPaths.forEach { linkToWorkspace(workspace, it) } + ApplicationManager.getApplication().executeOnPooledThread { + val workspace = createAndOpenWorkspaceProject(project, dialog.projectPath, dialog.projectName) + ?: return@executeOnPooledThread + StartupManager.getInstance(workspace).runAfterOpened { + addToWorkspace(workspace, dialog.projectPaths) } } - return true } -private fun importSettingsFromProject(project: Project, newWorkspace: Boolean): List { +private fun importSettingsFromProject(project: Project): List { val settings = mutableListOf() val handlers = SubprojectHandler.EP_NAME.extensionList for (handler in handlers) { - settings.addIfNotNull(handler.importFromProject(project, newWorkspace)) + settings.addIfNotNull(handler.importFromProject(project)) } val importers = WorkspaceSettingsImporter.EP_NAME.extensionList for (importer in importers) { - settings.addIfNotNull(importer.importFromProject(project, newWorkspace)) + settings.addIfNotNull(importer.importFromProject(project)) } return settings } @@ -73,7 +75,7 @@ internal suspend fun linkToWorkspace(workspace: Project, projectPath: String) { val projectManagerImpl = blockingContext { ProjectManager.getInstance() as ProjectManagerImpl } val referentProject = blockingContext { projectManagerImpl.loadProject(Path.of(projectPath), false, false) } try { - val settings = importSettingsFromProject(referentProject, false) + val settings = importSettingsFromProject(referentProject) for (importedSettings in settings) { importedSettings.applyTo(workspace) } @@ -88,8 +90,7 @@ internal suspend fun linkToWorkspace(workspace: Project, projectPath: String) { private fun createAndOpenWorkspaceProject(project: Project, workspacePath: Path, - projectName: String?, - initTask: suspend (workspace: Project) -> Unit) { + projectName: String): Project? { val options = OpenProjectTask { projectToClose = project this.projectName = projectName @@ -99,11 +100,10 @@ private fun createAndOpenWorkspaceProject(project: Project, isRefreshVfsNeeded = true beforeOpen = { workspace -> setWorkspace(workspace) - initTask(workspace) true } } Files.createDirectories(workspacePath) TrustedPaths.getInstance().setProjectPathTrusted(workspacePath, true) - ProjectManagerEx.getInstanceEx().openProject(workspacePath, options) + return ProjectManagerEx.getInstanceEx().openProject(workspacePath, options) } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/ide/workspace/DefaultWorkspaceSettingsImporter.kt b/platform/lang-impl/src/com/intellij/ide/workspace/DefaultWorkspaceSettingsImporter.kt index 59f2c5ee53bc..63181779e905 100644 --- a/platform/lang-impl/src/com/intellij/ide/workspace/DefaultWorkspaceSettingsImporter.kt +++ b/platform/lang-impl/src/com/intellij/ide/workspace/DefaultWorkspaceSettingsImporter.kt @@ -7,13 +7,8 @@ import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.roots.ProjectRootManager internal class DefaultWorkspaceSettingsImporter : WorkspaceSettingsImporter { - override fun importFromProject(project: Project, newWorkspace: Boolean): ImportedProjectSettings? { - if (newWorkspace) { - return DefaultImportedProjectSettings(project) - } - else { - return null - } + override fun importFromProject(project: Project): ImportedProjectSettings { + return DefaultImportedProjectSettings(project) } } @@ -30,7 +25,7 @@ private class DefaultImportedProjectSettings(project: Project) : ImportedProject } override suspend fun applyTo(workspace: Project) { - if (projectSdk != null) { + if (projectSdk != null && ProjectRootManager.getInstance(workspace).projectSdk == null) { writeAction { ProjectRootManager.getInstance(workspace).projectSdk = projectSdk } diff --git a/platform/lang-impl/src/com/intellij/ide/workspace/WorkspaceAttachProcessor.kt b/platform/lang-impl/src/com/intellij/ide/workspace/WorkspaceAttachProcessor.kt index 855740c5c37b..4ae938bc6787 100644 --- a/platform/lang-impl/src/com/intellij/ide/workspace/WorkspaceAttachProcessor.kt +++ b/platform/lang-impl/src/com/intellij/ide/workspace/WorkspaceAttachProcessor.kt @@ -11,15 +11,13 @@ import kotlin.io.path.pathString internal class WorkspaceAttachProcessor : ProjectAttachProcessor() { override fun attachToProject(project: Project, projectDir: Path, callback: ProjectOpenedCallback?): Boolean { - if (project.isWorkspace) { - getCoroutineScope(project).launch { - linkToWorkspace(project, projectDir.pathString) - } - return true + if (!project.isWorkspace) { + return false } - else { - return createWorkspace(project) + getCoroutineScope(project).launch { + linkToWorkspace(project, projectDir.pathString) } + return true } override fun isEnabled(project: Project?, path: Path?): Boolean = diff --git a/platform/lang-impl/src/com/intellij/ide/workspace/util.kt b/platform/lang-impl/src/com/intellij/ide/workspace/util.kt index f0491b3ee0a9..91ed24c691e4 100644 --- a/platform/lang-impl/src/com/intellij/ide/workspace/util.kt +++ b/platform/lang-impl/src/com/intellij/ide/workspace/util.kt @@ -19,10 +19,10 @@ internal fun getCoroutineScope(workspace: Project) = workspace.service = SubprojectHandler.EP_NAME.extensionList.filter { it.canImportFromFile(file) } -internal fun addToWorkspace(project: Project, projectPaths: List) { - getCoroutineScope(project).launch { +internal fun addToWorkspace(workspace: Project, projectPaths: List) { + getCoroutineScope(workspace).launch { projectPaths.forEach { s -> - linkToWorkspace(project, s) + linkToWorkspace(workspace, s) } } } diff --git a/plugins/gradle/java/src/workspace/GradleSubprojectHandler.kt b/plugins/gradle/java/src/workspace/GradleSubprojectHandler.kt index 68ed1224a0a8..7668a2e93e58 100644 --- a/plugins/gradle/java/src/workspace/GradleSubprojectHandler.kt +++ b/plugins/gradle/java/src/workspace/GradleSubprojectHandler.kt @@ -26,7 +26,7 @@ internal class GradleSubprojectHandler : ExternalSubprojectHandler(GradleConstan return canOpenGradleProject(file) } - override fun importFromProject(project: Project, newWorkspace: Boolean): ImportedProjectSettings = GradleImportedProjectSettings(project) + override fun importFromProject(project: Project): ImportedProjectSettings = GradleImportedProjectSettings(project) override fun suppressGenericImportFor(module: Module): Boolean { return ExternalSystemModulePropertyManager.getInstance(module).getExternalSystemId() == GradleConstants.SYSTEM_ID.id diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/workspace/MavenSubprojectHandler.kt b/plugins/maven/src/main/java/org/jetbrains/idea/maven/workspace/MavenSubprojectHandler.kt index 336f09565ba5..79184178be93 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/workspace/MavenSubprojectHandler.kt +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/workspace/MavenSubprojectHandler.kt @@ -7,13 +7,10 @@ import com.intellij.ide.workspace.SubprojectHandler import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.project.guessProjectDir -import com.intellij.openapi.startup.StartupManager import com.intellij.openapi.vfs.VirtualFile import icons.MavenIcons -import kotlinx.coroutines.launch import org.jetbrains.idea.maven.project.MavenProject import org.jetbrains.idea.maven.project.MavenProjectsManager -import org.jetbrains.idea.maven.utils.MavenCoroutineScopeProvider import org.jetbrains.idea.maven.utils.MavenUtil import org.jetbrains.idea.maven.wizards.MavenOpenProjectProvider import javax.swing.Icon @@ -34,7 +31,7 @@ internal class MavenSubprojectHandler : SubprojectHandler { MavenProjectsManager.getInstance(workspace).removeManagedFiles(files, null, null) } - override fun importFromProject(project: Project, newWorkspace: Boolean): ImportedProjectSettings { + override fun importFromProject(project: Project): ImportedProjectSettings { // FIXME: does not work for new project: AbstractMavenModuleBuilder creates project in 'MavenUtil.runWhenInitialized' callback return MavenImportedProjectSettings(project) } @@ -48,16 +45,12 @@ internal class MavenSubprojectHandler : SubprojectHandler { } private class MavenImportedProjectSettings(project: Project) : ImportedProjectSettings { - val projectDir = project.guessProjectDir() + val projectDir = requireNotNull(project.guessProjectDir()) override suspend fun applyTo(workspace: Project) { val openProjectProvider = MavenOpenProjectProvider() - if (openProjectProvider.canOpenProject(projectDir!!)) { - StartupManager.getInstance(workspace).runAfterOpened { - MavenCoroutineScopeProvider.getCoroutineScope(workspace).launch { - openProjectProvider.forceLinkToExistingProjectAsync(projectDir, workspace) - } - } + if (openProjectProvider.canOpenProject(projectDir)) { + openProjectProvider.forceLinkToExistingProjectAsync(projectDir, workspace) } } }