From 9818fc369833c821f66fc20ff1919ce86ed9c8eb Mon Sep 17 00:00:00 2001 From: Vadim Salavatov Date: Fri, 6 Feb 2026 15:55:24 +0100 Subject: [PATCH] IJPL-233642 wrap deferred listener calls, remember original EP GitOrigin-RevId: ea43db34b2dc41965283b6d37155523042a88cc3 --- .../ExtensionPointDeferredListenersNotification.kt | 13 +++++++++++++ .../openapi/extensions/impl/ExtensionPointImpl.kt | 6 ++++-- .../openapi/extensions/impl/ExtensionsAreaImpl.kt | 6 +++++- .../src/com/intellij/ide/plugins/DynamicPlugins.kt | 13 ++++++++++--- .../openapi/client/ClientAwareComponentManager.kt | 3 ++- .../intellij/openapi/client/ClientSessionImpl.kt | 3 ++- .../serviceContainer/ComponentManagerImpl.kt | 3 ++- 7 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionPointDeferredListenersNotification.kt diff --git a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionPointDeferredListenersNotification.kt b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionPointDeferredListenersNotification.kt new file mode 100644 index 000000000000..6fd008ea253b --- /dev/null +++ b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionPointDeferredListenersNotification.kt @@ -0,0 +1,13 @@ +// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.openapi.extensions.impl + +import com.intellij.openapi.extensions.ExtensionPoint +import com.intellij.openapi.util.IntellijInternalApi +import org.jetbrains.annotations.ApiStatus + +@IntellijInternalApi +@ApiStatus.Internal +class ExtensionPointDeferredListenersNotification( + val ep: ExtensionPointImpl<*>, + val notify: Runnable, +) \ No newline at end of file diff --git a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionPointImpl.kt b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionPointImpl.kt index a05d7e828330..2b024fd19fdc 100644 --- a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionPointImpl.kt +++ b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionPointImpl.kt @@ -847,7 +847,7 @@ sealed class ExtensionPointImpl(@JvmField val name: String, @Synchronized fun registerExtensions(descriptors: List, pluginDescriptor: PluginDescriptor, - listenerCallbacks: MutableList?) { + listenerCallbacks: MutableList?) { adaptersAreSorted = false val oldAdapters = adapters @@ -891,7 +891,9 @@ sealed class ExtensionPointImpl(@JvmField val name: String, break } - listenerCallbacks.add { notifyListeners(isRemoved = false, adapters = addedAdapters, listeners = listeners) } + listenerCallbacks.add(ExtensionPointDeferredListenersNotification(this) { + notifyListeners(isRemoved = false, adapters = addedAdapters, listeners = listeners) + }) } @TestOnly diff --git a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionsAreaImpl.kt b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionsAreaImpl.kt index 6bac2bdbf176..ac515df951d7 100644 --- a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionsAreaImpl.kt +++ b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionsAreaImpl.kt @@ -133,7 +133,11 @@ class ExtensionsAreaImpl(private val componentManager: ComponentManager) : Exten } } - fun registerExtensions(extensions: Map>, pluginDescriptor: PluginDescriptor, listenerCallbacks: MutableList?) { + fun registerExtensions( + extensions: Map>, + pluginDescriptor: PluginDescriptor, + listenerCallbacks: MutableList?, + ) { for ((descriptors, point) in intersectMaps(extensions, nameToPointMap)) { point.registerExtensions(descriptors, pluginDescriptor = pluginDescriptor, listenerCallbacks) } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/DynamicPlugins.kt b/platform/platform-impl/src/com/intellij/ide/plugins/DynamicPlugins.kt index 63d023e51e96..7f7dcc0c7a6e 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/DynamicPlugins.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/DynamicPlugins.kt @@ -49,6 +49,7 @@ import com.intellij.openapi.extensions.ExtensionDescriptor import com.intellij.openapi.extensions.ExtensionPointDescriptor import com.intellij.openapi.extensions.ExtensionPointName import com.intellij.openapi.extensions.PluginId +import com.intellij.openapi.extensions.impl.ExtensionPointDeferredListenersNotification import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.keymap.impl.BundledKeymapBean @@ -1070,7 +1071,7 @@ object DynamicPlugins { app.messageBus.syncPublisher(DynamicPluginListener.TOPIC).beforePluginLoaded(pluginDescriptor) app.runWriteAction { try { - val listenerCallbacks = mutableListOf() + val listenerCallbacks = mutableListOf() // 4. load into service container loadModules(modules = pluginWithContentModules, app = app, listenerCallbacks = listenerCallbacks) @@ -1093,7 +1094,9 @@ object DynamicPlugins { PluginManagerCore.setPluginSet(pluginSet) - listenerCallbacks.forEach(Runnable::run) + listenerCallbacks.forEach { + it.notify.run() + } DynamicPluginsUsagesCollector.logDescriptorLoad(pluginDescriptor) PluginManagerCore.clearPluginNonLoadReasonFor(pluginDescriptor.pluginId) @@ -1278,7 +1281,11 @@ private fun optionalDependenciesOnPlugin( .toSet() } -private fun loadModules(modules: List, app: ApplicationImpl, listenerCallbacks: MutableList) { +private fun loadModules( + modules: List, + app: ApplicationImpl, + listenerCallbacks: MutableList, +) { app.registerComponents(modules = modules, app = app, listenerCallbacks = listenerCallbacks) for (openProject in getOpenedProjects()) { openProject.getComponentManagerImpl().registerComponents(modules = modules, app = app, listenerCallbacks = listenerCallbacks) diff --git a/platform/platform-impl/src/com/intellij/openapi/client/ClientAwareComponentManager.kt b/platform/platform-impl/src/com/intellij/openapi/client/ClientAwareComponentManager.kt index f09c0b5b9fe4..c665fc0faf59 100644 --- a/platform/platform-impl/src/com/intellij/openapi/client/ClientAwareComponentManager.kt +++ b/platform/platform-impl/src/com/intellij/openapi/client/ClientAwareComponentManager.kt @@ -7,6 +7,7 @@ import com.intellij.ide.plugins.IdeaPluginDescriptorImpl import com.intellij.openapi.application.Application import com.intellij.openapi.components.ServiceDescriptor import com.intellij.openapi.diagnostic.logger +import com.intellij.openapi.extensions.impl.ExtensionPointDeferredListenersNotification import com.intellij.serviceContainer.ComponentManagerImpl import com.intellij.serviceContainer.throwAlreadyDisposedError import kotlinx.coroutines.CoroutineScope @@ -64,7 +65,7 @@ abstract class ClientAwareComponentManager: ComponentManagerImpl { final override fun registerComponents( modules: List, app: Application?, - listenerCallbacks: MutableList? + listenerCallbacks: MutableList? ) { super.registerComponents(modules = modules, app = app, diff --git a/platform/platform-impl/src/com/intellij/openapi/client/ClientSessionImpl.kt b/platform/platform-impl/src/com/intellij/openapi/client/ClientSessionImpl.kt index 469b69e3f701..2101d73c773d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/client/ClientSessionImpl.kt +++ b/platform/platform-impl/src/com/intellij/openapi/client/ClientSessionImpl.kt @@ -15,6 +15,7 @@ import com.intellij.openapi.components.impl.stores.IComponentStore import com.intellij.openapi.components.service import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.diagnostic.logger +import com.intellij.openapi.extensions.impl.ExtensionPointDeferredListenersNotification import com.intellij.openapi.project.Project import com.intellij.openapi.project.ProjectManager import com.intellij.openapi.project.impl.ProjectImpl @@ -99,7 +100,7 @@ abstract class ClientSessionImpl( final override fun registerComponents( modules: List, app: Application?, - listenerCallbacks: MutableList? + listenerCallbacks: MutableList? ) { for (rootModule in modules) { registerServices(getContainerDescriptor(rootModule).services, rootModule) diff --git a/platform/service-container/src/com/intellij/serviceContainer/ComponentManagerImpl.kt b/platform/service-container/src/com/intellij/serviceContainer/ComponentManagerImpl.kt index 5152f22639d8..9576ff57ff60 100644 --- a/platform/service-container/src/com/intellij/serviceContainer/ComponentManagerImpl.kt +++ b/platform/service-container/src/com/intellij/serviceContainer/ComponentManagerImpl.kt @@ -25,6 +25,7 @@ import com.intellij.openapi.components.impl.stores.ComponentStoreOwner import com.intellij.openapi.components.impl.stores.IComponentStore import com.intellij.openapi.diagnostic.* import com.intellij.openapi.extensions.* +import com.intellij.openapi.extensions.impl.ExtensionPointDeferredListenersNotification import com.intellij.openapi.extensions.impl.ExtensionPointImpl import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl import com.intellij.openapi.extensions.impl.createExtensionPoints @@ -316,7 +317,7 @@ abstract class ComponentManagerImpl( open fun registerComponents( modules: List, app: Application?, - listenerCallbacks: MutableList? = null, + listenerCallbacks: MutableList? = null, ) { val activityNamePrefix = activityNamePrefix()