Look for module EPs in descriptor of core plugin if there are no modules currently loaded (IDEA-255042)

GitOrigin-RevId: d095d299dfe48096152f0b374cee10eadad3d8cf
This commit is contained in:
Dmitry Jemerov
2021-01-07 18:55:16 +00:00
committed by intellij-monorepo-bot
parent b8e7608581
commit a151c2db29
2 changed files with 45 additions and 8 deletions
@@ -1185,15 +1185,22 @@ private fun doCheckExtensionsCanUnloadWithoutRestart(extensions: Map<String, Lis
?: anyModule?.extensionArea?.getExtensionPointIfRegistered<Any>(epName)
if (ep != null) {
if (!ep.isDynamic) {
if (optionalDependencyPluginId != null) {
return "Plugin ${baseDescriptor?.pluginId} is not unload-safe because of use of non-dynamic EP $epName in plugin $optionalDependencyPluginId that optionally depends on it"
}
else {
return "Plugin ${descriptor.pluginId ?: baseDescriptor?.pluginId} is not unload-safe because of extension to non-dynamic EP $epName"
}
return getNonDynamicUnloadError(epName, baseDescriptor, descriptor, optionalDependencyPluginId)
}
continue
}
if (anyModule == null) {
val corePlugin = PluginManagerCore.getPlugin(PluginManagerCore.CORE_ID)
if (corePlugin != null) {
val coreEP = findPluginExtensionPoint(corePlugin as IdeaPluginDescriptorImpl, epName)
if (coreEP != null) {
if (!coreEP.isDynamic) {
return getNonDynamicUnloadError(epName, baseDescriptor, descriptor, optionalDependencyPluginId)
}
continue
}
}
}
val contextEP = context.asSequence().mapNotNull { contextPlugin -> findPluginExtensionPoint(contextPlugin, epName) }.firstOrNull()
if (contextEP != null) {
@@ -1208,6 +1215,18 @@ private fun doCheckExtensionsCanUnloadWithoutRestart(extensions: Map<String, Lis
return null
}
private fun getNonDynamicUnloadError(epName: String,
baseDescriptor: IdeaPluginDescriptorImpl?,
descriptor: IdeaPluginDescriptorImpl,
optionalDependencyPluginId: PluginId?): String {
if (optionalDependencyPluginId != null) {
return "Plugin ${baseDescriptor?.pluginId} is not unload-safe because of use of non-dynamic EP $epName in plugin $optionalDependencyPluginId that optionally depends on it"
}
else {
return "Plugin ${descriptor.pluginId ?: baseDescriptor?.pluginId} is not unload-safe because of extension to non-dynamic EP $epName"
}
}
private fun findPluginExtensionPoint(pluginDescriptor: IdeaPluginDescriptorImpl, epName: String): ExtensionPointImpl<*>? {
return findContainerExtensionPoint(pluginDescriptor.app, epName)
?: findContainerExtensionPoint(pluginDescriptor.project, epName)
@@ -22,8 +22,11 @@ import com.intellij.openapi.components.*
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.extensions.PluginId
import com.intellij.openapi.module.ModuleConfigurationEditor
import com.intellij.openapi.options.Configurable
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationEditorProvider
import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState
import com.intellij.openapi.startup.StartupActivity
import com.intellij.openapi.util.Disposer
import com.intellij.psi.PsiFile
@@ -470,14 +473,23 @@ class DynamicPluginsTest {
DynamicPlugins::class.java.classLoader)
try {
assertThat(checked.get()).isEqualTo(1)
assertThat(Configurable.PROJECT_CONFIGURABLE.getExtensions(project).any { it.instanceClass == MyConfigurable::class.java.name }).isTrue()
assertThat(
Configurable.PROJECT_CONFIGURABLE.getExtensions(project).any { it.instanceClass == MyConfigurable::class.java.name }).isTrue()
}
finally {
Disposer.dispose(disposable)
Disposer.dispose(listenerDisposable)
}
assertThat(checked.get()).isEqualTo(2)
assertThat(Configurable.PROJECT_CONFIGURABLE.getExtensions(project).any { it.instanceClass == MyConfigurable::class.java.name }).isFalse()
assertThat(
Configurable.PROJECT_CONFIGURABLE.getExtensions(project).any { it.instanceClass == MyConfigurable::class.java.name }).isFalse()
}
@Test
fun unloadModuleEP() {
val disposable = loadExtensionWithText(
"""<moduleConfigurationEditorProvider implementation="${MyModuleConfigurationEditorProvider::class.java.name}"/>""")
Disposer.dispose(disposable)
}
@Test
@@ -699,3 +711,9 @@ private class MyRunnable : Runnable {
override fun run() {
}
}
private class MyModuleConfigurationEditorProvider : ModuleConfigurationEditorProvider {
override fun createEditors(state: ModuleConfigurationState?): Array<ModuleConfigurationEditor> {
return arrayOf()
}
}