IJPL-191229 remove scheduleReloadState (part 12)

GitOrigin-RevId: ffe2cc8cd9036fa8479145dcc1a85c57dcf015b4
This commit is contained in:
Vladimir Krivosheev
2025-09-20 23:23:52 +00:00
committed by intellij-monorepo-bot
parent ecbeefdbbe
commit ab4fde4639
16 changed files with 97 additions and 47 deletions
@@ -17,7 +17,7 @@ import org.jetbrains.idea.maven.utils.library.RepositoryUtils
// called in EDT (RemoteRepositoriesConfigurable.apply)
@RequiresEdt
internal fun reloadAllRepositoryLibraries(project: Project) {
runUnderModalProgressIfIsEdt {
runUnderModalProgressIfIsEdt(project) {
val libraries = collectLibraries(project) { (it as? LibraryEx)?.properties is RepositoryLibraryProperties }
libraries
.asSequence()
@@ -789,14 +789,6 @@ abstract class ComponentStoreImpl : IComponentStore {
}
}
final override fun scheduleReloadState(componentClass: Class<out PersistentStateComponent<*>>, postAction: Runnable?) {
val componentManager = project ?: ApplicationManager.getApplication()
val pluginScope = (componentManager as ComponentManagerEx).instanceCoroutineScope(componentClass)
pluginScope.launch {
reloadState(componentClass)
}
}
private suspend fun reloadState(componentName: String, changedStorages: Set<StateStorage>): Boolean {
val info = components.get(componentName) ?: return false
val component = info.component
@@ -67,10 +67,10 @@ internal class RunConfigurationIconAndInvalidCache : RunConfigurationIconCache {
settings.checkSettings()
ProgramRunnerUtil.getConfigurationIcon(settings, false) to false
}
catch (e: IndexNotReadyException) {
catch (_: IndexNotReadyException) {
ProgramRunnerUtil.getConfigurationIcon(settings, false) to false
}
catch (ignored: RuntimeConfigurationException) {
catch (_: RuntimeConfigurationException) {
val invalid = !DumbService.isDumb(runManagerImpl.project)
ProgramRunnerUtil.getConfigurationIcon(settings, invalid) to invalid
}
@@ -36,11 +36,14 @@ import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.UnknownFeat
import com.intellij.openapi.util.Computable
import com.intellij.openapi.util.Condition
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.platform.backend.workspace.WorkspaceModelChangeListener
import com.intellij.platform.backend.workspace.WorkspaceModelTopics
import com.intellij.platform.ide.progress.ModalTaskOwner
import com.intellij.platform.ide.progress.TaskCancellation
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
import com.intellij.platform.workspace.jps.entities.ContentRootEntity
import com.intellij.platform.workspace.jps.entities.SourceRootEntity
import com.intellij.platform.workspace.storage.VersionedStorageChange
@@ -61,10 +64,9 @@ import com.intellij.util.text.UniqueNameGenerator
import com.intellij.util.text.nullize
import com.intellij.util.ui.EDT
import com.intellij.util.ui.JBUI
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit
import org.jdom.Element
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.TestOnly
@@ -89,7 +91,7 @@ interface RunConfigurationTemplateProvider {
fun getRunConfigurationTemplate(factory: ConfigurationFactory, runManager: RunManagerImpl): RunnerAndConfigurationSettingsImpl?
}
@State(name = "RunManager", storages = [(Storage(value = StoragePathMacros.WORKSPACE_FILE, useSaveThreshold = ThreeState.NO))])
@State(name = "RunManager", storages = [Storage(value = StoragePathMacros.WORKSPACE_FILE, useSaveThreshold = ThreeState.NO)])
open class RunManagerImpl @NonInjectable constructor(val project: Project, private val coroutineScope: CoroutineScope, sharedStreamProvider: StreamProvider?) :
RunManagerEx(), PersistentStateComponent<Element>, Disposable, SettingsSavingComponent {
companion object {
@@ -167,7 +169,7 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, priva
get() = listManager.idToSettings
// When readExternal not all configuration may be loaded, so we need to remember the selected configuration
// so that when it is eventually loaded, we can mark is as a selected.
// so that when it is eventually loaded, we can mark it as selected.
protected open var selectedConfigurationId: String? = null
private val iconAndInvalidCache = RunConfigurationIconAndInvalidCache()
@@ -179,7 +181,7 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, priva
private val recentlyUsedTemporaries = ArrayList<RunnerAndConfigurationSettings>()
// templates should be first, because to migrate old before a run list to effective, we need to get template before a run task
// templates should be first, because, to migrate old before a run list to effective, we need to get template before a run task
private val workspaceSchemeManagerProvider = SchemeManagerIprProvider("configuration", Comparator { n1, n2 ->
val w1 = getNameWeight(n1)
val w2 = getNameWeight(n2)
@@ -200,9 +202,12 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, priva
@Suppress("LeakingThis")
private val workspaceSchemeManager = SchemeManagerFactory.getInstance(project).create(
directoryName = "workspace",
processor = RunConfigurationSchemeManager(this, templateDifferenceHelper,
isShared = false,
isWrapSchemeIntoComponentElement = false),
processor = RunConfigurationSchemeManager(
manager = this,
templateDifferenceHelper = templateDifferenceHelper,
isShared = false,
isWrapSchemeIntoComponentElement = false,
),
streamProvider = workspaceSchemeManagerProvider,
isAutoSave = false,
)
@@ -210,16 +215,18 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, priva
@Suppress("LeakingThis")
private val projectSchemeManager = SchemeManagerFactory.getInstance(project).create(
directoryName = "runConfigurations",
processor = RunConfigurationSchemeManager(this, templateDifferenceHelper,
isShared = true,
isWrapSchemeIntoComponentElement = schemeManagerIprProvider == null),
processor = RunConfigurationSchemeManager(
manager = this, templateDifferenceHelper = templateDifferenceHelper,
isShared = true,
isWrapSchemeIntoComponentElement = schemeManagerIprProvider == null,
),
schemeNameToFileName = OLD_NAME_CONVERTER,
streamProvider = sharedStreamProvider ?: schemeManagerIprProvider,
)
@Suppress("unused")
internal val dotIdeaRunConfigurationsPath: String
get() = FileUtil.toSystemIndependentName(projectSchemeManager.rootDirectory.path)
get() = FileUtilRt.toSystemIndependentName(projectSchemeManager.rootDirectory.path)
private val rcInArbitraryFileManager = RCInArbitraryFileManager(project)
@@ -237,7 +244,7 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, priva
get() = project.messageBus.syncPublisher(RunManagerListener.TOPIC)
init {
project.messageBus.connect().subscribe(DynamicPluginListener.TOPIC, object : DynamicPluginListener {
project.messageBus.connect(coroutineScope).subscribe(DynamicPluginListener.TOPIC, object : DynamicPluginListener {
override fun beforePluginUnload(pluginDescriptor: IdeaPluginDescriptor, isUpdate: Boolean) {
iconAndInvalidCache.clear()
}
@@ -656,7 +663,7 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, priva
val element = Element("state")
if (EDT.isCurrentThreadEdt()) {
runWriteAction { workspaceSchemeManager.save() }
ApplicationManager.getApplication().runWriteAction { workspaceSchemeManager.save() }
}
else {
workspaceSchemeManager.save()
@@ -765,7 +772,7 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, priva
@VisibleForTesting
protected open fun onFirstLoadingFinished() {
project.messageBus.connect().subscribe(WorkspaceModelTopics.CHANGED, object : WorkspaceModelChangeListener {
project.messageBus.connect(coroutineScope).subscribe(WorkspaceModelTopics.CHANGED, object : WorkspaceModelChangeListener {
override fun changed(event: VersionedStorageChange) {
if (event.getChanges(ContentRootEntity::class.java).any() || event.getChanges(SourceRootEntity::class.java).any()) {
clearSelectedConfigurationIcon()
@@ -780,9 +787,29 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, priva
}
ConfigurationType.CONFIGURATION_TYPE_EP.addExtensionPointListener(coroutineScope, object : ExtensionPointListener<ConfigurationType> {
private val semaphore = Semaphore(1)
override fun extensionAdded(extension: ConfigurationType, pluginDescriptor: PluginDescriptor) {
idToType.drop()
project.stateStore.scheduleReloadState(RunManagerImpl::class.java)
val task = suspend {
semaphore.withPermit {
project.stateStore.reloadState(RunManagerImpl::class.java)
}
}
// plugin unloading is performed in a write action
if (EDT.isCurrentThreadEdt() && !ApplicationManager.getApplication().isWriteAccessAllowed) {
runWithModalProgressBlocking(ModalTaskOwner.project(project), "", TaskCancellation.cancellable()) {
task()
}
}
else {
@Suppress("RAW_RUN_BLOCKING")
runBlocking {
task()
}
}
}
override fun extensionRemoved(extension: ConfigurationType, pluginDescriptor: PluginDescriptor) {
@@ -797,7 +824,7 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, priva
}
lock.write {
templateIdToConfiguration.values.removeIf(java.util.function.Predicate { it.type == extension })
templateIdToConfiguration.values.removeIf { it.type == extension }
}
}
})
@@ -10,9 +10,8 @@ import java.util.Collection;
@ApiStatus.Experimental
public interface SyntheticConfigurationTypeProvider {
ExtensionPointName<SyntheticConfigurationTypeProvider> EP_NAME =
ExtensionPointName.create("com.intellij.execution.syntheticConfigurationTypeProvider");
new ExtensionPointName<>("com.intellij.execution.syntheticConfigurationTypeProvider");
@NotNull @Unmodifiable
Collection<? extends ConfigurationType> getConfigurationTypes();
@@ -2,7 +2,6 @@
package com.intellij.openapi.extensions
interface ExtensionPointListener<T> {
fun extensionAdded(extension: T, pluginDescriptor: PluginDescriptor) {}
fun extensionRemoved(extension: T, pluginDescriptor: PluginDescriptor) {}
@@ -30,7 +30,10 @@ final class PackageSetFactoryImpl extends PackageSetFactory {
public void extensionAdded(@NotNull PackageSetParserExtension extension, @NotNull PluginDescriptor pluginDescriptor) {
for (Project project : ProjectUtil.getOpenProjects()) {
for (NamedScopesHolder holder : NamedScopesHolder.getAllNamedScopeHolders(project)) {
IComponentStoreKt.getStateStore(project).scheduleReloadState(holder.getClass(), holder::fireScopeListeners);
IComponentStoreKt.scheduleReloadState(IComponentStoreKt.getStateStore(project),
holder.getClass(),
holder::fireScopeListeners,
coroutineScope);
}
}
}
@@ -766,6 +766,21 @@ fun <T> runUnderModalProgressIfIsEdt(task: suspend CoroutineScope.() -> T): T {
}
}
@Internal
@ScheduledForRemoval
@Deprecated(
"Use runWithModalProgressBlocking on EDT with proper owner and title, " +
"or runBlockingCancellable(+withBackgroundProgress with proper title) on BGT"
)
fun <T> runUnderModalProgressIfIsEdt(project: Project, task: suspend CoroutineScope.() -> T): T {
if (ApplicationManager.getApplication().isDispatchThread) {
return runWithModalProgressBlocking(ModalTaskOwner.project(project), "", TaskCancellation.cancellable(), task)
}
else {
return runBlockingMaybeCancellable(task)
}
}
private fun getActiveWindow(): Window? {
val window = KeyboardFocusManager.getCurrentKeyboardFocusManager().activeWindow
LOG.trace { "getActiveWindow: active window is $window" }
@@ -21,7 +21,7 @@ private fun fireProjectOpened(project: Project) {
val fireRunnable = Runnable {
// similar to com.intellij.openapi.project.impl.ProjectManagerExImplKt.openProject
app.messageBus.syncPublisher(ProjectManager.TOPIC).projectOpened(project)
runUnderModalProgressIfIsEdt {
runUnderModalProgressIfIsEdt(project) {
val startupManager = StartupManager.getInstance(project) as StartupManagerImpl
startupManager.initProject()
startupManager.runPostStartupActivities()
@@ -77,7 +77,12 @@ class PlatformProjectOpenProcessor : ProjectOpenProcessor(), CommandLineProjectO
@JvmStatic
@JvmOverloads
@Internal
fun openProjectLegacyJavaApi(virtualFile: VirtualFile, projectToClose: Project?, forceOpenInNewFrame: Boolean, instance: PlatformProjectOpenProcessor? = null): Project? {
fun openProjectLegacyJavaApi(
virtualFile: VirtualFile,
projectToClose: Project?,
forceOpenInNewFrame: Boolean,
instance: PlatformProjectOpenProcessor? = null,
): Project? {
@Suppress("DEPRECATION") // Function has no thread requirements
return runUnderModalProgressIfIsEdt { (instance ?: getInstance()).openProjectAsync(virtualFile, projectToClose, forceOpenInNewFrame) }
}
@@ -137,7 +137,7 @@ class EditorNotificationsImpl(private val project: Project, coroutineScope: Coro
fun completeAsyncTasks() {
NonBlockingReadActionImpl.waitForAsyncTaskCompletion()
@Suppress("DEPRECATION")
runUnderModalProgressIfIsEdt {
runUnderModalProgressIfIsEdt(project) {
val parentJob = coroutineScope.coroutineContext[Job]!!
while (true) {
// process all events in EDT
@@ -28,9 +28,6 @@ object NonPersistentStore : IComponentStore {
override suspend fun reloadStates(componentNames: Set<String>) {}
override fun scheduleReloadState(componentClass: Class<out PersistentStateComponent<*>>, postAction: Runnable?) {
}
override suspend fun reloadState(componentClass: Class<out PersistentStateComponent<*>>) {
}
@@ -9,6 +9,7 @@ import com.intellij.openapi.components.service
import com.intellij.openapi.extensions.PluginId
import com.intellij.openapi.util.NlsSafe
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.jetbrains.annotations.ApiStatus.Internal
import org.jetbrains.annotations.TestOnly
import java.nio.file.Path
@@ -33,8 +34,6 @@ interface IComponentStore {
suspend fun reloadState(componentClass: Class<out PersistentStateComponent<*>>)
fun scheduleReloadState(componentClass: Class<out PersistentStateComponent<*>>, postAction: Runnable? = null)
fun isReloadPossible(componentNames: Set<String>): Boolean
suspend fun save(forceSavingAllSettings: Boolean = false)
@@ -58,6 +57,21 @@ interface ComponentStoreOwner {
val componentStore: IComponentStore
}
// for poor code in java
@Deprecated("Use coroutine version")
@Internal
fun scheduleReloadState(
store: IComponentStore,
componentClass: Class<out PersistentStateComponent<*>>,
postAction: Runnable,
coroutineScope: CoroutineScope,
) {
coroutineScope.launch {
store.reloadState(componentClass)
postAction.run()
}
}
@get:Internal
val ComponentManager.stateStore: IComponentStore
get() = if (this is ComponentStoreOwner) this.componentStore else this.service<IComponentStore>()
@@ -114,7 +114,7 @@ open class TestProjectManager : ProjectManagerImpl() {
val app = ApplicationManager.getApplication()
try {
runUnderModalProgressIfIsEdt {
runUnderModalProgressIfIsEdt(project) {
coroutineScope {
runInitProjectActivities(project = project)
}
@@ -13,7 +13,7 @@ import java.util.function.Consumer
// todo rewrite PlatformTestUtil to kotlin
internal fun saveProject(project: Project, forceSavingAllSettings: Boolean = false) {
runUnderModalProgressIfIsEdt {
runUnderModalProgressIfIsEdt(project) {
StoreReloadManager.getInstance(project).reloadChangedStorageFiles()
project.stateStore.save(forceSavingAllSettings = forceSavingAllSettings)
}
@@ -32,7 +32,6 @@ import com.intellij.testFramework.DisposableRule
import com.intellij.testFramework.IndexingTestUtil
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.RuleChain
import com.intellij.util.application
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
import org.junit.jupiter.api.extension.*
import org.junit.rules.ExternalResource
@@ -217,7 +216,7 @@ open class ProjectModelRule : TestRule {
}
fun setUnloadedModules(vararg moduleName: String) {
runUnderModalProgressIfIsEdt {
runUnderModalProgressIfIsEdt(project) {
moduleManager.setUnloadedModules(moduleName.toList())
}
IndexingTestUtil.waitUntilIndexesAreReady(project)