From 505cc13614ad971280f135bcf5cb2b36b26f4c76 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 4 Jul 2022 14:53:03 +0200 Subject: [PATCH] use kotlin coroutines instead of fork-join pool and completable future (part 17.1 - get rid of invokeAndWait in PyTemplatesAutoConfiguration) GitOrigin-RevId: 43a91d3a0ebab7f6658263ece51acfd0f6d23a12 --- .../projectImport/ProjectAttachProcessor.java | 3 +- .../platform/ModuleAttachProcessor.kt | 9 ++-- .../project/impl/ProjectManagerImpl.kt | 2 +- .../platform/DirectoryProjectConfigurator.kt | 51 ++++++++++++------- .../platform/PlatformProjectOpenProcessor.kt | 40 +++------------ .../python/newProject/welcome/PyWelcome.kt | 5 +- 6 files changed, 52 insertions(+), 58 deletions(-) diff --git a/platform/ide-core/src/com/intellij/projectImport/ProjectAttachProcessor.java b/platform/ide-core/src/com/intellij/projectImport/ProjectAttachProcessor.java index 81922b204592..07427c29778f 100644 --- a/platform/ide-core/src/com/intellij/projectImport/ProjectAttachProcessor.java +++ b/platform/ide-core/src/com/intellij/projectImport/ProjectAttachProcessor.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.projectImport; import com.intellij.openapi.extensions.ExtensionPointName; @@ -9,7 +9,6 @@ import org.jetbrains.annotations.Nullable; import java.nio.file.Path; - public class ProjectAttachProcessor { public static final ExtensionPointName EP_NAME = new ExtensionPointName<>("com.intellij.projectAttachProcessor"); diff --git a/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.kt b/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.kt index fe4857cc44de..843b30e29b75 100644 --- a/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.kt +++ b/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.kt @@ -5,6 +5,7 @@ import com.intellij.CommonBundle import com.intellij.configurationStore.StoreUtil import com.intellij.featureStatistics.fusCollectors.LifecycleUsageTriggerCollector import com.intellij.ide.impl.OpenProjectTask +import com.intellij.ide.impl.runUnderModalProgressIfIsEdt import com.intellij.lang.LangBundle import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.diagnostic.logger @@ -79,9 +80,11 @@ class ModuleAttachProcessor : ProjectAttachProcessor() { if (!dotIdeaDir.exists()) { val options = OpenProjectTask(useDefaultProjectAsTemplate = true, isNewProject = true) val newProject = ProjectManagerEx.getInstanceEx().newProject(projectDir, options) ?: return false - PlatformProjectOpenProcessor.runDirectoryProjectConfigurators(baseDir = projectDir, - project = newProject, - newProject = true) + runUnderModalProgressIfIsEdt { + PlatformProjectOpenProcessor.runDirectoryProjectConfigurators(baseDir = projectDir, + project = newProject, + newProject = true) + } StoreUtil.saveSettings(newProject) runWriteAction { Disposer.dispose(newProject) } } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.kt b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.kt index 54bcfe9332a9..6158c3bfb1a4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.kt +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.kt @@ -851,7 +851,7 @@ open class ProjectManagerImpl : ProjectManagerEx(), Disposable { if (options.runConfigurators && (options.isNewProject || ModuleManager.getInstance(project).modules.isEmpty()) || project.isLoadedFromCacheButHasNoModules()) { - val module = PlatformProjectOpenProcessor.runDirectoryProjectConfiguratorsV2( + val module = PlatformProjectOpenProcessor.runDirectoryProjectConfigurators( baseDir = projectStoreBaseDir, project = project, newProject = options.isProjectCreatedWithWizard diff --git a/platform/platform-impl/src/com/intellij/platform/DirectoryProjectConfigurator.kt b/platform/platform-impl/src/com/intellij/platform/DirectoryProjectConfigurator.kt index 1e23eef8aa9b..091c75b3ec09 100644 --- a/platform/platform-impl/src/com/intellij/platform/DirectoryProjectConfigurator.kt +++ b/platform/platform-impl/src/com/intellij/platform/DirectoryProjectConfigurator.kt @@ -1,32 +1,49 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.platform; +package com.intellij.platform -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Ref; -import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NotNull; +import com.intellij.openapi.module.Module +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Ref +import com.intellij.openapi.vfs.VirtualFile /** * Configures various subsystems (facets etc.) when a user opens a directory with code but without `.idea` subdirectory. - *

+ * * Example: to support some framework, you need to enable and configure a facet. A user opens a directory with code for the first time. * This class scans the code and detects the framework heuristically. It then configures facet without user action. */ -public interface DirectoryProjectConfigurator { +interface DirectoryProjectConfigurator { /** * @return if code must be called or EDT or not. - * If {@link #configureProject(Project, VirtualFile, Ref, boolean)} is slow (heavy computations, network access etc) return "false" here. + * If [.configureProject] is slow (heavy computations, network access etc) return "false" here. */ - default boolean isEdtRequired() { - return true; - } + @JvmDefault + val isEdtRequired: Boolean + get() = true /** * @param isProjectCreatedWithWizard if true then new project created with wizard, existing folder opened otherwise */ - void configureProject(@NotNull Project project, - @NotNull VirtualFile baseDir, - @NotNull Ref moduleRef, - boolean isProjectCreatedWithWizard); -} + fun configureProject(project: Project, + baseDir: VirtualFile, + moduleRef: Ref, + isProjectCreatedWithWizard: Boolean) + + abstract class AsyncDirectoryProjectConfigurator : DirectoryProjectConfigurator { + final override val isEdtRequired: Boolean + get() = false + + final override fun configureProject(project: Project, + baseDir: VirtualFile, + moduleRef: Ref, + isProjectCreatedWithWizard: Boolean) { + } + + abstract suspend fun configure( + project: Project, + baseDir: VirtualFile, + moduleRef: Ref, + isProjectCreatedWithWizard: Boolean + ) + } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.kt b/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.kt index bf1b4820f7d6..1856ce9fbe69 100644 --- a/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.kt +++ b/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.kt @@ -174,32 +174,7 @@ class PlatformProjectOpenProcessor : ProjectOpenProcessor(), CommandLineProjectO return project } - @JvmStatic - fun runDirectoryProjectConfigurators(baseDir: Path, project: Project, newProject: Boolean): Module { - project.putUserData(PROJECT_CONFIGURED_BY_PLATFORM_PROCESSOR, true) - val moduleRef = Ref() - val virtualFile = ProjectUtilCore.getFileAndRefresh(baseDir)!! - EP_NAME.forEachExtensionSafe { configurator -> - fun task() { - configurator.configureProject(project, virtualFile, moduleRef, newProject) - } - if (configurator.isEdtRequired) { - ApplicationManager.getApplication().invokeAndWait { - task() - } - } - else { - task() - } - } - val module = moduleRef.get() - if (module == null) { - LOG.error("No extension configured a module for $baseDir; extensions = ${EP_NAME.extensionList}") - } - return module - } - - suspend fun runDirectoryProjectConfiguratorsV2(baseDir: Path, project: Project, newProject: Boolean): Module { + suspend fun runDirectoryProjectConfigurators(baseDir: Path, project: Project, newProject: Boolean): Module { project.putUserData(PROJECT_CONFIGURED_BY_PLATFORM_PROCESSOR, true) val moduleRef = Ref() @@ -210,18 +185,17 @@ class PlatformProjectOpenProcessor : ProjectOpenProcessor(), CommandLineProjectO } for (configurator in EP_NAME.iterable) { - fun task() { - configurator.configureProject(project, virtualFile, moduleRef, newProject) - } - try { - if (configurator.isEdtRequired) { + if (configurator is DirectoryProjectConfigurator.AsyncDirectoryProjectConfigurator) { + configurator.configure(project, virtualFile, moduleRef, newProject) + } + else if (configurator.isEdtRequired) { withContext(Dispatchers.EDT) { - task() + configurator.configureProject(project, virtualFile, moduleRef, newProject) } } else { - task() + configurator.configureProject(project, virtualFile, moduleRef, newProject) } } catch (e: ProcessCanceledException) { diff --git a/python/ide/impl/src/com/jetbrains/python/newProject/welcome/PyWelcome.kt b/python/ide/impl/src/com/jetbrains/python/newProject/welcome/PyWelcome.kt index 11f438f6a136..6886f22eedd8 100644 --- a/python/ide/impl/src/com/jetbrains/python/newProject/welcome/PyWelcome.kt +++ b/python/ide/impl/src/com/jetbrains/python/newProject/welcome/PyWelcome.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.jetbrains.python.newProject.welcome import com.intellij.execution.RunManager @@ -55,7 +55,8 @@ import java.util.concurrent.Callable import javax.swing.JPanel internal class PyWelcomeConfigurator : DirectoryProjectConfigurator { - override fun isEdtRequired() = false + override val isEdtRequired: Boolean + get() = false override fun configureProject(project: Project, baseDir: VirtualFile, moduleRef: Ref, isProjectCreatedWithWizard: Boolean) { if (isProjectCreatedWithWizard || isInsideTempDirectory(baseDir)) {