IJPL-241314 keep action group dependencies explicit

Plugin XML generation now records action group declarations and add-to-group references from plugin descriptors. When a plugin contributes an action into a group declared by another content module, generated dependencies keep that module explicit even if the module is embedded in product layouts.

This makes plugin loading order match action registration requirements, including Kotlin's XDebugger.Settings contribution in tests, and prevents bootstrap failures caused by missing action groups.

IJ-MR-184958 IJ-MR-184993 IJ-MR-179029 IJ-MR-184126 IJ-MR-181153 IJ-MR-146078 IJ-MR-175479 IJ-MR-186058 IJ-MR-193195 IJ-MR-196957 IJ-MR-199124 IJ-MR-197441 IJ-MR-204135 IJ-MR-204674 IJ-MR-205883

GitOrigin-RevId: 43bfdc4b53dfa836ddbaf626e10399407d2fad24
This commit is contained in:
Vladimir Krivosheev
2026-06-02 14:03:36 +00:00
committed by intellij-monorepo-bot
parent 87ba38ba75
commit 008c81e916
28 changed files with 324 additions and 18 deletions
@@ -50,6 +50,10 @@ internal class ModuleDescriptorCache(
@JvmField val registeredServiceKeys: Set<String> = emptySet(),
/** Service keys registered with `overrides="true"`. */
@JvmField val overridingServiceKeys: Set<String> = emptySet(),
/** Action group IDs declared by this descriptor. */
@JvmField val declaredActionGroupIds: Set<String> = emptySet(),
/** Action group IDs referenced by this descriptor. */
@JvmField val referencedActionGroupIds: Set<String> = emptySet(),
/**
* Suppressible error if the descriptor has issues (e.g., non-standard XML root element).
* Collected by generators and filtered through suppression config based on [UnsuppressedPipelineError.suppressionKey].
@@ -142,6 +146,8 @@ internal class ModuleDescriptorCache(
existingModuleDependencies = parseResult.moduleDependencies,
registeredServiceKeys = parseResult.registeredServiceKeys,
overridingServiceKeys = parseResult.overridingServiceKeys,
declaredActionGroupIds = parseResult.declaredActionGroupIds,
referencedActionGroupIds = parseResult.referencedActionGroupIds,
suppressibleError = suppressibleError,
)
}
@@ -121,6 +121,10 @@ internal data class PluginContentInfo(
* Used for IDE capability markers (e.g., `com.intellij.modules.java`, `com.intellij.modules.ruby-capable`).
*/
@JvmField val pluginAliases: List<PluginId> = emptyList(),
/** Action group IDs declared by this plugin.xml and its xi:includes. */
@JvmField val declaredActionGroupIds: Set<String> = emptySet(),
/** Action group IDs referenced by this plugin.xml and its xi:includes. */
@JvmField val referencedActionGroupIds: Set<String> = emptySet(),
) {
/** True if DSL-defined (content computed from spec, not extracted from disk) */
val isDslDefined: Boolean get() = source == PluginSource.DSL_TEST
@@ -244,6 +248,8 @@ internal suspend fun extractPluginContent(
source = source,
legacyDepends = extractLegacyDepends(content),
pluginAliases = extractedContent.pluginAliases,
declaredActionGroupIds = extractedContent.declaredActionGroupIds,
referencedActionGroupIds = extractedContent.referencedActionGroupIds,
)
}
@@ -253,6 +259,8 @@ private class ExtractedContent(
@JvmField val pluginDependencies: Set<PluginId>,
/** Plugin aliases declared via `<module value="..."/>` elements (main file + xi:includes) */
@JvmField val pluginAliases: List<PluginId>,
@JvmField val declaredActionGroupIds: Set<String>,
@JvmField val referencedActionGroupIds: Set<String>,
/** Deps by source file: first entry = main plugin.xml, subsequent = xi:includes */
@JvmField val depsByFile: List<FileDepInfo>,
)
@@ -273,6 +281,8 @@ private suspend fun extractContentModules(
val allModuleDependencies = LinkedHashSet<ContentModuleName>()
val allPluginDependencies = LinkedHashSet<PluginId>()
val allPluginAliases = LinkedHashSet<PluginId>()
val allDeclaredActionGroupIds = LinkedHashSet<String>()
val allReferencedActionGroupIds = LinkedHashSet<String>()
val depsByFile = ArrayList<FileDepInfo>()
val processedPaths = HashSet<String>()
@@ -295,6 +305,8 @@ private suspend fun extractContentModules(
for (alias in result.pluginAliases) {
allPluginAliases.add(PluginId(alias))
}
allDeclaredActionGroupIds.addAll(result.declaredActionGroupIds)
allReferencedActionGroupIds.addAll(result.referencedActionGroupIds)
// Track deps per file
depsByFile.add(FileDepInfo(relativePath = path, moduleDependencies = moduleDeps, pluginDependencies = pluginDeps))
}
@@ -328,6 +340,8 @@ private suspend fun extractContentModules(
moduleDependencies = allModuleDependencies,
pluginDependencies = allPluginDependencies,
pluginAliases = allPluginAliases.toList(),
declaredActionGroupIds = allDeclaredActionGroupIds,
referencedActionGroupIds = allReferencedActionGroupIds,
depsByFile = depsByFile,
)
}
@@ -13,7 +13,9 @@ import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import org.jetbrains.intellij.build.productLayout.debug
import org.jetbrains.intellij.build.productLayout.config.SuppressionConfig
import org.jetbrains.intellij.build.productLayout.dependency.ModuleDescriptorCache
import org.jetbrains.intellij.build.productLayout.dependency.PluginContentProvider
import org.jetbrains.intellij.build.productLayout.deps.PluginDependencyPlan
import org.jetbrains.intellij.build.productLayout.deps.PluginDependencyPlanOutput
@@ -66,6 +68,7 @@ internal object PluginDependencyPlanner : PipelineNode {
// DSL-defined plugins are generated from Kotlin specs and skipped here.
val tasks = ArrayList<Deferred<PluginDependencyPlan?>>()
val pluginGraphDeps = collectPluginGraphDeps(graph = graph, allRealProductNames = allRealProductNames)
val actionGroupProviderModules = buildActionGroupProviderModules(graph = graph, descriptorCache = model.descriptorCache)
for (graphDeps in pluginGraphDeps) {
if (graphDeps.isDslDefined) continue
tasks.add(async {
@@ -73,6 +76,7 @@ internal object PluginDependencyPlanner : PipelineNode {
graph = graph,
graphDeps = graphDeps,
pluginContentCache = pluginContentCache,
actionGroupProviderModules = actionGroupProviderModules,
suppressionConfig = suppressionConfig,
updateSuppressions = updateSuppressions,
emitError = ctx::emitError,
@@ -90,6 +94,7 @@ internal data class PluginGraphDeps(
val pluginContentModuleName: ContentModuleName,
@JvmField val isDslDefined: Boolean,
@JvmField val isTest: Boolean,
@JvmField val contentModules: Set<ContentModuleName>,
@JvmField val jpsModuleDependencies: Set<ContentModuleName>,
@JvmField val jpsPluginDependencies: Set<PluginId>,
/** Plugin deps declared via legacy `<depends ... config-file="...">` in plugin.xml. */
@@ -156,6 +161,7 @@ internal fun collectPluginGraphDeps(
pluginContentModuleName = pluginName,
isDslDefined = plugin.isDslDefined,
isTest = plugin.isTest,
contentModules = contentModules,
jpsModuleDependencies = moduleDeps,
jpsPluginDependencies = pluginDeps,
legacyConfigFilePluginDependencies = legacyConfigFilePluginDeps,
@@ -167,6 +173,59 @@ internal fun collectPluginGraphDeps(
return results
}
internal suspend fun buildActionGroupProviderModules(
graph: PluginGraph,
descriptorCache: ModuleDescriptorCache,
): Map<String, Set<ContentModuleName>> {
val moduleNames = LinkedHashSet<ContentModuleName>()
graph.query {
contentModules { contentModule ->
if (hasContentSource(contentModule.id)) {
moduleNames.add(contentModule.contentName())
}
}
}
val providers = LinkedHashMap<String, MutableSet<ContentModuleName>>()
coroutineScope {
moduleNames.map { moduleName ->
async {
moduleName to descriptorCache.getOrAnalyze(moduleName.value)?.declaredActionGroupIds.orEmpty()
}
}.awaitAll()
}.forEach { (moduleName, groupIds) ->
for (groupId in groupIds) {
providers.getOrPut(groupId) { LinkedHashSet() }.add(moduleName)
}
}
return providers
}
internal fun computeActionGroupModuleDependencies(
pluginInfo: PluginContentInfo,
graphDeps: PluginGraphDeps,
actionGroupProviderModules: Map<String, Set<ContentModuleName>>,
): Set<ContentModuleName> {
if (pluginInfo.referencedActionGroupIds.isEmpty()) {
return emptySet()
}
val result = LinkedHashSet<ContentModuleName>()
for (groupId in pluginInfo.referencedActionGroupIds) {
val providers = actionGroupProviderModules[groupId] ?: continue
for (provider in providers) {
if (provider == graphDeps.pluginContentModuleName || provider in graphDeps.contentModules) {
continue
}
result.add(provider)
debug("missingDeps") {
"actionGroupOrder plugin=${graphDeps.pluginContentModuleName.value} group=$groupId dep=${provider.value}"
}
}
}
return result
}
/**
* Container for filtered plugin dependencies.
*
@@ -193,6 +252,7 @@ private suspend fun buildPluginDependencyPlan(
graph: PluginGraph,
graphDeps: PluginGraphDeps,
pluginContentCache: PluginContentProvider,
actionGroupProviderModules: Map<String, Set<ContentModuleName>>,
suppressionConfig: SuppressionConfig,
updateSuppressions: Boolean,
emitError: (org.jetbrains.intellij.build.productLayout.model.error.ValidationError) -> Unit,
@@ -215,13 +275,20 @@ private suspend fun buildPluginDependencyPlan(
val mainDependencyEntries = extractDependenciesEntries(info.pluginXmlContent)
val managedXmlModuleDeps = mainDependencyEntries?.managedModuleNames?.mapTo(HashSet(), ::ContentModuleName) ?: existingXmlModuleDeps
val managedXmlPluginDeps = mainDependencyEntries?.managedPluginIds?.mapTo(HashSet(), ::PluginId) ?: existingXmlPluginDeps
val actionGroupModuleDeps = computeActionGroupModuleDependencies(
pluginInfo = info,
graphDeps = graphDeps,
actionGroupProviderModules = actionGroupProviderModules,
)
val effectiveJpsModuleDependencies = graphDeps.jpsModuleDependencies + actionGroupModuleDeps
val effectiveGraphDeps = graphDeps.copy(jpsModuleDependencies = effectiveJpsModuleDependencies)
val effectiveJpsPluginDependencies = graphDeps.jpsPluginDependencies - graphDeps.legacyConfigFilePluginDependencies
val suppressedModules = suppressionConfig.getPluginSuppressedModules(pluginContentModuleName)
val suppressedPlugins = suppressionConfig.getPluginSuppressedPlugins(pluginContentModuleName)
val moduleHandling = computeExistingDependencyHandling(
updateSuppressions = updateSuppressions,
existingXmlDeps = existingXmlModuleDeps,
jpsDeps = graphDeps.jpsModuleDependencies,
jpsDeps = effectiveJpsModuleDependencies,
suppressedDeps = suppressedModules,
xmlOnlySuppressionCandidateDeps = managedXmlModuleDeps,
)
@@ -235,7 +302,7 @@ private suspend fun buildPluginDependencyPlan(
)
val deps = filterPluginDependencies(
graphDeps = graphDeps,
graphDeps = effectiveGraphDeps,
pluginInfo = info,
jpsPluginDependencies = effectiveJpsPluginDependencies,
suppressedModules = moduleHandling.effectiveSuppressedDeps,
@@ -25,7 +25,9 @@ import org.jetbrains.intellij.build.productLayout.deps.ContentModuleDependencyPl
import org.jetbrains.intellij.build.productLayout.deps.ContentModuleDependencyPlanOutput
import org.jetbrains.intellij.build.productLayout.discovery.PluginContentInfo
import org.jetbrains.intellij.build.productLayout.generator.PluginGraphDeps
import org.jetbrains.intellij.build.productLayout.generator.buildActionGroupProviderModules
import org.jetbrains.intellij.build.productLayout.generator.collectPluginGraphDeps
import org.jetbrains.intellij.build.productLayout.generator.computeActionGroupModuleDependencies
import org.jetbrains.intellij.build.productLayout.generator.computeAliasPreservedPluginDeps
import org.jetbrains.intellij.build.productLayout.generator.computeExistingDependencyHandling
import org.jetbrains.intellij.build.productLayout.generator.embeddedCheckProductNames
@@ -125,6 +127,7 @@ internal suspend fun generatePluginDependencies(
val allRealProductNames = embeddedCheckProductNames(testSetup.products.map { it.name })
val pluginGraphDeps = collectPluginGraphDeps(graph = graph, allRealProductNames = allRealProductNames)
.associateBy { it.pluginContentModuleName.value }
val actionGroupProviderModules = buildActionGroupProviderModules(graph = graph, descriptorCache = descriptorCache)
val generationOutputs = plugins.map { pluginModuleName ->
async {
@@ -137,6 +140,7 @@ internal suspend fun generatePluginDependencies(
allRealProductNames = allRealProductNames,
outputProvider = outputProvider,
descriptorCache = descriptorCache,
actionGroupProviderModules = actionGroupProviderModules,
suppressionConfig = suppressionConfig,
updateSuppressions = updateSuppressions,
strategy = strategy,
@@ -231,6 +235,7 @@ private suspend fun generatePluginDependency(
allRealProductNames: Set<String>,
outputProvider: ModuleOutputProvider,
descriptorCache: ModuleDescriptorCache,
actionGroupProviderModules: Map<String, Set<ContentModuleName>>,
suppressionConfig: SuppressionConfig,
updateSuppressions: Boolean,
strategy: FileUpdateStrategy,
@@ -249,13 +254,20 @@ private suspend fun generatePluginDependency(
val mainDependencyEntries = extractDependenciesEntries(info.pluginXmlContent)
val managedXmlModuleDeps = mainDependencyEntries?.managedModuleNames?.mapTo(HashSet(), ::ContentModuleName) ?: existingXmlModuleDeps
val managedXmlPluginDeps = mainDependencyEntries?.managedPluginIds?.mapTo(HashSet(), ::PluginId) ?: existingXmlPluginDeps
val actionGroupModuleDeps = computeActionGroupModuleDependencies(
pluginInfo = info,
graphDeps = graphDeps,
actionGroupProviderModules = actionGroupProviderModules,
)
val effectiveJpsModuleDependencies = graphDeps.jpsModuleDependencies + actionGroupModuleDeps
val effectiveGraphDeps = graphDeps.copy(jpsModuleDependencies = effectiveJpsModuleDependencies)
val effectiveJpsPluginDependencies = graphDeps.jpsPluginDependencies - graphDeps.legacyConfigFilePluginDependencies
val suppressedModules = effectiveConfig.getPluginSuppressedModules(pluginContentModuleName)
val suppressedPlugins = effectiveConfig.getPluginSuppressedPlugins(pluginContentModuleName)
val moduleHandling = computeExistingDependencyHandling(
updateSuppressions = updateSuppressions,
existingXmlDeps = existingXmlModuleDeps,
jpsDeps = graphDeps.jpsModuleDependencies,
jpsDeps = effectiveJpsModuleDependencies,
suppressedDeps = suppressedModules,
xmlOnlySuppressionCandidateDeps = managedXmlModuleDeps,
)
@@ -271,7 +283,7 @@ private suspend fun generatePluginDependency(
val effectiveSuppressedPlugins = pluginHandling.effectiveSuppressedDeps
val deps = filterPluginDependencies(
graphDeps = graphDeps,
graphDeps = effectiveGraphDeps,
pluginInfo = info,
jpsPluginDependencies = effectiveJpsPluginDependencies,
suppressedModules = effectiveSuppressedModules,
@@ -6,7 +6,6 @@ import com.intellij.platform.pluginGraph.PluginGraph
import com.intellij.platform.pluginGraph.PluginId
import com.intellij.platform.pluginGraph.TargetName
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat
import org.jetbrains.intellij.build.productLayout.TestFailureLogger
@@ -205,6 +204,59 @@ class PluginXmlGenerationTest {
}
}
@Test
fun `plugin action group reference generates module dependency on group owner`(@TempDir tempDir: Path) {
runBlocking(Dispatchers.Default) {
val setup = pluginTestSetup(tempDir) {
contentModule("intellij.platform.debugger.impl.ui") {
descriptor = """
|<idea-plugin package="com.intellij.xdebugger.impl.ui">
| <actions>
| <group id="XDebugger.Settings"/>
| </actions>
|</idea-plugin>
""".trimMargin()
}
contentModule("intellij.kotlin.jvm.debugger.core") {
descriptor = """<idea-plugin package="org.jetbrains.kotlin.idea.debugger.core"/>"""
}
plugin("kotlin.plugin") {
pluginId = "org.jetbrains.kotlin"
content("intellij.kotlin.jvm.debugger.core")
}
product("IDEA") {
bundlesPlugin("kotlin.plugin")
moduleSet("debugger") {
module(
"intellij.platform.debugger.impl.ui",
com.intellij.platform.pluginSystem.parser.impl.elements.ModuleLoadingRuleValue.EMBEDDED,
)
}
}
}
val kotlinInfo = setup.pluginContentInfos.getValue("kotlin.plugin").withReferencedActionGroup("XDebugger.Settings")
val pluginContentCache = StubPluginContentCache(setup.pluginContentInfos + ("kotlin.plugin" to kotlinInfo))
val result = generatePluginDependencies(
plugins = listOf("kotlin.plugin"),
pluginContentCache = pluginContentCache,
testSetup = setup,
graph = setup.pluginGraph,
descriptorCache = ModuleDescriptorCache(setup.jps.outputProvider),
suppressionConfig = SuppressionConfig(),
strategy = setup.strategy,
testFrameworkContentModules = emptySet(),
)
assertThat(result.errors).isEmpty()
val pluginXmlDiff = setup.strategy.getDiffs().single { it.path.toString().contains("kotlin/plugin") }
assertThat(pluginXmlDiff.expectedContent)
.describedAs("Kotlin plugin.xml should depend on the content module declaring the referenced action group")
.contains("<module name=\"intellij.platform.debugger.impl.ui\"/>")
}
}
@Test
fun `manual alias plugin dependency is preserved in plugin xml`(@TempDir tempDir: Path) {
runBlocking(Dispatchers.Default) {
@@ -320,6 +372,20 @@ private fun PluginContentInfo.withManualPluginDependency(pluginId: PluginId): Pl
)
}
private fun PluginContentInfo.withReferencedActionGroup(groupId: String): PluginContentInfo {
val actionXml = """
| <actions>
| <action id="Kotlin.XDebugger.ToggleKotlinVariableView" class="org.jetbrains.kotlin.idea.debugger.core.ToggleKotlinVariablesView">
| <add-to-group group-id="$groupId"/>
| </action>
| </actions>
""".trimMargin()
return copy(
pluginXmlContent = pluginXmlContent.replace("</idea-plugin>", "$actionXml\n</idea-plugin>"),
referencedActionGroupIds = setOf(groupId),
)
}
private fun PluginContentInfo.withManualAndGeneratedPluginDependency(pluginId: PluginId): PluginContentInfo {
val dependencyTag = "<plugin id=\"${pluginId.value}\"/>"
val updatedPluginXmlContent = pluginXmlContent.replace(
@@ -120,11 +120,9 @@ abstract class KotlinPluginBuilder(val kind : KotlinPluginKind = System.getPrope
"intellij.kotlin.projectWizard.maven",
"intellij.kotlin.projectWizard.gradle",
"intellij.kotlin.projectWizard.compose",
"intellij.kotlin.jvm.debugger.base.util",
"intellij.kotlin.jvm.debugger.core",
"kotlin.jvm-debugger.evaluation",
"intellij.kotlin.jvm.debugger.evaluation",
"intellij.kotlin.jvm.debugger.coroutines",
"intellij.kotlin.jvm.debugger.eval4j",
"intellij.kotlin.uast.base",
"intellij.kotlin.uast.idea.base",
@@ -9,6 +9,7 @@ val compileOnlyDependenciesInCommunity: List<Pair<String, String>> = listOf(
"*" to "intellij.platform.multiplatformSupport", // references are replaced by expects-compiler-plugin
"*" to "fleet.util.multiplatform", // references are replaced by expects-compiler-plugin
"*" to "intellij.platform.compose.compilerPlugin", // dependency is needed for compose compiler plugin
"intellij.kotlin.jvm.debugger.coroutines" to "intellij.java.rt", // module is used to compile debugger helper classes for external processes
"intellij.java.rt" to "intellij.libraries.junit4", // module is used in external processes where the library from user's project is added to the classpath
"intellij.platform.util" to "intellij.platform.util.troveCompileOnly", //used only for compilation of deprecated FileUtil.FILE_HASHING_STRATEGY left for compatibility
)
@@ -1,4 +1,4 @@
<idea-plugin>
<idea-plugin visibility="internal">
<!-- region Generated dependencies - run `Generate Product Layouts` to regenerate -->
<dependencies>
<module name="intellij.libraries.bouncy.castle.provider"/>
@@ -75,6 +75,12 @@ object PluginXmlConst {
const val ACTIONS_ELEM: String = "actions"
const val ACTIONS_RESOURCE_BUNDLE_ATTR: String = "resource-bundle"
const val ACTION_ELEM: String = "action"
const val ACTION_GROUP_ELEM: String = "group"
const val ACTION_GROUP_ID_ATTR: String = "id"
const val ACTION_OVERRIDES_ATTR: String = "overrides"
const val ADD_TO_GROUP_ELEM: String = "add-to-group"
const val ADD_TO_GROUP_GROUP_ID_ATTR: String = "group-id"
const val APPLICATION_LISTENERS_ELEM: String = "applicationListeners"
const val PROJECT_LISTENERS_ELEM: String = "projectListeners"
@@ -1077,6 +1077,10 @@ class ContentParseResult(
@JvmField val registeredServiceKeys: Set<String> = emptySet(),
/** Service keys registered with `overrides="true"`. */
@JvmField val overridingServiceKeys: Set<String> = emptySet(),
/** Action group IDs declared by `<actions><group id="...">`. */
@JvmField val declaredActionGroupIds: Set<String> = emptySet(),
/** Action group IDs referenced by `<add-to-group group-id="...">`. */
@JvmField val referencedActionGroupIds: Set<String> = emptySet(),
)
/**
@@ -1087,6 +1091,7 @@ class ContentParseResult(
* - `<content><module>` elements
* - `xi:include` elements (at root level)
* - service registrations
* - action group declarations and references
*
* All other elements are skipped efficiently.
*/
@@ -1116,6 +1121,8 @@ private fun parseElementForContentAndIncludes(reader: XMLStreamReader2): Content
val pluginAliases = ArrayList<String>()
val registeredServiceKeys = HashSet<String>()
val overridingServiceKeys = HashSet<String>()
val declaredActionGroupIds = HashSet<String>()
val referencedActionGroupIds = HashSet<String>()
consumeChildElements(reader) { localName ->
when (localName) {
PluginXmlConst.INCLUDE_ELEM if reader.namespaceURI == PluginXmlConst.XINCLUDE_NAMESPACE_URI -> {
@@ -1168,6 +1175,9 @@ private fun parseElementForContentAndIncludes(reader: XMLStreamReader2): Content
PluginXmlConst.EXTENSIONS_ELEM -> {
readRegisteredServiceKeys(reader, registeredServiceKeys, overridingServiceKeys)
}
PluginXmlConst.ACTIONS_ELEM -> {
readActionGroupIds(reader, declaredActionGroupIds, referencedActionGroupIds)
}
else -> {
// Recursively check nested elements for xi:includes (they can appear at root level only,
// but we still need to traverse to find them in case of nested structures)
@@ -1186,9 +1196,58 @@ private fun parseElementForContentAndIncludes(reader: XMLStreamReader2): Content
pluginAliases = pluginAliases,
registeredServiceKeys = registeredServiceKeys,
overridingServiceKeys = overridingServiceKeys,
declaredActionGroupIds = declaredActionGroupIds,
referencedActionGroupIds = referencedActionGroupIds,
)
}
private fun readActionGroupIds(
reader: XMLStreamReader2,
declaredActionGroupIds: MutableSet<String>,
referencedActionGroupIds: MutableSet<String>,
) {
consumeChildElements(reader) { elementName ->
readActionElementGroupIds(reader, elementName, declaredActionGroupIds, referencedActionGroupIds)
}
}
private fun readActionElementGroupIds(
reader: XMLStreamReader2,
elementName: String,
declaredActionGroupIds: MutableSet<String>,
referencedActionGroupIds: MutableSet<String>,
) {
when (elementName) {
PluginXmlConst.ACTION_GROUP_ELEM -> {
if (!isActionOverride(reader)) {
XmlReadUtils.findAttributeValue(reader, PluginXmlConst.ACTION_GROUP_ID_ATTR)?.let(declaredActionGroupIds::add)
}
consumeChildElements(reader) { childName ->
readActionElementGroupIds(reader, childName, declaredActionGroupIds, referencedActionGroupIds)
}
}
PluginXmlConst.ACTION_ELEM -> {
consumeChildElements(reader) { childName ->
readActionElementGroupIds(reader, childName, declaredActionGroupIds, referencedActionGroupIds)
}
}
PluginXmlConst.ADD_TO_GROUP_ELEM -> {
XmlReadUtils.findAttributeValue(reader, PluginXmlConst.ADD_TO_GROUP_GROUP_ID_ATTR)?.let(referencedActionGroupIds::add)
reader.skipElement()
}
else -> reader.skipElement()
}
}
private fun isActionOverride(reader: XMLStreamReader2): Boolean {
for (i in 0 until reader.attributeCount) {
if (reader.getAttributeLocalName(i) == PluginXmlConst.ACTION_OVERRIDES_ATTR) {
return reader.getAttributeAsBoolean(i)
}
}
return false
}
private fun readRegisteredServiceKeys(
reader: XMLStreamReader2,
registeredServiceKeys: MutableSet<String>,
+4
View File
@@ -18,12 +18,14 @@ jvm_library(
"@lib//:kotlin-test",
"//java/testFramework",
"@lib//:grazie-tests-org-jetbrains-intellij-deps-languagetool-languagetool-core",
"//xml/dom-impl",
"//platform/structuralsearch:structuralSearch",
"//module-set-plugins/generated/intellij.moduleSet.plugin.structuralSearch:moduleSet-plugin-structuralSearch",
"//module-set-plugins/generated/intellij.moduleSet.plugin.structureView:moduleSet-plugin-structureView",
"//module-set-plugins/generated/intellij.moduleSet.plugin.todoView:moduleSet-plugin-todoView",
"//libraries/misc/plugin",
"//platform/vcs-api:vcs",
"//platform/testRunner/plugin",
]
)
@@ -133,12 +135,14 @@ jvm_library(
],
runtime_deps = [
":grazie-tests",
"//xml/dom-impl:dom-impl_test_lib",
"//platform/structuralsearch:structuralSearch_test_lib",
"//module-set-plugins/generated/intellij.moduleSet.plugin.structuralSearch:moduleSet-plugin-structuralSearch_test_lib",
"//module-set-plugins/generated/intellij.moduleSet.plugin.structureView:moduleSet-plugin-structureView_test_lib",
"//module-set-plugins/generated/intellij.moduleSet.plugin.todoView:moduleSet-plugin-todoView_test_lib",
"//libraries/misc/plugin:plugin_test_lib",
"//platform/ide-core:ide-core_test_lib",
"//platform/testRunner/plugin:plugin_test_lib",
]
)
### auto-generated section `build intellij.grazie.tests` end
@@ -360,6 +360,7 @@
<orderEntry type="module" module-name="intellij.platform.vcs.impl" scope="TEST" />
<orderEntry type="module" module-name="intellij.xml.psi" scope="TEST" />
<orderEntry type="module" module-name="intellij.xml.parser" scope="TEST" />
<orderEntry type="module" module-name="intellij.xml.dom.impl" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.grazie.java" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.structuralSearch" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.moduleSet.plugin.structuralSearch" scope="RUNTIME" />
@@ -383,5 +384,6 @@
<orderEntry type="module" module-name="intellij.platform.ide.core" scope="TEST" />
<orderEntry type="module" module-name="intellij.libraries.fastutil" scope="TEST" />
<orderEntry type="module" module-name="intellij.libraries.kotlinx.collections.immutable" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.testRunner.plugin" scope="RUNTIME" />
</component>
</module>
+2
View File
@@ -9,6 +9,7 @@ jvm_library(
runtime_deps = [
"//plugins/junit5_rt:junit-v5-rt",
"//platform/smRunner",
"//platform/testRunner/plugin",
]
)
@@ -96,6 +97,7 @@ jvm_library(
":junit-v5-rt-tests",
"//platform/platform-util-io:ide-util-io_test_lib",
"//platform/ide-core:ide-core_test_lib",
"//platform/testRunner/plugin:plugin_test_lib",
]
)
### auto-generated section `build intellij.junit.v5.rt.tests` end
@@ -44,6 +44,7 @@
<orderEntry type="module" module-name="intellij.platform.debugger.impl.tests" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.codeStyle" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.testRunner" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.testRunner.plugin" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.statistics" scope="TEST" />
</component>
</module>
+5 -1
View File
@@ -6,7 +6,10 @@ jvm_library(
module_name = "intellij.junit.v6.rt.tests",
visibility = ["//visibility:public"],
srcs = glob([], allow_empty = True),
runtime_deps = ["//platform/smRunner"]
runtime_deps = [
"//platform/smRunner",
"//platform/testRunner/plugin",
]
)
jvm_library(
@@ -81,6 +84,7 @@ jvm_library(
":junit-v6-rt-tests",
"//platform/platform-util-io:ide-util-io_test_lib",
"//platform/ide-core:ide-core_test_lib",
"//platform/testRunner/plugin:plugin_test_lib",
]
)
### auto-generated section `build intellij.junit.v6.rt.tests` end
@@ -37,6 +37,7 @@
<orderEntry type="module" module-name="intellij.regexp.tests" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.debugger.impl.tests" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.testRunner" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.testRunner.plugin" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.statistics" scope="TEST" />
</component>
</module>
@@ -13,6 +13,7 @@
<module name="intellij.kotlin.base.externalSystem"/>
<module name="intellij.kotlin.gradle.codeInsight.common"/>
<module name="intellij.kotlin.gradle.gradle"/>
<module name="intellij.kotlin.jvm.debugger.coroutines"/>
<module name="intellij.kotlin.runConfigurations.jvm"/>
<module name="intellij.platform.smRunner"/>
<module name="intellij.platform.testRunner"/>
@@ -155,7 +155,13 @@ jvm_library(
name = "kotlin-gradle-scripting-tests",
module_name = "intellij.kotlin.gradle.scripting.tests",
visibility = ["//visibility:public"],
srcs = glob([], allow_empty = True)
srcs = glob([], allow_empty = True),
runtime_deps = [
"//plugins/kotlin/plugin/k2",
"//platform/testRunner/plugin",
"//plugins/gradle/plugin",
"//plugins/gradle/java/plugin",
]
)
jvm_library(
@@ -172,8 +178,6 @@ jvm_library(
"@lib//:kotlin-stdlib",
"//platform/projectModel-api:projectModel",
"//platform/projectModel-api:projectModel_test_lib",
"//plugins/kotlin/plugin/k2",
"//plugins/kotlin/plugin/k2:k2_test_lib",
"//platform/editor-ui-api:editor-ui",
"//platform/editor-ui-api:editor-ui_test_lib",
"//platform/platform-api:ide",
@@ -201,6 +205,10 @@ jvm_library(
"//platform/external-system-impl:externalSystem-impl_test_lib",
"//platform/execution",
"//platform/execution:execution_test_lib",
"//platform/smRunner",
"//platform/smRunner:smRunner_test_lib",
"//platform/testRunner",
"//platform/testRunner:testRunner_test_lib",
"//platform/workspace/jps",
"//platform/workspace/jps:jps_test_lib",
"//plugins/gradle",
@@ -303,8 +311,12 @@ jvm_library(
],
runtime_deps = [
":kotlin-gradle-scripting-tests",
"//plugins/kotlin/plugin/k2:k2_test_lib",
"//platform/testRunner/plugin:plugin_test_lib",
"//plugins/gradle/plugin:plugin_test_lib",
"//platform/observable:observable_test_lib",
"//platform/platform-impl:ide-impl_test_lib",
"//plugins/gradle/java/plugin:plugin_test_lib",
]
)
### auto-generated section `build intellij.kotlin.gradle.scripting.tests` end
@@ -25,7 +25,7 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="TEST" name="kotlin-stdlib" level="project" />
<orderEntry type="module" module-name="intellij.platform.projectModel" scope="TEST" />
<orderEntry type="module" module-name="kotlin.plugin.k2" scope="TEST" />
<orderEntry type="module" module-name="kotlin.plugin.k2" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.editor.ui" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.ide" scope="TEST" />
<orderEntry type="module" module-name="intellij.java.frontback.psi.impl" scope="TEST" />
@@ -41,8 +41,12 @@
<orderEntry type="module" module-name="intellij.platform.analysis" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.externalSystem.impl" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.execution" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.smRunner" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.testRunner" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.testRunner.plugin" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.workspace.jps" scope="TEST" />
<orderEntry type="module" module-name="intellij.gradle" scope="TEST" />
<orderEntry type="module" module-name="intellij.gradle.plugin" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.backend.observation" scope="TEST" />
<orderEntry type="module" module-name="intellij.kotlin.gradle.gradle" scope="TEST" />
<orderEntry type="module" module-name="intellij.java.ui" scope="TEST" />
@@ -83,6 +87,7 @@
<orderEntry type="module" module-name="intellij.platform.projectModel.impl" scope="TEST" />
<orderEntry type="module" module-name="intellij.java.testFramework" scope="TEST" />
<orderEntry type="module" module-name="intellij.gradle.java" scope="TEST" />
<orderEntry type="module" module-name="intellij.gradle.java.plugin" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.kotlin.codeInsight.shared" scope="TEST" />
<orderEntry type="module" module-name="intellij.kotlin.highlighting.minimal" scope="TEST" />
<orderEntry type="module" module-name="intellij.libraries.assertj.core" scope="TEST" />
@@ -6,6 +6,8 @@ jvm_library(
module_name = "intellij.kotlin.jvm.debugger.base.util",
visibility = ["//visibility:public"],
srcs = glob(["src/**/*.kt", "src/**/*.java", "src/**/*.form"], allow_empty = True),
resources = glob(["resources/**/*"]),
resource_strip_prefix = "resources",
deps = [
"@lib//:kotlin-stdlib",
"@lib//:kotlinc-kotlin-compiler-common",
@@ -3,6 +3,7 @@
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
@@ -0,0 +1,10 @@
<idea-plugin visibility="public">
<!-- region Generated dependencies - run `Generate Product Layouts` to regenerate -->
<dependencies>
<module name="intellij.java.compiler"/>
<module name="intellij.java.debugger"/>
<module name="intellij.java.debugger.impl"/>
<module name="intellij.java.psi"/>
</dependencies>
<!-- endregion -->
</idea-plugin>
@@ -1,6 +1,6 @@
### auto-generated section `build intellij.kotlin.jvm.debugger.coroutines` start
load("//build:compiler-options.bzl", "create_kotlinc_options")
load("@rules_jvm//:jvm.bzl", "jvm_library")
load("@rules_jvm//:jvm.bzl", "jvm_library", "jvm_provided_library")
create_kotlinc_options(
name = "custom_coroutines",
@@ -11,6 +11,11 @@ create_kotlinc_options(
x_context_parameters = True
)
jvm_provided_library(
name = "java_rt_provided",
lib = "//java/java-runtime:rt"
)
jvm_library(
name = "coroutines",
module_name = "intellij.kotlin.jvm.debugger.coroutines",
@@ -59,7 +64,6 @@ jvm_library(
"//java/execution/impl",
"//java/debugger/impl",
"//plugins/kotlin/code-insight/utils",
"//java/java-runtime:rt",
"//libraries/kotlinx/serialization/core",
"//libraries/kotlinx/serialization/json",
"//java/java-impl:impl",
@@ -68,6 +72,7 @@ jvm_library(
"//platform/execution",
"//platform/statistics",
"//platform/util:util-ui",
":java_rt_provided",
]
)
@@ -116,6 +121,7 @@ jvm_library(
"//java/execution/impl:impl_test_lib",
"//java/debugger/impl:impl_test_lib",
"//plugins/kotlin/code-insight/utils:utils_test_lib",
"//java/java-runtime:rt",
"//java/java-runtime:rt_test_lib",
"//libraries/kotlinx/serialization/core:core_test_lib",
"//libraries/kotlinx/serialization/json:json_test_lib",
@@ -69,7 +69,7 @@
<orderEntry type="module" module-name="intellij.java.execution.impl" />
<orderEntry type="module" module-name="intellij.java.debugger.impl" />
<orderEntry type="module" module-name="intellij.kotlin.codeInsight.utils" />
<orderEntry type="module" module-name="intellij.java.rt" />
<orderEntry type="module" module-name="intellij.java.rt" scope="PROVIDED" />
<orderEntry type="module" module-name="intellij.libraries.kotlinx.serialization.core" />
<orderEntry type="module" module-name="intellij.libraries.kotlinx.serialization.json" />
<orderEntry type="module" module-name="intellij.java.impl" />
@@ -0,0 +1,15 @@
<idea-plugin visibility="public">
<!-- region Generated dependencies - run `Generate Product Layouts` to regenerate -->
<dependencies>
<module name="intellij.java.debugger"/>
<module name="intellij.java.debugger.impl"/>
<module name="intellij.java.debugger.impl.shared"/>
<module name="intellij.java.execution.impl"/>
<module name="intellij.java.impl"/>
<module name="intellij.java.psi"/>
<module name="intellij.kotlin.jvm.debugger.base.util"/>
<module name="intellij.libraries.maven.resolver.provider"/>
<module name="intellij.platform.smRunner"/>
</dependencies>
<!-- endregion -->
</idea-plugin>
@@ -5,6 +5,7 @@
<module name="intellij.java.psi"/>
<module name="intellij.kotlin.codeInsight.inspections"/>
<module name="intellij.kotlin.codeInsight.shared"/>
<module name="intellij.kotlin.jvm.debugger.base.util"/>
</dependencies>
<!-- endregion -->
<extensions defaultExtensionNs="com.intellij">
+6 -2
View File
@@ -17,6 +17,12 @@
- name: lib/intellij.kotlin.codeInsight.shared.jar
contentModules:
- name: intellij.kotlin.codeInsight.shared
- name: lib/intellij.kotlin.jvm.debugger.base.util.jar
contentModules:
- name: intellij.kotlin.jvm.debugger.base.util
- name: lib/intellij.kotlin.jvm.debugger.coroutines.jar
contentModules:
- name: intellij.kotlin.jvm.debugger.coroutines
- name: lib/javax-inject.jar
library: javax-inject
files:
@@ -198,11 +204,9 @@
- name: intellij.kotlin.projectWizard.maven
- name: intellij.kotlin.projectWizard.gradle
- name: intellij.kotlin.projectWizard.compose
- name: intellij.kotlin.jvm.debugger.base.util
- name: intellij.kotlin.jvm.debugger.core
- name: kotlin.jvm-debugger.evaluation
- name: intellij.kotlin.jvm.debugger.evaluation
- name: intellij.kotlin.jvm.debugger.coroutines
- name: intellij.kotlin.jvm.debugger.eval4j
- name: intellij.kotlin.uast.base
- name: intellij.kotlin.uast.idea.base
@@ -18,6 +18,10 @@
<dependencies>
<module name="intellij.java.backend"/>
<module name="intellij.platform.collaborationTools"/>
<module name="intellij.platform.scriptDebugger.ui"/>
<!-- region Generated dependencies - run `Generate Product Layouts` to regenerate -->
<module name="intellij.platform.debugger.impl.ui"/>
<!-- endregion -->
</dependencies>
<extensionPoints>
@@ -32,6 +36,8 @@
<content namespace="jetbrains">
<module name="intellij.kotlin.base.resources" loading="embedded"/>
<module name="intellij.kotlin.codeInsight.shared" loading="embedded"/>
<module name="intellij.kotlin.jvm.debugger.base.util" loading="embedded"/>
<module name="intellij.kotlin.jvm.debugger.coroutines" loading="embedded"/>
</content>
<xi:include href="kotlin.plugin.k1.xml" includeIf="idea.kotlin.plugin.use.k1.obsolete"/>