diff --git a/platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.kt b/platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.kt index 8d0119f43494..41f57cf02fdd 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.kt +++ b/platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.kt @@ -12,6 +12,7 @@ import com.intellij.openapi.extensions.impl.ExtensionPointImpl import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.NonNls import org.jetbrains.annotations.PropertyKey +import org.jetbrains.annotations.VisibleForTesting import java.io.File import java.io.IOException import java.nio.file.Path @@ -81,7 +82,14 @@ class IdeaPluginDescriptorImpl(raw: RawPluginDescriptor, companion object { @ApiStatus.Internal - @JvmField var disableNonBundledPlugins = false + @JvmField + var disableNonBundledPlugins = false + + @VisibleForTesting + const val ON_DEMAND_ENABLED_KEY = "idea.on.demand.plugins" + + val isOnDemandEnabled + @ApiStatus.Experimental get() = java.lang.Boolean.getBoolean(ON_DEMAND_ENABLED_KEY) } @Transient @JvmField var jarFiles: List? = null @@ -105,7 +113,7 @@ class IdeaPluginDescriptorImpl(raw: RawPluginDescriptor, @JvmField val isUseIdeaClassLoader = raw.isUseIdeaClassLoader @JvmField val isBundledUpdateAllowed = raw.isBundledUpdateAllowed @JvmField internal val implementationDetail = raw.implementationDetail - @JvmField internal val onDemand = raw.onDemand + @ApiStatus.Experimental @JvmField internal val onDemand = isOnDemandEnabled && raw.onDemand @JvmField internal val isRestartRequired = raw.isRestartRequired @JvmField val packagePrefix = raw.`package` diff --git a/platform/core-impl/src/com/intellij/ide/plugins/RawPluginDescriptor.kt b/platform/core-impl/src/com/intellij/ide/plugins/RawPluginDescriptor.kt index 9e9ca19cbf11..810f3f40e093 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/RawPluginDescriptor.kt +++ b/platform/core-impl/src/com/intellij/ide/plugins/RawPluginDescriptor.kt @@ -32,7 +32,7 @@ class RawPluginDescriptor { @JvmField internal var isUseIdeaClassLoader = false @JvmField internal var isBundledUpdateAllowed = false @JvmField internal var implementationDetail = false - @JvmField internal var onDemand = false + @ApiStatus.Experimental @JvmField internal var onDemand = false @JvmField internal var isRestartRequired = false @JvmField internal var isLicenseOptional = false diff --git a/platform/core-impl/src/com/intellij/ide/plugins/XmlReader.kt b/platform/core-impl/src/com/intellij/ide/plugins/XmlReader.kt index 2122f331c73b..091b37fc5307 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/XmlReader.kt +++ b/platform/core-impl/src/com/intellij/ide/plugins/XmlReader.kt @@ -18,7 +18,7 @@ import com.intellij.util.xml.dom.createNonCoalescingXmlStreamReader import com.intellij.util.xml.dom.readXmlAsModel import org.codehaus.stax2.XMLStreamReader2 import org.codehaus.stax2.typed.TypedXMLStreamException -import org.jetbrains.annotations.ApiStatus.Internal +import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.TestOnly import java.io.IOException import java.io.InputStream @@ -31,9 +31,9 @@ import javax.xml.stream.XMLStreamException import javax.xml.stream.XMLStreamReader import javax.xml.stream.events.XMLEvent -@Internal const val PACKAGE_ATTRIBUTE = "package" -@Internal const val IMPLEMENTATION_DETAIL_ATTRIBUTE = "implementation-detail" -@Internal const val ON_DEMAND_ATTRIBUTE = "on-demand" +@ApiStatus.Internal const val PACKAGE_ATTRIBUTE = "package" +@ApiStatus.Internal const val IMPLEMENTATION_DETAIL_ATTRIBUTE = "implementation-detail" +@ApiStatus.Experimental const val ON_DEMAND_ATTRIBUTE = "on-demand" private const val defaultXPointerValue = "xpointer(/idea-plugin/*)" diff --git a/platform/platform-tests/testSrc/com/intellij/ide/plugins/PluginDescriptorTest.kt b/platform/platform-tests/testSrc/com/intellij/ide/plugins/PluginDescriptorTest.kt index c2ff786a9fbd..877fff0c7c6e 100644 --- a/platform/platform-tests/testSrc/com/intellij/ide/plugins/PluginDescriptorTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/ide/plugins/PluginDescriptorTest.kt @@ -120,8 +120,7 @@ class PluginDescriptorTest { fun testProductionPlugins() { IoTestUtil.assumeMacOS() assumeNotUnderTeamcity() - val descriptors = loadAndInitDescriptors(pluginsPath = Paths.get("/Applications/Idea.app/Contents/plugins")) - .pluginSet + val descriptors = loadPluginSet(pluginsPath = Paths.get("/Applications/Idea.app/Contents/plugins")) .allPlugins assertThat(descriptors).isNotEmpty() assertThat(descriptors.find { it.pluginId.idString == "com.intellij.java" }).isNotNull @@ -147,8 +146,8 @@ class PluginDescriptorTest { IoTestUtil.assumeMacOS() assumeNotUnderTeamcity() - val descriptors = loadAndInitDescriptors(pluginsPath = Paths.get("/Volumes/data/plugins")) - .pluginSet.allPlugins + val descriptors = loadPluginSet(pluginsPath = Paths.get("/Volumes/data/plugins")) + .allPlugins assertThat(descriptors).isNotEmpty() } @@ -251,7 +250,7 @@ class PluginDescriptorTest { 2.0 """) - val pluginSet = loadAndInitDescriptors().pluginSet + val pluginSet = loadPluginSet() val plugins = pluginSet.enabledPlugins assertThat(plugins).hasSize(1) val foo = plugins[0] @@ -341,9 +340,7 @@ class PluginDescriptorTest { """) - val pluginSet = loadAndInitDescriptors(BuildNumber.fromString("3.12")!!) - .pluginSet - + val pluginSet = loadPluginSet(BuildNumber.fromString("3.12")!!) val plugins = pluginSet.enabledPlugins assertThat(plugins).hasSize(1) val foo = plugins[0] @@ -360,7 +357,7 @@ class PluginDescriptorTest { PluginBuilder().noDepends().id("foo").version("1.0").build(pluginsPath.resolve("foo_1-0")) PluginBuilder().noDepends().id("foo").version("1.0").build(pluginsPath.resolve("foo_another")) - val pluginSet = loadAndInitDescriptors().pluginSet + val pluginSet = loadPluginSet() val plugins = pluginSet.enabledPlugins assertThat(plugins).hasSize(1) val foo = plugins[0] @@ -408,9 +405,7 @@ class PluginDescriptorTest { } private fun checkClassLoader() { - val list = loadAndInitDescriptors() - .pluginSet - .enabledPlugins + val list = loadPluginSet().enabledPlugins assertThat(list).hasSize(2) val bar = list[0] @@ -513,8 +508,7 @@ class PluginDescriptorTest { PluginBuilder().noDepends().id("foo").depends("bar").build(pluginsPath.resolve("foo")) PluginBuilder().noDepends().id("bar").build(pluginsPath.resolve("bar")) - val pluginSet = loadAndInitDescriptors(disabledPlugins = setOf("bar")) - .pluginSet + val pluginSet = loadPluginSet(disabledPlugins = setOf("bar")) assertThat(pluginSet.enabledPlugins).isEmpty() } @@ -537,8 +531,7 @@ class PluginDescriptorTest { .id("com.intellij.gradle") .build(pluginsPath.resolve("intellij.gradle")) - val result = loadAndInitDescriptors(disabledPlugins = setOf("com.intellij.gradle")) - .pluginSet + val result = loadPluginSet(disabledPlugins = setOf("com.intellij.gradle")) assertThat(result.enabledPlugins).isEmpty() } @@ -551,12 +544,19 @@ class PluginDescriptorTest { .build(pluginsPath.resolve("foo")) PluginBuilder() + .noDepends() .id("bar") .pluginDependency("foo") .build(pluginsPath.resolve("bar")) - val pluginSet = loadAndInitDescriptors().pluginSet - assertThat(pluginSet.enabledPlugins).isEmpty() + assertThat(loadPluginSet().enabledPlugins).hasSize(2) + + PlatformTestUtil.withSystemProperty( + /* key = */ IdeaPluginDescriptorImpl.ON_DEMAND_ENABLED_KEY, + /* value = */ "true", + ) { + assertThat(loadPluginSet().enabledPlugins).isEmpty() + } } private fun writeDescriptor(id: String, @Language("xml") data: String) { @@ -565,17 +565,17 @@ class PluginDescriptorTest { .write(data.trimIndent()) } - private fun loadAndInitDescriptors( + private fun loadPluginSet( buildNumber: BuildNumber = PluginManagerCore.getBuildNumber(), pluginsPath: Path = this.pluginsPath, disabledPlugins: Set = emptySet(), - ): PluginManagerState { + ): PluginSet { return PluginManagerCore.initializePlugins( - loadDescriptors(pluginsPath, buildNumber, disabledPlugins), - UrlClassLoader.build().get(), - false, - null, - ) + /* context = */ loadDescriptors(pluginsPath, buildNumber, disabledPlugins), + /* coreLoader = */ UrlClassLoader.build().get(), + /* checkEssentialPlugins = */ false, + /* parentActivity = */ null, + ).pluginSet } }