From fe76e2f705e7379bc6b74c74bec973fcdeb2bc45 Mon Sep 17 00:00:00 2001 From: Nikolay Chashnikov Date: Wed, 11 Feb 2026 11:17:34 +0100 Subject: [PATCH] IJPL-234358 refactor: use RuntimeModuleId instance instead of String in runtime module repository classes This is needed to add `namespace` property in RuntimeModuleId. GitOrigin-RevId: 817b800f462a95f093049349f7b161947c577e3e --- .../ModuleBasedProductLoadingStrategy.kt | 6 +- .../RuntimeModuleRepositoryForDistribution.kt | 22 ++--- .../RuntimeModuleRepositoryChecker.kt | 7 +- .../serialization/PluginXmlReaderTest.kt | 16 ++-- .../serialization/ProductModulesLoaderTest.kt | 86 +++++++++---------- .../repository/api-dump-experimental.txt | 5 ++ .../impl/RuntimeModuleRepositoryImpl.java | 15 ++-- .../RawRuntimeModuleDescriptor.java | 47 ++++++++-- .../RawRuntimeModuleRepositoryData.java | 65 +++++++++++--- .../impl/CachedClasspathComputation.java | 19 ++-- .../serialization/impl/CompactFileReader.java | 16 ++-- .../serialization/impl/CompactFileWriter.java | 25 +++--- .../serialization/impl/JarFileSerializer.java | 16 ++-- .../impl/ModuleXmlSerializer.java | 16 ++-- .../tests/testSrc/RepositoryTest.kt | 50 +++++------ .../tests/testSrc/repositoryTestUtils.kt | 6 +- .../JarRepositorySerializationTest.kt | 21 ++--- .../RuntimeModuleRepositoryForTests.kt | 2 +- .../src/RuntimeModuleRepositoryGenerator.kt | 30 +++---- .../src/RuntimeModuleRepositoryValidator.kt | 9 +- .../build/RuntimeModuleRepositoryBuilder.kt | 5 +- .../build/RuntimeModuleRepositoryCheckers.kt | 11 +-- .../build/RuntimeModuleRepositoryTestCase.kt | 2 +- 23 files changed, 297 insertions(+), 200 deletions(-) diff --git a/platform/bootstrap/src/com/intellij/platform/bootstrap/ModuleBasedProductLoadingStrategy.kt b/platform/bootstrap/src/com/intellij/platform/bootstrap/ModuleBasedProductLoadingStrategy.kt index 6d61e3b56a97..b0815c1cc7b9 100644 --- a/platform/bootstrap/src/com/intellij/platform/bootstrap/ModuleBasedProductLoadingStrategy.kt +++ b/platform/bootstrap/src/com/intellij/platform/bootstrap/ModuleBasedProductLoadingStrategy.kt @@ -303,9 +303,9 @@ internal class ModuleBasedProductLoadingStrategy(internal val moduleRepository: */ val descriptors = ArrayList() descriptors.add(mainModule) - repositoryData.allIds.asSequence() - .filter { it != mainModuleId } - .mapTo(descriptors) { moduleRepository.getModule(RuntimeModuleId.raw(it)) } + repositoryData.allModuleIds.asSequence() + .filter { it != mainModule.moduleId } + .mapTo(descriptors) { moduleRepository.getModule(it) } val moduleGroup = CustomPluginModuleGroup(descriptors, mainModule) loadPluginDescriptorFromRuntimeModule( pluginModuleGroup = moduleGroup, diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/RuntimeModuleRepositoryForDistribution.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/RuntimeModuleRepositoryForDistribution.kt index 3c1ebaf89315..ff0ca38b4426 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/RuntimeModuleRepositoryForDistribution.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/RuntimeModuleRepositoryForDistribution.kt @@ -110,15 +110,15 @@ internal fun generateCrossPlatformRepository(distAllPath: Path, osSpecificDistPa } RuntimeModuleRepositorySerialization.loadFromCompactFile(repositoryFile) } - val commonIds = repositories.map { it.allIds }.reduce { a, b -> a.intersect(b) } + val commonIds = repositories.map { it.allModuleIds }.reduce { a, b -> a.intersect(b) } val commonDescriptors = ArrayList() for (moduleId in commonIds) { val descriptors = repositories.map { it.findDescriptor(moduleId)!! } val commonResourcePaths = descriptors.map { it.resourcePaths.toSet() }.reduce { a, b -> a.intersect(b) } - val commonDependencies = descriptors.first().dependencies + val commonDependencies = descriptors.first().dependencyIds for (descriptor in descriptors) { - if (descriptor.dependencies != commonDependencies) { - context.messages.logErrorAndThrow("Cannot generate runtime module repository for cross-platform distribution: different dependencies for module '$moduleId', ${descriptor.dependencies} and $commonDependencies") + if (descriptor.dependencyIds != commonDependencies) { + context.messages.logErrorAndThrow("Cannot generate runtime module repository for cross-platform distribution: different dependencies for module '${moduleId.presentableName}', ${descriptor.dependencyIds} and $commonDependencies") } } commonDescriptors.add(RawRuntimeModuleDescriptor.create(moduleId, commonResourcePaths.toList(), commonDependencies)) @@ -188,15 +188,15 @@ private suspend fun generateRepositoryForDistribution( resourcePathsSchema = DistributionResourcePathsSchema(moduleProductionPaths, moduleTestPaths, libraryPaths), ).map { descriptor -> //this is a temporary workaround to skip optional dependencies which aren't included in the distribution - val dependenciesToSkip = dependenciesToSkip[descriptor.id] ?: return@map descriptor - val actualDependencies = descriptor.dependencies.filterNot { it in dependenciesToSkip} - RawRuntimeModuleDescriptor.create(descriptor.id, descriptor.resourcePaths, actualDependencies) + val dependenciesToSkip = dependenciesToSkip[descriptor.moduleId] ?: return@map descriptor + val actualDependencies = descriptor.dependencyIds.filterNot { it in dependenciesToSkip} + RawRuntimeModuleDescriptor.create(descriptor.moduleId, descriptor.resourcePaths, actualDependencies) } val errors = ArrayList() val errorReporter = object : RuntimeModuleRepositoryValidator.ErrorReporter { - override fun reportDuplicatingId(moduleId: String) { - errors.add("Module '$moduleId' is included several times in the runtime module repository") + override fun reportDuplicatingId(moduleId: RuntimeModuleId) { + errors.add("Module '${moduleId.presentableName}' is included several times in the runtime module repository") } } RuntimeModuleRepositoryValidator.validate(distDescriptors, errorReporter) @@ -344,7 +344,7 @@ private fun collectTransitiveDependencies(moduleIds: Collection if (result.add(moduleId)) { val descriptor = descriptorMap[moduleId] if (descriptor != null) { - collectTransitiveDependencies(descriptor.dependencies.map { RuntimeModuleId.raw(it) }, descriptorMap, result) + collectTransitiveDependencies(descriptor.dependencyIds, descriptorMap, result) } } } @@ -356,5 +356,5 @@ const val MODULE_DESCRIPTORS_COMPACT_PATH: String = "$RUNTIME_REPOSITORY_MODULES private val dependenciesToSkip = mapOf( //may be removed when IJPL-125 is fixed - "intellij.platform.buildScripts.downloader" to setOf("lib.zstd-jni"), + RuntimeModuleId.module("intellij.platform.buildScripts.downloader") to setOf(RuntimeModuleId.projectLibrary("zstd-jni")), ) diff --git a/platform/build-scripts/testFramework/src/com/intellij/platform/buildScripts/testFramework/RuntimeModuleRepositoryChecker.kt b/platform/build-scripts/testFramework/src/com/intellij/platform/buildScripts/testFramework/RuntimeModuleRepositoryChecker.kt index 0c538725d6ea..6ff028701ee0 100644 --- a/platform/build-scripts/testFramework/src/com/intellij/platform/buildScripts/testFramework/RuntimeModuleRepositoryChecker.kt +++ b/platform/build-scripts/testFramework/src/com/intellij/platform/buildScripts/testFramework/RuntimeModuleRepositoryChecker.kt @@ -194,13 +194,12 @@ internal class RuntimeModuleRepositoryChecker private constructor( repository.getModule(moduleId).resourceRootPaths.map { it to moduleId } }.groupBy({ it.first }, { it.second }) - for (rawModuleId in moduleRepositoryData.allIds) { - val moduleId = RuntimeModuleId.raw(rawModuleId) - if (rawModuleId.startsWith(RuntimeModuleId.LIB_NAME_PREFIX)) { + for (moduleId in moduleRepositoryData.allModuleIds) { + if (moduleId.stringId.startsWith(RuntimeModuleId.LIB_NAME_PREFIX)) { //additional libraries shouldn't cause problems because their resources should not be loaded unless they are requested from modules continue } - val module = context.outputProvider.findModule(rawModuleId) + val module = context.outputProvider.findModule(moduleId.stringId) if (module != null && hasModuleOutputPath(module = module, relativePath = "${module.name}.xml", outputProvider = context.outputProvider)) { // such a descriptor indicates that it's a module in plugin model V2, and its ClassLoader ignores classes from irrelevant packages, // so including its JAR to classpath should not cause problems diff --git a/platform/runtime/product/tests/testSrc/serialization/PluginXmlReaderTest.kt b/platform/runtime/product/tests/testSrc/serialization/PluginXmlReaderTest.kt index ed33498ddb9c..5350526ff8b6 100644 --- a/platform/runtime/product/tests/testSrc/serialization/PluginXmlReaderTest.kt +++ b/platform/runtime/product/tests/testSrc/serialization/PluginXmlReaderTest.kt @@ -4,8 +4,8 @@ package com.intellij.platform.runtime.product.serialization import com.intellij.platform.runtime.product.RuntimeModuleLoadingRule import com.intellij.platform.runtime.product.serialization.impl.loadPluginModules import com.intellij.platform.runtime.repository.RuntimeModuleId +import com.intellij.platform.runtime.repository.createModuleDescriptor import com.intellij.platform.runtime.repository.createRepository -import com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor import com.intellij.platform.runtime.repository.writePluginXml import com.intellij.testFramework.rules.TempDirectoryExtension import org.junit.jupiter.api.Assertions.assertEquals @@ -22,7 +22,7 @@ class PluginXmlReaderTest { fun `single module`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("plugin.main", listOf("plugin"), emptyList()), + createModuleDescriptor("plugin.main", listOf("plugin"), emptyList()), ) writePluginXml(tempDirectory.rootPath / "plugin", """ @@ -42,12 +42,12 @@ class PluginXmlReaderTest { fun `multiple modules`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("plugin.main", listOf("plugin"), emptyList()), - RawRuntimeModuleDescriptor.create("plugin.optional", emptyList(), listOf("plugin.main")), - RawRuntimeModuleDescriptor.create("plugin.optional.explicit", emptyList(), listOf("plugin.main")), - RawRuntimeModuleDescriptor.create("plugin.on_demand", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("plugin.required", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("plugin.embedded", emptyList(), emptyList()), + createModuleDescriptor("plugin.main", listOf("plugin"), emptyList()), + createModuleDescriptor("plugin.optional", emptyList(), listOf("plugin.main")), + createModuleDescriptor("plugin.optional.explicit", emptyList(), listOf("plugin.main")), + createModuleDescriptor("plugin.on_demand", emptyList(), emptyList()), + createModuleDescriptor("plugin.required", emptyList(), emptyList()), + createModuleDescriptor("plugin.embedded", emptyList(), emptyList()), ) @Suppress("XmlUnusedNamespaceDeclaration") writePluginXml(tempDirectory.rootPath / "plugin", diff --git a/platform/runtime/product/tests/testSrc/serialization/ProductModulesLoaderTest.kt b/platform/runtime/product/tests/testSrc/serialization/ProductModulesLoaderTest.kt index e57b1bb8ccdb..b93e389eb424 100644 --- a/platform/runtime/product/tests/testSrc/serialization/ProductModulesLoaderTest.kt +++ b/platform/runtime/product/tests/testSrc/serialization/ProductModulesLoaderTest.kt @@ -6,8 +6,8 @@ import com.intellij.platform.runtime.product.RuntimeModuleLoadingRule import com.intellij.platform.runtime.product.impl.ServiceModuleMapping import com.intellij.platform.runtime.repository.MalformedRepositoryException import com.intellij.platform.runtime.repository.RuntimeModuleId +import com.intellij.platform.runtime.repository.createModuleDescriptor import com.intellij.platform.runtime.repository.createRepository -import com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor import com.intellij.platform.runtime.repository.writePluginXml import com.intellij.platform.runtime.repository.xml import com.intellij.testFramework.rules.TempDirectoryExtension @@ -30,9 +30,9 @@ class ProductModulesLoaderTest { @Test fun simple() { val repository = createRepository(tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("util", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("root", emptyList(), listOf("util")), - RawRuntimeModuleDescriptor.create("plugin", listOf("plugin"), emptyList()), + createModuleDescriptor("util", emptyList(), emptyList()), + createModuleDescriptor("root", emptyList(), listOf("util")), + createModuleDescriptor("plugin", listOf("plugin"), emptyList()), ) writePluginXmlWithModules(tempDirectory.rootPath / "plugin", "plugin") val xml = generateProductModulesWithPlugin() @@ -53,10 +53,10 @@ class ProductModulesLoaderTest { @Test fun `optional modules in main module group`() { val repository = createRepository(tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("util", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("root", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("required", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("optional", emptyList(), listOf("root")), + createModuleDescriptor("util", emptyList(), emptyList()), + createModuleDescriptor("root", emptyList(), emptyList()), + createModuleDescriptor("required", emptyList(), emptyList()), + createModuleDescriptor("optional", emptyList(), listOf("root")), ) val xml = directoryContent { xml(FILE_NAME, """ @@ -87,9 +87,9 @@ class ProductModulesLoaderTest { fun `multiple modules in plugin module group`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("root", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("plugin", listOf("plugin"), emptyList()), - RawRuntimeModuleDescriptor.create("optional", emptyList(), listOf("plugin")), + createModuleDescriptor("root", emptyList(), emptyList()), + createModuleDescriptor("plugin", listOf("plugin"), emptyList()), + createModuleDescriptor("optional", emptyList(), listOf("plugin")), ) writePluginXmlWithModules(tempDirectory.rootPath / "plugin", "plugin", "optional", "unknown") @@ -110,9 +110,9 @@ class ProductModulesLoaderTest { fun `unresolved plugin module`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("root", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("plugin", listOf("plugin"), listOf("plugin.util")), - RawRuntimeModuleDescriptor.create("plugin.util", emptyList(), listOf("unresolved.module")), + createModuleDescriptor("root", emptyList(), emptyList()), + createModuleDescriptor("plugin", listOf("plugin"), listOf("plugin.util")), + createModuleDescriptor("plugin.util", emptyList(), listOf("unresolved.module")), ) writePluginXmlWithModules(tempDirectory.rootPath / "plugin", "plugin") val xml = generateProductModulesWithPlugin() @@ -132,14 +132,14 @@ class ProductModulesLoaderTest { fun `enable plugin modules in relevant modes`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("root", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("intellij.platform.frontend.split", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("intellij.platform.backend", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("intellij.platform.monolith", emptyList(), listOf("intellij.platform.backend")), - RawRuntimeModuleDescriptor.create("plugin", listOf("plugin"), emptyList()), - RawRuntimeModuleDescriptor.create("plugin.common", emptyList(), listOf("plugin")), - RawRuntimeModuleDescriptor.create("plugin.frontend", emptyList(), listOf("plugin", "intellij.platform.frontend.split")), - RawRuntimeModuleDescriptor.create("plugin.localIde", emptyList(), listOf("plugin", "intellij.platform.monolith")), + createModuleDescriptor("root", emptyList(), emptyList()), + createModuleDescriptor("intellij.platform.frontend.split", emptyList(), emptyList()), + createModuleDescriptor("intellij.platform.backend", emptyList(), emptyList()), + createModuleDescriptor("intellij.platform.monolith", emptyList(), listOf("intellij.platform.backend")), + createModuleDescriptor("plugin", listOf("plugin"), emptyList()), + createModuleDescriptor("plugin.common", emptyList(), listOf("plugin")), + createModuleDescriptor("plugin.frontend", emptyList(), listOf("plugin", "intellij.platform.frontend.split")), + createModuleDescriptor("plugin.localIde", emptyList(), listOf("plugin", "intellij.platform.monolith")), ) writePluginXmlWithModules(tempDirectory.rootPath / "plugin", "plugin", "plugin.common", "plugin.frontend", "plugin.localIde") @@ -162,10 +162,10 @@ class ProductModulesLoaderTest { fun inclusion() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("root", listOf("root"), emptyList()), - RawRuntimeModuleDescriptor.create("common.plugin", listOf("common.plugin"), emptyList()), - RawRuntimeModuleDescriptor.create("additional", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("plugin", listOf("plugin"), emptyList()), + createModuleDescriptor("root", listOf("root"), emptyList()), + createModuleDescriptor("common.plugin", listOf("common.plugin"), emptyList()), + createModuleDescriptor("additional", emptyList(), emptyList()), + createModuleDescriptor("plugin", listOf("plugin"), emptyList()), ) writePluginXmlWithModules(tempDirectory.rootPath.resolve("common.plugin"), "common") writePluginXmlWithModules(tempDirectory.rootPath.resolve("plugin"), "plugin") @@ -198,10 +198,10 @@ class ProductModulesLoaderTest { fun `inclusion without some modules`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("root", listOf("root"), emptyList()), - RawRuntimeModuleDescriptor.create("additional", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("plugin", listOf("plugin"), emptyList()), - RawRuntimeModuleDescriptor.create("plugin2", listOf("plugin2"), emptyList()), + createModuleDescriptor("root", listOf("root"), emptyList()), + createModuleDescriptor("additional", emptyList(), emptyList()), + createModuleDescriptor("plugin", listOf("plugin"), emptyList()), + createModuleDescriptor("plugin2", listOf("plugin2"), emptyList()), ) writePluginXmlWithModules(tempDirectory.rootPath.resolve("plugin"), "plugin") writePluginXmlWithModules(tempDirectory.rootPath.resolve("plugin2"), "plugin2") @@ -233,11 +233,11 @@ class ProductModulesLoaderTest { fun `service module mapping`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("root", listOf("root"), emptyList()), - RawRuntimeModuleDescriptor.create("additional1", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("lib.common", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("plugin1", listOf("plugin1"), listOf("additional1", "lib.common")), - RawRuntimeModuleDescriptor.create("plugin2", listOf("plugin2"), listOf("lib.common")), + createModuleDescriptor("root", listOf("root"), emptyList()), + createModuleDescriptor("additional1", emptyList(), emptyList()), + createModuleDescriptor("lib.common", emptyList(), emptyList()), + createModuleDescriptor("plugin1", listOf("plugin1"), listOf("additional1", "lib.common")), + createModuleDescriptor("plugin2", listOf("plugin2"), listOf("lib.common")), ) writePluginXmlWithModules(tempDirectory.rootPath.resolve("plugin1"), "plugin1") writePluginXmlWithModules(tempDirectory.rootPath.resolve("plugin2"), "plugin2") @@ -257,10 +257,10 @@ class ProductModulesLoaderTest { fun `service module mapping reports error about ambiguous module`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("root", listOf("root"), emptyList()), - RawRuntimeModuleDescriptor.create("additional", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("plugin1", listOf("plugin1"), listOf("additional")), - RawRuntimeModuleDescriptor.create("plugin2", listOf("plugin2"), listOf("additional")), + createModuleDescriptor("root", listOf("root"), emptyList()), + createModuleDescriptor("additional", emptyList(), emptyList()), + createModuleDescriptor("plugin1", listOf("plugin1"), listOf("additional")), + createModuleDescriptor("plugin2", listOf("plugin2"), listOf("additional")), ) writePluginXmlWithModules(tempDirectory.rootPath.resolve("plugin1"), "plugin1") writePluginXmlWithModules(tempDirectory.rootPath.resolve("plugin2"), "plugin2") @@ -279,10 +279,10 @@ class ProductModulesLoaderTest { fun `without module should exclude module from the nested included module`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("root", listOf("root"), listOf("plugin1")), - RawRuntimeModuleDescriptor.create("plugin1", listOf("plugin1"), listOf("plugin2")), - RawRuntimeModuleDescriptor.create("plugin2", listOf("plugin2"), listOf("plugin3")), - RawRuntimeModuleDescriptor.create("plugin3", listOf("plugin3"), listOf()), + createModuleDescriptor("root", listOf("root"), listOf("plugin1")), + createModuleDescriptor("plugin1", listOf("plugin1"), listOf("plugin2")), + createModuleDescriptor("plugin2", listOf("plugin2"), listOf("plugin3")), + createModuleDescriptor("plugin3", listOf("plugin3"), listOf()), ) val plugins = listOf("plugin1", "plugin2", "plugin3") plugins.forEach { writePluginXmlWithModules(tempDirectory.rootPath.resolve(it), it) } diff --git a/platform/runtime/repository/api-dump-experimental.txt b/platform/runtime/repository/api-dump-experimental.txt index b7d48f8a3aa1..fbd86cec0069 100644 --- a/platform/runtime/repository/api-dump-experimental.txt +++ b/platform/runtime/repository/api-dump-experimental.txt @@ -26,15 +26,20 @@ - a:getResolvedModule():com.intellij.platform.runtime.repository.RuntimeModuleDescriptor *f:com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor - (java.lang.String,java.util.List,java.util.List):V +- s:create(com.intellij.platform.runtime.repository.RuntimeModuleId,java.util.List,java.util.List):com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor - s:create(java.lang.String,java.util.List,java.util.List):com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor - equals(java.lang.Object):Z - getDependencies():java.util.List +- getDependencyIds():java.util.List - getId():java.lang.String +- getModuleId():com.intellij.platform.runtime.repository.RuntimeModuleId - getResourcePaths():java.util.List - hashCode():I *f:com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleRepositoryData +- findDescriptor(com.intellij.platform.runtime.repository.RuntimeModuleId):com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor - findDescriptor(java.lang.String):com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor - getAllIds():java.util.Set +- getAllModuleIds():java.util.Set - getBasePath():java.nio.file.Path - getMainPluginModuleId():java.lang.String *f:com.intellij.platform.runtime.repository.serialization.RuntimeModuleRepositorySerialization diff --git a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/impl/RuntimeModuleRepositoryImpl.java b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/impl/RuntimeModuleRepositoryImpl.java index b6e3413b02e8..9d568782b7ef 100644 --- a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/impl/RuntimeModuleRepositoryImpl.java +++ b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/impl/RuntimeModuleRepositoryImpl.java @@ -26,7 +26,6 @@ public class RuntimeModuleRepositoryImpl implements RuntimeModuleRepository { private volatile RawRuntimeModuleRepositoryData myMainData; private volatile List myAdditionalData; private final Path myDescriptorsFilePath; - private final Map myInternedModuleIds; public RuntimeModuleRepositoryImpl(@NotNull Path descriptorsFilePath) { this(descriptorsFilePath, null); @@ -35,7 +34,6 @@ public class RuntimeModuleRepositoryImpl implements RuntimeModuleRepository { public RuntimeModuleRepositoryImpl(@NotNull Path descriptorsFilePath, @Nullable RawRuntimeModuleRepositoryData preloadedMainData) { myDescriptorsFilePath = descriptorsFilePath; myResolveResults = new ConcurrentHashMap<>(); - myInternedModuleIds = new ConcurrentHashMap<>(); myMainData = preloadedMainData; } @@ -53,11 +51,11 @@ public class RuntimeModuleRepositoryImpl implements RuntimeModuleRepository { if (cached != null) return cached; RawRuntimeModuleRepositoryData rawData = getMainData(); - RawRuntimeModuleDescriptor rawDescriptor = rawData.findDescriptor(moduleId.getStringId()); + RawRuntimeModuleDescriptor rawDescriptor = rawData.findDescriptor(moduleId); if (rawDescriptor == null) { if (myAdditionalData != null) { for (RawRuntimeModuleRepositoryData data : myAdditionalData) { - rawDescriptor = data.findDescriptor(moduleId.getStringId()); + rawDescriptor = data.findDescriptor(moduleId); if (rawDescriptor != null) { rawData = data; break; @@ -72,12 +70,11 @@ public class RuntimeModuleRepositoryImpl implements RuntimeModuleRepository { } } - List rawDependencies = rawDescriptor.getDependencies(); + List rawDependencies = rawDescriptor.getDependencyIds(); List resolvedDependencies = new ArrayList<>(rawDependencies.size()); RuntimeModuleDescriptorImpl descriptor = new RuntimeModuleDescriptorImpl(moduleId, rawData.getBasePath(), rawDescriptor.getResourcePaths(), resolvedDependencies); dependencyPath.put(moduleId, descriptor); - for (String dependency : rawDependencies) { - RuntimeModuleId dependencyId = myInternedModuleIds.computeIfAbsent(dependency, RuntimeModuleId::raw); + for (RuntimeModuleId dependencyId : rawDependencies) { RuntimeModuleDescriptor circularDependency = dependencyPath.get(dependencyId); if (circularDependency != null) { //the circularDependency instance isn't fully constructed, but it's ok given that RuntimeModuleDescriptorImpl's constructor just stores the passed values @@ -124,11 +121,11 @@ public class RuntimeModuleRepositoryImpl implements RuntimeModuleRepository { @Override public @NotNull List getModuleResourcePaths(@NotNull RuntimeModuleId moduleId) { RawRuntimeModuleRepositoryData rawData = getMainData(); - RawRuntimeModuleDescriptor rawDescriptor = rawData.findDescriptor(moduleId.getStringId()); + RawRuntimeModuleDescriptor rawDescriptor = rawData.findDescriptor(moduleId); if (rawDescriptor == null) { if (myAdditionalData != null) { for (RawRuntimeModuleRepositoryData repository : myAdditionalData) { - rawDescriptor = repository.findDescriptor(moduleId.getStringId()); + rawDescriptor = repository.findDescriptor(moduleId); if (rawDescriptor != null) { rawData = repository; break; diff --git a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/RawRuntimeModuleDescriptor.java b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/RawRuntimeModuleDescriptor.java index aca97086edad..9068a7d0662f 100644 --- a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/RawRuntimeModuleDescriptor.java +++ b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/RawRuntimeModuleDescriptor.java @@ -1,45 +1,74 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.runtime.repository.serialization; +import com.intellij.platform.runtime.repository.RuntimeModuleId; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; /** * Describes raw data of a runtime module descriptor. This class is used in code which generates the module repository, if you need to * get information about modules in IDE, use {@link com.intellij.platform.runtime.repository.RuntimeModuleDescriptor} instead. */ public final class RawRuntimeModuleDescriptor { - private final String myId; + private final RuntimeModuleId myId; private final List myResourcePaths; - private final List myDependencies; + private final List myDependencies; /** - * @deprecated use {@link #create(String, List, List)} instead + * @deprecated use {@link #create(RuntimeModuleId, List, List)} instead */ @Deprecated(forRemoval = true) public RawRuntimeModuleDescriptor(@NotNull String id, @NotNull List resourcePaths, @NotNull List dependencies) { + myId = RuntimeModuleId.raw(id); + myResourcePaths = resourcePaths; + myDependencies = new ArrayList<>(dependencies.size()); + for (String dependency : dependencies) { + myDependencies.add(RuntimeModuleId.raw(dependency)); + } + } + + private RawRuntimeModuleDescriptor(@NotNull RuntimeModuleId id, @NotNull List resourcePaths, @NotNull List dependencies) { myId = id; myResourcePaths = resourcePaths; myDependencies = dependencies; } - public @NotNull String getId() { + public @NotNull RuntimeModuleId getModuleId() { return myId; } + /** + * @deprecated use {@link #getModuleId()} instead + */ + @Deprecated(forRemoval = true) + public @NotNull String getId() { + return myId.getStringId(); + } + public @NotNull List getResourcePaths() { return myResourcePaths; } + /** + * @deprecated use {@link #getDependencyIds()} instead + */ + @Deprecated(forRemoval = true) public @NotNull List getDependencies() { + //noinspection SSBasedInspection + return myDependencies.stream().map(RuntimeModuleId::getStringId).collect(Collectors.toList()); + } + + public @NotNull List getDependencyIds() { return myDependencies; } @Override public String toString() { return "RawRuntimeModuleDescriptor{" + - "id='" + myId + '\'' + + "id='" + myId.getPresentableName() + '\'' + ", resourcePaths=" + myResourcePaths + ", dependencies=" + myDependencies + '}'; @@ -67,6 +96,14 @@ public final class RawRuntimeModuleDescriptor { return result; } + public static @NotNull RawRuntimeModuleDescriptor create(@NotNull RuntimeModuleId id, @NotNull List resourcePaths, @NotNull List dependencies) { + return new RawRuntimeModuleDescriptor(id, resourcePaths, dependencies); + } + + /** + * @deprecated use {@link #create(RuntimeModuleId, List, List)} instead + */ + @Deprecated(forRemoval = true) public static @NotNull RawRuntimeModuleDescriptor create(@NotNull String id, @NotNull List resourcePaths, @NotNull List dependencies) { return new RawRuntimeModuleDescriptor(id, resourcePaths, dependencies); } diff --git a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/RawRuntimeModuleRepositoryData.java b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/RawRuntimeModuleRepositoryData.java index 3a57957ddf9e..9c4a09306187 100644 --- a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/RawRuntimeModuleRepositoryData.java +++ b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/RawRuntimeModuleRepositoryData.java @@ -1,50 +1,93 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.runtime.repository.serialization; +import com.intellij.platform.runtime.repository.RuntimeModuleId; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.nio.file.Path; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; /** * Describes raw data read from the module repository JAR. This class is used in code which parses the module repository, if you need to * get information about modules in IDE, use {@link com.intellij.platform.runtime.repository.RuntimeModuleRepository} instead. */ public final class RawRuntimeModuleRepositoryData { - private final Map myDescriptors; + private final Map myDescriptors; private final Path myBasePath; - private final String myMainPluginModuleId; + private final RuntimeModuleId myMainPluginModuleId; - /** - * Use {@link RuntimeModuleRepositorySerialization#loadFromJar(Path)} to create an instance in production code. - */ - @ApiStatus.Internal - public RawRuntimeModuleRepositoryData(@NotNull Map descriptors, @NotNull Path basePath, @Nullable String mainPluginModuleId) { + private RawRuntimeModuleRepositoryData(@NotNull Map descriptors, + @NotNull Path basePath, + @Nullable RuntimeModuleId mainPluginModuleId) { myDescriptors = descriptors; myBasePath = basePath; myMainPluginModuleId = mainPluginModuleId; } - public @Nullable RawRuntimeModuleDescriptor findDescriptor(@NotNull String id) { + /** + * @deprecated use {@link RuntimeModuleRepositorySerialization#loadFromJar(Path)} or {@link #create(Map, Path, RuntimeModuleId)} instead + */ + @Deprecated(forRemoval = true) + @ApiStatus.Internal + public RawRuntimeModuleRepositoryData(@NotNull Map descriptors, @NotNull Path basePath, @Nullable String mainPluginModuleId) { + myDescriptors = new LinkedHashMap<>(descriptors.size()); + for (Map.Entry entry : descriptors.entrySet()) { + myDescriptors.put(RuntimeModuleId.raw(entry.getKey()), entry.getValue()); + } + myBasePath = basePath; + myMainPluginModuleId = mainPluginModuleId != null ? RuntimeModuleId.raw(mainPluginModuleId) : null; + } + + public @Nullable RawRuntimeModuleDescriptor findDescriptor(@NotNull RuntimeModuleId id) { return myDescriptors.get(id); } + /** + * @deprecated use {@link #findDescriptor(RuntimeModuleId)} instead + */ + @Deprecated(forRemoval = true) + public @Nullable RawRuntimeModuleDescriptor findDescriptor(@NotNull String id) { + return myDescriptors.get(RuntimeModuleId.raw(id)); + } + public @NotNull Path getBasePath() { return myBasePath; } - - public @NotNull Set getAllIds() { + + public @NotNull Set getAllModuleIds() { return myDescriptors.keySet(); } + /** + * @deprecated use {@link #getAllModuleIds()} instead + */ + @Deprecated(forRemoval = true) + public @NotNull Set getAllIds() { + return myDescriptors.keySet().stream().map(RuntimeModuleId::getStringId).collect(Collectors.toSet()); + } + /** * Returns ID of the main plugin module for an additional module repository describing a custom plugin. * For the main module repository (describing the IDE distribution) it returns {@code null}. */ public @Nullable String getMainPluginModuleId() { - return myMainPluginModuleId; + return myMainPluginModuleId != null ? myMainPluginModuleId.getStringId() : null; + } + + /** + * Use {@link RuntimeModuleRepositorySerialization#loadFromCompactFile} to create an instance in production code. + */ + @ApiStatus.Internal + public static @NotNull RawRuntimeModuleRepositoryData create( + @NotNull Map descriptors, + @NotNull Path basePath, + @Nullable RuntimeModuleId mainPluginModuleId + ) { + return new RawRuntimeModuleRepositoryData(descriptors, basePath, mainPluginModuleId); } } diff --git a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/CachedClasspathComputation.java b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/CachedClasspathComputation.java index cc5109abe1a3..374184833d13 100644 --- a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/CachedClasspathComputation.java +++ b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/CachedClasspathComputation.java @@ -1,6 +1,7 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.runtime.repository.serialization.impl; +import com.intellij.platform.runtime.repository.RuntimeModuleId; import com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor; import org.jetbrains.annotations.NotNull; @@ -13,25 +14,25 @@ import java.util.Set; final class CachedClasspathComputation { - static @NotNull Collection computeClasspath(Collection descriptors, String moduleName) { + static @NotNull Collection computeClasspath(Collection descriptors, RuntimeModuleId moduleName) { Set classpath = new LinkedHashSet<>(); - Map descriptorMap = new HashMap<>(); + Map descriptorMap = new HashMap<>(); for (RawRuntimeModuleDescriptor descriptor : descriptors) { - descriptorMap.put(descriptor.getId(), descriptor); + descriptorMap.put(descriptor.getModuleId(), descriptor); } collectClasspathEntries(moduleName, descriptorMap, new HashSet<>(), classpath); return classpath; } - private static void collectClasspathEntries(String moduleName, - Map descriptorMap, - Set processedModules, + private static void collectClasspathEntries(RuntimeModuleId moduleId, + Map descriptorMap, + Set processedModules, Set classpath) { - if (!processedModules.add(moduleName)) return; - RawRuntimeModuleDescriptor descriptor = descriptorMap.get(moduleName); + if (!processedModules.add(moduleId)) return; + RawRuntimeModuleDescriptor descriptor = descriptorMap.get(moduleId); if (descriptor == null) return; classpath.addAll(descriptor.getResourcePaths()); - for (String dependency : descriptor.getDependencies()) { + for (RuntimeModuleId dependency : descriptor.getDependencyIds()) { collectClasspathEntries(dependency, descriptorMap, processedModules, classpath); } } diff --git a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/CompactFileReader.java b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/CompactFileReader.java index f97043252cae..1643550b98e1 100644 --- a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/CompactFileReader.java +++ b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/CompactFileReader.java @@ -2,6 +2,7 @@ package com.intellij.platform.runtime.repository.serialization.impl; import com.intellij.platform.runtime.repository.MalformedRepositoryException; +import com.intellij.platform.runtime.repository.RuntimeModuleId; import com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor; import com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleRepositoryData; import org.jetbrains.annotations.NotNull; @@ -39,25 +40,26 @@ public final class CompactFileReader { boolean hasMainPluginModule = in.readBoolean(); String mainPluginModuleName = hasMainPluginModule? in.readUTF() : null; + RuntimeModuleId mainPluginModuleId = mainPluginModuleName != null ? RuntimeModuleId.module(mainPluginModuleName) : null; - Map descriptors = new HashMap<>(); + Map descriptors = new HashMap<>(); int descriptorsCount = in.readInt(); int unresolvedDependenciesCount = in.readInt(); int totalIdCount = descriptorsCount + unresolvedDependenciesCount; - String[] descriptorIds = new String[totalIdCount]; + RuntimeModuleId[] descriptorIds = new RuntimeModuleId[totalIdCount]; for (int i = 0; i < totalIdCount; i++) { - descriptorIds[i] = in.readUTF(); + descriptorIds[i] = RuntimeModuleId.raw(in.readUTF()); } for (int i = 0; i < descriptorsCount; i++) { - String descriptorId = descriptorIds[i]; + RuntimeModuleId descriptorId = descriptorIds[i]; int dependenciesCount = in.readInt(); - List dependencies = new ArrayList<>(dependenciesCount); + List dependencies = new ArrayList<>(dependenciesCount); for (int j = 0; j < dependenciesCount; j++) { int dependencyIndex = in.readInt(); if (dependencyIndex < 0 || dependencyIndex >= totalIdCount) { - throw new MalformedRepositoryException("Invalid dependency index '" + dependencyIndex + "' in '" + descriptorId + "'"); + throw new MalformedRepositoryException("Invalid dependency index '" + dependencyIndex + "' in '" + descriptorId.getPresentableName() + "'"); } dependencies.add(descriptorIds[dependencyIndex]); } @@ -69,7 +71,7 @@ public final class CompactFileReader { descriptors.put(descriptorId, RawRuntimeModuleDescriptor.create(descriptorId, resourcePaths, dependencies)); } - return new RawRuntimeModuleRepositoryData(descriptors, filePath.getParent(), mainPluginModuleName); + return RawRuntimeModuleRepositoryData.create(descriptors, filePath.getParent(), mainPluginModuleId); } } diff --git a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/CompactFileWriter.java b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/CompactFileWriter.java index c348592149e3..6531f05fb5e2 100644 --- a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/CompactFileWriter.java +++ b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/CompactFileWriter.java @@ -1,6 +1,7 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.runtime.repository.serialization.impl; +import com.intellij.platform.runtime.repository.RuntimeModuleId; import com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,7 +32,7 @@ public final class CompactFileWriter { out.writeBoolean(hasBootstrap); if (hasBootstrap) { out.writeUTF(bootstrapModuleName); - Collection bootstrapClasspath = CachedClasspathComputation.computeClasspath(originalDescriptors, bootstrapModuleName); + Collection bootstrapClasspath = CachedClasspathComputation.computeClasspath(originalDescriptors, RuntimeModuleId.module(bootstrapModuleName)); out.writeInt(bootstrapClasspath.size()); for (String path : bootstrapClasspath) { out.writeUTF(path); @@ -45,14 +46,14 @@ public final class CompactFileWriter { } List descriptors = new ArrayList<>(originalDescriptors); - Collections.sort(descriptors, Comparator.comparing(RawRuntimeModuleDescriptor::getId)); - Map indexes = new HashMap<>(descriptors.size()); + Collections.sort(descriptors, Comparator.comparing(descriptor -> descriptor.getModuleId().getStringId())); + Map indexes = new HashMap<>(descriptors.size()); for (int i = 0; i < descriptors.size(); i++) { - indexes.put(descriptors.get(i).getId(), i); + indexes.put(descriptors.get(i).getModuleId(), i); } - List unresolvedDependencies = new ArrayList<>(); + List unresolvedDependencies = new ArrayList<>(); for (RawRuntimeModuleDescriptor descriptor : descriptors) { - for (String dependency : descriptor.getDependencies()) { + for (RuntimeModuleId dependency : descriptor.getDependencyIds()) { if (!indexes.containsKey(dependency)) { unresolvedDependencies.add(dependency); int nextId = indexes.size(); @@ -64,19 +65,19 @@ public final class CompactFileWriter { out.writeInt(descriptors.size()); out.writeInt(unresolvedDependencies.size()); for (RawRuntimeModuleDescriptor descriptor : descriptors) { - out.writeUTF(descriptor.getId()); + out.writeUTF(descriptor.getModuleId().getStringId()); } - for (String dependency : unresolvedDependencies) { - out.writeUTF(dependency); + for (RuntimeModuleId dependency : unresolvedDependencies) { + out.writeUTF(dependency.getStringId()); } for (RawRuntimeModuleDescriptor descriptor : descriptors) { - out.writeInt(descriptor.getDependencies().size()); - for (String dependency : descriptor.getDependencies()) { + out.writeInt(descriptor.getDependencyIds().size()); + for (RuntimeModuleId dependency : descriptor.getDependencyIds()) { Integer index = indexes.get(dependency); if (index == null) { - throw new AssertionError("Unknown dependency '" + dependency + "' in '" + descriptor.getId() + "'"); + throw new AssertionError("Unknown dependency '" + dependency.getPresentableName() + "' in '" + descriptor.getModuleId().getPresentableName() + "'"); } out.writeInt(index); } diff --git a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/JarFileSerializer.java b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/JarFileSerializer.java index 577d9597fe09..b4410779d84f 100644 --- a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/JarFileSerializer.java +++ b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/JarFileSerializer.java @@ -1,6 +1,7 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.runtime.repository.serialization.impl; +import com.intellij.platform.runtime.repository.RuntimeModuleId; import com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor; import com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleRepositoryData; import org.jetbrains.annotations.NotNull; @@ -33,8 +34,8 @@ public final class JarFileSerializer { private static final Attributes.Name BOOTSTRAP_CLASSPATH_ATTRIBUTE_NAME = new Attributes.Name("Bootstrap-Class-Path"); public static @NotNull RawRuntimeModuleRepositoryData loadFromJar(@NotNull Path jarPath) throws IOException, XMLStreamException { - Map rawData = new HashMap<>(); - String mainPluginModuleId; + Map rawData = new HashMap<>(); + String mainPluginModuleName; try (JarInputStream input = new JarInputStream(new BufferedInputStream(Files.newInputStream(jarPath)))) { Manifest manifest = input.getManifest(); if (manifest == null) { @@ -48,18 +49,19 @@ public final class JarFileSerializer { if (!version.equals(SPECIFICATION_VERSION)) { throw new IOException("'" + jarPath + "' has unsupported version '" + version + "' ('" + SPECIFICATION_VERSION + "' is expected)"); } - mainPluginModuleId = mainAttributes.getValue(MAIN_PLUGIN_MODULE_ATTRIBUTE_NAME); + mainPluginModuleName = mainAttributes.getValue(MAIN_PLUGIN_MODULE_ATTRIBUTE_NAME); JarEntry entry; XMLInputFactory factory = XMLInputFactory.newDefaultFactory(); while ((entry = input.getNextJarEntry()) != null) { String name = entry.getName(); if (name.endsWith(".xml")) { RawRuntimeModuleDescriptor data = ModuleXmlSerializer.parseModuleXml(factory, input); - rawData.put(data.getId(), data); + rawData.put(data.getModuleId(), data); } } } - return new RawRuntimeModuleRepositoryData(rawData, jarPath.getParent(), mainPluginModuleId); + RuntimeModuleId mainPluginModuleId = mainPluginModuleName != null ? RuntimeModuleId.module(mainPluginModuleName) : null; + return RawRuntimeModuleRepositoryData.create(rawData, jarPath.getParent(), mainPluginModuleId); } public static @NotNull String @Nullable [] loadBootstrapClasspath(@NotNull Path jarPath, @NotNull String bootstrapModuleName) @@ -97,7 +99,7 @@ public final class JarFileSerializer { attributes.put(Attributes.Name.IMPLEMENTATION_VERSION, SPECIFICATION_VERSION + "." + generatorVersion); if (bootstrapModuleName != null) { attributes.put(BOOTSTRAP_MODULE_ATTRIBUTE_NAME, bootstrapModuleName); - Collection bootstrapClasspath = CachedClasspathComputation.computeClasspath(descriptors, bootstrapModuleName); + Collection bootstrapClasspath = CachedClasspathComputation.computeClasspath(descriptors, RuntimeModuleId.module(bootstrapModuleName)); attributes.put(BOOTSTRAP_CLASSPATH_ATTRIBUTE_NAME, String.join(" ", bootstrapClasspath)); } if (mainPluginModuleId != null) { @@ -106,7 +108,7 @@ public final class JarFileSerializer { try (JarOutputStream jarOutput = new JarOutputStream(new BufferedOutputStream(Files.newOutputStream(jarFile)), manifest)) { XMLOutputFactory factory = XMLOutputFactory.newDefaultFactory(); for (RawRuntimeModuleDescriptor descriptor : descriptors) { - String id = descriptor.getId(); + String id = descriptor.getModuleId().getStringId(); jarOutput.putNextEntry(new JarEntry(id + ".xml")); PrintWriter output = new PrintWriter(jarOutput, false, StandardCharsets.UTF_8); ModuleXmlSerializer.writeModuleXml(descriptor, output, factory); diff --git a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/ModuleXmlSerializer.java b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/ModuleXmlSerializer.java index 0d3b56b0bada..b7351e703c55 100644 --- a/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/ModuleXmlSerializer.java +++ b/platform/runtime/repository/src/com/intellij/platform/runtime/repository/serialization/impl/ModuleXmlSerializer.java @@ -1,6 +1,7 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.runtime.repository.serialization.impl; +import com.intellij.platform.runtime.repository.RuntimeModuleId; import com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor; import org.jetbrains.annotations.NotNull; @@ -27,15 +28,15 @@ final class ModuleXmlSerializer { writer.writeStartDocument("UTF-8", "1.0"); writeEolAndIndent(writer, 0); writer.writeStartElement(MODULE_TAG); - writer.writeAttribute(NAME_ATTRIBUTE, descriptor.getId()); - List dependencies = descriptor.getDependencies(); + writer.writeAttribute(NAME_ATTRIBUTE, descriptor.getModuleId().getStringId()); + List dependencies = descriptor.getDependencyIds(); if (!dependencies.isEmpty()) { writeEolAndIndent(writer, 1); writer.writeStartElement("dependencies"); - for (String dependency : dependencies) { + for (RuntimeModuleId dependency : dependencies) { writeEolAndIndent(writer, 2); writer.writeEmptyElement(MODULE_TAG); - writer.writeAttribute(NAME_ATTRIBUTE, dependency); + writer.writeAttribute(NAME_ATTRIBUTE, dependency.getStringId()); } writeEolAndIndent(writer, 1); writer.writeEndElement(); @@ -67,7 +68,7 @@ final class ModuleXmlSerializer { public static RawRuntimeModuleDescriptor parseModuleXml(XMLInputFactory factory, InputStream inputStream) throws XMLStreamException { XMLStreamReader reader = factory.createXMLStreamReader(inputStream); - ArrayList dependencies = new ArrayList<>(); + ArrayList dependencies = new ArrayList<>(); ArrayList resources = new ArrayList<>(); String moduleName = null; int level = 0; @@ -80,7 +81,8 @@ final class ModuleXmlSerializer { moduleName = XmlStreamUtil.readFirstAttribute(reader, NAME_ATTRIBUTE); } else if (level == 3 & tagName.equals(MODULE_TAG)) { - dependencies.add(XmlStreamUtil.readFirstAttribute(reader, NAME_ATTRIBUTE)); + String dependencyName = XmlStreamUtil.readFirstAttribute(reader, NAME_ATTRIBUTE); + dependencies.add(RuntimeModuleId.raw(dependencyName)); } else if (level == 3 && tagName.equals(RESOURCE_ROOT_TAG)) { String relativePath = XmlStreamUtil.readFirstAttribute(reader, PATH_ATTRIBUTE); @@ -98,6 +100,6 @@ final class ModuleXmlSerializer { if (moduleName == null) { throw new XMLStreamException("Required attribute 'module' is not specified"); } - return RawRuntimeModuleDescriptor.create(moduleName, resources, dependencies); + return RawRuntimeModuleDescriptor.create(RuntimeModuleId.raw(moduleName), resources, dependencies); } } diff --git a/platform/runtime/repository/tests/testSrc/RepositoryTest.kt b/platform/runtime/repository/tests/testSrc/RepositoryTest.kt index 03705c5ca3f7..72818b8dc597 100644 --- a/platform/runtime/repository/tests/testSrc/RepositoryTest.kt +++ b/platform/runtime/repository/tests/testSrc/RepositoryTest.kt @@ -27,8 +27,8 @@ class RepositoryTest { fun `resolved dependencies`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("ij.foo", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("ij.bar", emptyList(), listOf("ij.foo")), + createModuleDescriptor("ij.foo", emptyList(), emptyList()), + createModuleDescriptor("ij.bar", emptyList(), listOf("ij.foo")), ) val bar = repository.getModule(RuntimeModuleId.raw("ij.bar")) val foo = repository.getModule(RuntimeModuleId.raw("ij.foo")) @@ -39,9 +39,9 @@ class RepositoryTest { fun `unresolved dependency`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("ij.foo", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("ij.bar", emptyList(), listOf("ij.foo", "unresolved")), - RawRuntimeModuleDescriptor.create("ij.baz", emptyList(), listOf("ij.bar")), + createModuleDescriptor("ij.foo", emptyList(), emptyList()), + createModuleDescriptor("ij.bar", emptyList(), listOf("ij.foo", "unresolved")), + createModuleDescriptor("ij.baz", emptyList(), listOf("ij.bar")), ) fun RuntimeModuleId.assertUnresolved(vararg pathToFailed: RuntimeModuleId) { val result = repository.resolveModule(this) @@ -65,9 +65,9 @@ class RepositoryTest { fun `circular dependency`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("ij.foo", emptyList(), listOf("ij.bar")), - RawRuntimeModuleDescriptor.create("ij.bar", emptyList(), listOf("ij.foo")), - RawRuntimeModuleDescriptor.create("ij.baz", emptyList(), listOf("ij.bar")), + createModuleDescriptor("ij.foo", emptyList(), listOf("ij.bar")), + createModuleDescriptor("ij.bar", emptyList(), listOf("ij.foo")), + createModuleDescriptor("ij.baz", emptyList(), listOf("ij.bar")), ) val baz = repository.getModule(RuntimeModuleId.raw("ij.baz")) val bar = repository.getModule(RuntimeModuleId.raw("ij.bar")) @@ -81,8 +81,8 @@ class RepositoryTest { fun `relative path`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("ij.foo", listOf("foo.jar"), emptyList()), - RawRuntimeModuleDescriptor.create("ij.bar", listOf("../bar/bar.jar"), emptyList()), + createModuleDescriptor("ij.foo", listOf("foo.jar"), emptyList()), + createModuleDescriptor("ij.bar", listOf("../bar/bar.jar"), emptyList()), ) val foo = repository.getModule(RuntimeModuleId.raw("ij.foo")) assertEquals(listOf(tempDirectory.rootPath.resolve("foo.jar")), foo.resourceRootPaths) @@ -94,7 +94,7 @@ class RepositoryTest { fun `compute resource paths without resolving`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("ij.foo", listOf("foo.jar"), listOf("unresolved")), + createModuleDescriptor("ij.foo", listOf("foo.jar"), listOf("unresolved")), ) assertEquals(listOf(tempDirectory.rootPath.resolve("foo.jar")), repository.getModuleResourcePaths(RuntimeModuleId.raw("ij.foo"))) @@ -104,8 +104,8 @@ class RepositoryTest { fun `resource path macros`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("ij.foo", listOf("\$PROJECT_DIR$/foo.jar"), emptyList()), - RawRuntimeModuleDescriptor.create("ij.bar", listOf("${getLocalMavenRepo()}/bar/bar.jar"), emptyList()), + createModuleDescriptor("ij.foo", listOf("\$PROJECT_DIR$/foo.jar"), emptyList()), + createModuleDescriptor("ij.bar", listOf("${getLocalMavenRepo()}/bar/bar.jar"), emptyList()), ) //ensure that tempDirectory will be treated as the project root if 'idea.home.path' isn't specified explicitly @@ -135,7 +135,7 @@ class RepositoryTest { for (path in incorrectPaths) { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("ij.foo", listOf(path), emptyList()) + createModuleDescriptor("ij.foo", listOf(path), emptyList()) ) val module = repository.getModule(RuntimeModuleId.raw("ij.foo")) assertThrows(MalformedRepositoryException::class.java, { module.resourceRootPaths }, "Path $path is incorrect") @@ -146,10 +146,10 @@ class RepositoryTest { fun `module classpath`() { val repository = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("ij.foo", listOf("foo.jar"), emptyList()), - RawRuntimeModuleDescriptor.create("ij.bar", listOf("bar.jar"), listOf("ij.foo")), - RawRuntimeModuleDescriptor.create("ij.baz", listOf("baz.jar"), listOf("ij.foo")), - RawRuntimeModuleDescriptor.create("ij.main", emptyList(), listOf("ij.bar", "ij.baz")), + createModuleDescriptor("ij.foo", listOf("foo.jar"), emptyList()), + createModuleDescriptor("ij.bar", listOf("bar.jar"), listOf("ij.foo")), + createModuleDescriptor("ij.baz", listOf("baz.jar"), listOf("ij.foo")), + createModuleDescriptor("ij.main", emptyList(), listOf("ij.bar", "ij.baz")), ) val classpath = repository.getModule(RuntimeModuleId.raw("ij.main")).moduleClasspath assertEquals(listOf("bar.jar", "foo.jar", "baz.jar").map { tempDirectory.rootPath.resolve(it) }, classpath) @@ -161,8 +161,8 @@ class RepositoryTest { @CartesianTest.Values(booleans = [true, false]) loadFromCompact: Boolean ) { val descriptors = arrayOf( - RawRuntimeModuleDescriptor.create("ij.foo", listOf("foo.jar"), emptyList()), - RawRuntimeModuleDescriptor.create("ij.bar", listOf("bar.jar"), listOf("ij.foo")), + createModuleDescriptor("ij.foo", listOf("foo.jar"), emptyList()), + createModuleDescriptor("ij.bar", listOf("bar.jar"), listOf("ij.foo")), ) val basePath = tempDirectory.rootPath val bootstrapModuleName = storedBootstrapModule.takeIf { it.isNotEmpty() } @@ -183,18 +183,18 @@ class RepositoryTest { fun `additional repositories`() { val main = createRepository( tempDirectory.rootPath, - RawRuntimeModuleDescriptor.create("ij.foo", listOf("foo.jar"), emptyList()), + createModuleDescriptor("ij.foo", listOf("foo.jar"), emptyList()), ) as RuntimeModuleRepositoryImpl val additional1Path = tempDirectory.rootPath.resolve("additional1") val additional1 = createRawRepository( additional1Path, - RawRuntimeModuleDescriptor.create("custom1.foo", listOf("custom1-foo.jar"), listOf("ij.foo")), - RawRuntimeModuleDescriptor.create("custom1.bar", listOf("custom1-bar.jar"), listOf("custom1.foo")), + createModuleDescriptor("custom1.foo", listOf("custom1-foo.jar"), listOf("ij.foo")), + createModuleDescriptor("custom1.bar", listOf("custom1-bar.jar"), listOf("custom1.foo")), ) val additional2Path = tempDirectory.rootPath.resolve("additional2") val additional2 = createRawRepository( additional2Path, - RawRuntimeModuleDescriptor.create("custom2", listOf("custom2.jar"), listOf("custom1.bar")), + createModuleDescriptor("custom2", listOf("custom2.jar"), listOf("custom1.bar")), ) main.loadAdditionalRepositories(listOf(additional1, additional2)) val moduleId = RuntimeModuleId.raw("custom2") @@ -209,6 +209,6 @@ class RepositoryTest { } private fun createRawRepository(basePath: Path, vararg descriptors: RawRuntimeModuleDescriptor): RawRuntimeModuleRepositoryData { - return RawRuntimeModuleRepositoryData(descriptors.associateBy { it.id }, basePath, null) + return RawRuntimeModuleRepositoryData.create(descriptors.associateBy { it.moduleId }, basePath, null) } } \ No newline at end of file diff --git a/platform/runtime/repository/tests/testSrc/repositoryTestUtils.kt b/platform/runtime/repository/tests/testSrc/repositoryTestUtils.kt index fa5e21d6189f..53c7bf4daf34 100644 --- a/platform/runtime/repository/tests/testSrc/repositoryTestUtils.kt +++ b/platform/runtime/repository/tests/testSrc/repositoryTestUtils.kt @@ -18,7 +18,11 @@ fun DirectoryContentBuilder.xml(name: String, @Language("XML") content: String) fun createRepository(basePath: Path, vararg descriptors: RawRuntimeModuleDescriptor): RuntimeModuleRepository { val moduleDescriptorsPath = basePath.resolve("module-descriptors.dat") return RuntimeModuleRepositoryImpl(moduleDescriptorsPath, - RawRuntimeModuleRepositoryData(descriptors.associateBy { it.id }, basePath, null)) + RawRuntimeModuleRepositoryData.create(descriptors.associateBy { it.moduleId }, basePath, null)) +} + +fun createModuleDescriptor(id: String, resourcePaths: List, dependencies: List = emptyList()): RawRuntimeModuleDescriptor { + return RawRuntimeModuleDescriptor.create(RuntimeModuleId.raw(id), resourcePaths, dependencies.map { RuntimeModuleId.raw(it) }) } fun writePluginXml(resourceRoot: Path, @Language("XM") content: String) { diff --git a/platform/runtime/repository/tests/testSrc/serialization/JarRepositorySerializationTest.kt b/platform/runtime/repository/tests/testSrc/serialization/JarRepositorySerializationTest.kt index e2b5648f7fc2..fecc320b6479 100644 --- a/platform/runtime/repository/tests/testSrc/serialization/JarRepositorySerializationTest.kt +++ b/platform/runtime/repository/tests/testSrc/serialization/JarRepositorySerializationTest.kt @@ -1,6 +1,7 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.runtime.repository.serialization +import com.intellij.platform.runtime.repository.createModuleDescriptor import com.intellij.platform.runtime.repository.serialization.impl.JarFileSerializer import com.intellij.platform.runtime.repository.xml import com.intellij.testFramework.UsefulTestCase @@ -20,7 +21,7 @@ class JarRepositorySerializationTest { @Test fun `empty module`() { - check(listOf(RawRuntimeModuleDescriptor.create("ij.platform.util", emptyList(), emptyList()))) { + check(listOf(createModuleDescriptor("ij.platform.util", emptyList(), emptyList()))) { xml("ij.platform.util.xml", """ @@ -30,7 +31,7 @@ class JarRepositorySerializationTest { @Test fun `single module`() { - check(listOf(RawRuntimeModuleDescriptor.create("ij.platform.util", listOf("ij-util.jar"), emptyList()))) { + check(listOf(createModuleDescriptor("ij.platform.util", listOf("ij-util.jar"), emptyList()))) { xml("ij.platform.util.xml", """ @@ -44,8 +45,8 @@ class JarRepositorySerializationTest { @Test fun `two modules`() { check(listOf( - RawRuntimeModuleDescriptor.create("ij.platform.util.rt", listOf("ij-util-rt.jar"), emptyList()), - RawRuntimeModuleDescriptor.create("ij.platform.util", emptyList(), listOf("ij.platform.util.rt")), + createModuleDescriptor("ij.platform.util.rt", listOf("ij-util-rt.jar"), emptyList()), + createModuleDescriptor("ij.platform.util", emptyList(), listOf("ij.platform.util.rt")), )) { xml("ij.platform.util.xml", """ @@ -67,8 +68,8 @@ class JarRepositorySerializationTest { @Test fun `bootstrap module classpath`() { check(listOf( - RawRuntimeModuleDescriptor.create("foo", listOf("foo.jar"), emptyList()), - RawRuntimeModuleDescriptor.create("bar", listOf("bar.jar"), listOf("foo")), + createModuleDescriptor("foo", listOf("foo.jar"), emptyList()), + createModuleDescriptor("bar", listOf("bar.jar"), listOf("foo")), ), "bar", "bar.jar foo.jar") { xml("foo.xml", """ @@ -93,8 +94,8 @@ class JarRepositorySerializationTest { @Test fun `unresolved dependency`() { val descriptors = listOf( - RawRuntimeModuleDescriptor.create("ij.foo", emptyList(), emptyList()), - RawRuntimeModuleDescriptor.create("ij.bar", emptyList(), listOf("ij.foo", "unresolved")), + createModuleDescriptor("ij.foo", emptyList(), emptyList()), + createModuleDescriptor("ij.bar", emptyList(), listOf("ij.foo", "unresolved")), ) check(descriptors) { xml("ij.foo.xml", """ @@ -147,13 +148,13 @@ class JarRepositorySerializationTest { private fun checkLoadingFromCompactFile(filePath: Path, expectedDescriptors: List) { val repositoryData = RuntimeModuleRepositorySerialization.loadFromCompactFile(filePath) - val actualDescriptors = repositoryData.allIds.map { repositoryData.findDescriptor(it)!! } + val actualDescriptors = repositoryData.allModuleIds.map { repositoryData.findDescriptor(it)!! } UsefulTestCase.assertSameElements(actualDescriptors, expectedDescriptors) } private fun checkLoadingFromJar(zipFileSpec: DirectoryContentSpec, expectedDescriptors: List) { val repositoryData = RuntimeModuleRepositorySerialization.loadFromJar(zipFileSpec.generateInTempDir()) - val actualDescriptors = repositoryData.allIds.map { repositoryData.findDescriptor(it)!! } + val actualDescriptors = repositoryData.allModuleIds.map { repositoryData.findDescriptor(it)!! } UsefulTestCase.assertSameElements(actualDescriptors, expectedDescriptors) } } \ No newline at end of file diff --git a/platform/testFramework/monorepo/tests/runtimeModuleRepository/RuntimeModuleRepositoryForTests.kt b/platform/testFramework/monorepo/tests/runtimeModuleRepository/RuntimeModuleRepositoryForTests.kt index 431a515dffae..f1aad5b872c0 100644 --- a/platform/testFramework/monorepo/tests/runtimeModuleRepository/RuntimeModuleRepositoryForTests.kt +++ b/platform/testFramework/monorepo/tests/runtimeModuleRepository/RuntimeModuleRepositoryForTests.kt @@ -42,7 +42,7 @@ fun generateRuntimeModuleRepositoryForTests(monorepoProject: JpsProject): Runtim //the repository won't be saved on disk so the actual location of the directory doesn't matter much val outputDirectory = JpsModelSerializationDataService.getBaseDirectoryPath(monorepoProject)!!.resolve("out/module-descriptors-for-tests") - val repositoryData = RawRuntimeModuleRepositoryData(moduleDescriptors.associateBy { it.id }, outputDirectory, null) + val repositoryData = RawRuntimeModuleRepositoryData.create(moduleDescriptors.associateBy { it.moduleId }, outputDirectory, null) return RuntimeModuleRepositoryImpl(outputDirectory.resolve(RuntimeModuleRepositoryGenerator.COMPACT_REPOSITORY_FILE_NAME), repositoryData) } diff --git a/plugins/devkit/runtimeModuleRepository/generator/src/RuntimeModuleRepositoryGenerator.kt b/plugins/devkit/runtimeModuleRepository/generator/src/RuntimeModuleRepositoryGenerator.kt index e47c4bf058a9..036b9b80c446 100644 --- a/plugins/devkit/runtimeModuleRepository/generator/src/RuntimeModuleRepositoryGenerator.kt +++ b/plugins/devkit/runtimeModuleRepository/generator/src/RuntimeModuleRepositoryGenerator.kt @@ -53,7 +53,7 @@ object RuntimeModuleRepositoryGenerator { generateDescriptorsForModules(descriptors, includedProduction, includedTests, resourcePathsSchema) for (library in includedProjectLibraries) { val moduleId = getProjectLibraryId(library) ?: error("Project-level library expected, but found: $library") - descriptors.add(RawRuntimeModuleDescriptor.create(moduleId.stringId, resourcePathsSchema.libraryPaths(library), emptyList())) + descriptors.add(RawRuntimeModuleDescriptor.create(moduleId, resourcePathsSchema.libraryPaths(library), emptyList())) } return descriptors } @@ -94,22 +94,22 @@ private fun generateDescriptorsForModules( } } - fun getRuntimeModuleName(module: JpsModule, tests: Boolean): String { + fun getRuntimeModuleName(module: JpsModule, tests: Boolean): RuntimeModuleId { val moduleName = module.name if (tests) { if (moduleName in productionModulesWithTestRoots) { - return moduleName + RuntimeModuleId.TESTS_NAME_SUFFIX + "2" + return RuntimeModuleId.raw(moduleName + RuntimeModuleId.TESTS_NAME_SUFFIX + "2") } if (!moduleName.endsWith(RuntimeModuleId.TESTS_NAME_SUFFIX)) { - return moduleName + RuntimeModuleId.TESTS_NAME_SUFFIX + return RuntimeModuleId.moduleTests(moduleName) } } else { if (moduleName in testModulesWithProductionRoots) { - return moduleName + "2" + return RuntimeModuleId.raw(moduleName + "2") } } - return moduleName + return RuntimeModuleId.module(moduleName) } for (module in includedProduction) { @@ -142,15 +142,15 @@ private val JpsModule.hasTestSources private val JpsModule.hasProductionSources get() = sourceRoots.any { it.rootType in JavaModuleSourceRootTypes.PRODUCTION } -private fun createProductionPartDescriptor(module: JpsModule, runtimeModuleNameGenerator: (JpsModule, Boolean) -> String, resourcePathsSchema: ResourcePathsSchema): RawRuntimeModuleDescriptor { - val dependencies = LinkedHashSet() +private fun createProductionPartDescriptor(module: JpsModule, runtimeModuleNameGenerator: (JpsModule, Boolean) -> RuntimeModuleId, resourcePathsSchema: ResourcePathsSchema): RawRuntimeModuleDescriptor { + val dependencies = LinkedHashSet() val resourcePaths = if (module.hasProductionSources) resourcePathsSchema.moduleOutputPaths(module).toMutableSet() else mutableSetOf() enumerateRuntimeDependencies(module).productionOnly().processModuleAndLibraries( { dependencies.add(runtimeModuleNameGenerator(it, false)) }, { library -> val projectLibraryId = getProjectLibraryId(library) if (projectLibraryId != null) { - dependencies.add(projectLibraryId.stringId) + dependencies.add(projectLibraryId) } else { resourcePaths.addAll(resourcePathsSchema.libraryPaths(library)) @@ -169,7 +169,7 @@ private fun createProductionPartDescriptor(module: JpsModule, runtimeModuleNameG */ private fun createTestPartDescriptor( module: JpsModule, - runtimeModuleNameGenerator: (JpsModule, Boolean) -> String, + runtimeModuleNameGenerator: (JpsModule, Boolean) -> RuntimeModuleId, additionalDependenciesForTestsCache: MutableMap, productionDependenciesCache: MutableMap, resourcePathsSchema: ResourcePathsSchema, @@ -187,7 +187,7 @@ private fun createTestPartDescriptor( resourcePathsSchema ) forTests.copyTo(dependencies, resourcePaths) - return RawRuntimeModuleDescriptor.create(runtimeModuleNameGenerator(module, true), resourcePaths.toList(), dependencies.map { it.stringId }) + return RawRuntimeModuleDescriptor.create(runtimeModuleNameGenerator(module, true), resourcePaths.toList(), dependencies.toList()) } /** @@ -196,7 +196,7 @@ private fun createTestPartDescriptor( private fun collectProductionDependenciesForModule( module: JpsModule, productionDependenciesCache: MutableMap, - runtimeModuleNameGenerator: (JpsModule, Boolean) -> String, + runtimeModuleNameGenerator: (JpsModule, Boolean) -> RuntimeModuleId, resourcePathsSchema: ResourcePathsSchema, ) : DependenciesAndResources { val cached = productionDependenciesCache[module] @@ -204,7 +204,7 @@ private fun collectProductionDependenciesForModule( return cached } if (module.hasDescriptorForProduction) { - val result = DependenciesAndResources(setOf(RuntimeModuleId.raw(runtimeModuleNameGenerator(module, false))), emptySet()) + val result = DependenciesAndResources(setOf(runtimeModuleNameGenerator(module, false)), emptySet()) productionDependenciesCache[module] = result return result } @@ -256,7 +256,7 @@ private fun collectAdditionalRuntimeDependenciesAndResourcesForTests( module: JpsModule, productionDependenciesCache: MutableMap, additionalDependenciesForTestsCache: MutableMap, - runtimeModuleNameGenerator: (JpsModule, Boolean) -> String, + runtimeModuleNameGenerator: (JpsModule, Boolean) -> RuntimeModuleId, resourcePathsSchema: ResourcePathsSchema ): DependenciesAndResources { val cached = additionalDependenciesForTestsCache[module] @@ -274,7 +274,7 @@ private fun collectAdditionalRuntimeDependenciesAndResourcesForTests( if (scope == JpsJavaDependencyScope.PROVIDED) continue if (dependencyModule.hasTestSources) { - dependencies.add(RuntimeModuleId.raw(runtimeModuleNameGenerator(dependencyModule, true))) + dependencies.add(runtimeModuleNameGenerator(dependencyModule, true)) } else { if (scope == JpsJavaDependencyScope.TEST) { diff --git a/plugins/devkit/runtimeModuleRepository/generator/src/RuntimeModuleRepositoryValidator.kt b/plugins/devkit/runtimeModuleRepository/generator/src/RuntimeModuleRepositoryValidator.kt index 24713e7404d0..1df8f45d1e4c 100644 --- a/plugins/devkit/runtimeModuleRepository/generator/src/RuntimeModuleRepositoryValidator.kt +++ b/plugins/devkit/runtimeModuleRepository/generator/src/RuntimeModuleRepositoryValidator.kt @@ -1,18 +1,19 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.devkit.runtimeModuleRepository.generator +import com.intellij.platform.runtime.repository.RuntimeModuleId import com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor object RuntimeModuleRepositoryValidator { interface ErrorReporter { - fun reportDuplicatingId(moduleId: String) + fun reportDuplicatingId(moduleId: RuntimeModuleId) } fun validate(descriptors: List, errorReporter: ErrorReporter) { - val moduleIDs = HashSet() + val moduleIDs = HashSet() for (descriptor in descriptors) { - if (!moduleIDs.add(descriptor.id)) { - errorReporter.reportDuplicatingId(descriptor.id) + if (!moduleIDs.add(descriptor.moduleId)) { + errorReporter.reportDuplicatingId(descriptor.moduleId) } } } diff --git a/plugins/devkit/runtimeModuleRepository/jps/src/build/RuntimeModuleRepositoryBuilder.kt b/plugins/devkit/runtimeModuleRepository/jps/src/build/RuntimeModuleRepositoryBuilder.kt index 2892a96f9ab3..3ff48a768a68 100644 --- a/plugins/devkit/runtimeModuleRepository/jps/src/build/RuntimeModuleRepositoryBuilder.kt +++ b/plugins/devkit/runtimeModuleRepository/jps/src/build/RuntimeModuleRepositoryBuilder.kt @@ -6,6 +6,7 @@ import com.intellij.devkit.runtimeModuleRepository.generator.RuntimeModuleReposi import com.intellij.devkit.runtimeModuleRepository.generator.RuntimeModuleRepositoryValidator import com.intellij.devkit.runtimeModuleRepository.jps.impl.DevkitRuntimeModuleRepositoryJpsBundle import com.intellij.openapi.diagnostic.logger +import com.intellij.platform.runtime.repository.RuntimeModuleId import com.intellij.platform.runtime.repository.serialization.RawRuntimeModuleDescriptor import com.intellij.platform.runtime.repository.serialization.RuntimeModuleRepositorySerialization import com.intellij.platform.runtime.repository.serialization.impl.CompactFileWriter @@ -53,8 +54,8 @@ internal class RuntimeModuleRepositoryBuilder LOG.info("${descriptors.size} descriptors are created in ${timeToCreateDescriptors}ms") val errorReporter = object : RuntimeModuleRepositoryValidator.ErrorReporter { - override fun reportDuplicatingId(moduleId: String) { - context.reportError(DevkitRuntimeModuleRepositoryJpsBundle.message("error.message.duplicating.id.0.is.found", moduleId)) + override fun reportDuplicatingId(moduleId: RuntimeModuleId) { + context.reportError(DevkitRuntimeModuleRepositoryJpsBundle.message("error.message.duplicating.id.0.is.found", moduleId.presentableName)) } } RuntimeModuleRepositoryValidator.validate(descriptors, errorReporter) diff --git a/plugins/devkit/runtimeModuleRepository/jps/testSrc/build/RuntimeModuleRepositoryCheckers.kt b/plugins/devkit/runtimeModuleRepository/jps/testSrc/build/RuntimeModuleRepositoryCheckers.kt index 7fdaef785fc3..e64f4f8a895c 100644 --- a/plugins/devkit/runtimeModuleRepository/jps/testSrc/build/RuntimeModuleRepositoryCheckers.kt +++ b/plugins/devkit/runtimeModuleRepository/jps/testSrc/build/RuntimeModuleRepositoryCheckers.kt @@ -21,12 +21,12 @@ private fun checkRuntimeModuleRepository( buildRepositoryData: RawRuntimeModuleRepositoryData, expected: RawDescriptorListBuilder.() -> Unit, ) { - val actualIds = buildRepositoryData.allIds.filter { it != RUNTIME_REPOSITORY_MARKER_MODULE && it != "${RUNTIME_REPOSITORY_MARKER_MODULE}${RuntimeModuleId.TESTS_NAME_SUFFIX}" } + val actualIds = buildRepositoryData.allModuleIds.filter { it != RUNTIME_REPOSITORY_MARKER_MODULE && it != RUNTIME_REPOSITORY_TESTS_MARKER_MODULE } val builder = RawDescriptorListBuilder() builder.expected() - JpsBuildTestCase.assertSameElements(actualIds, builder.descriptors.map { it.id }) + JpsBuildTestCase.assertSameElements(actualIds, builder.descriptors.map { it.moduleId }) for (expectedDescriptor in builder.descriptors) { - JpsBuildTestCase.assertEquals("Different data for '${expectedDescriptor.id}'.", expectedDescriptor, buildRepositoryData.findDescriptor(expectedDescriptor.id)!!) + JpsBuildTestCase.assertEquals("Different data for '${expectedDescriptor.moduleId.presentableName}'.", expectedDescriptor, buildRepositoryData.findDescriptor(expectedDescriptor.moduleId)!!) } } @@ -45,8 +45,9 @@ class RawDescriptorListBuilder { } fun descriptor(id: String, resources: List, dependencies: List) { - descriptors.add(RawRuntimeModuleDescriptor.create(id, resources, dependencies)) + descriptors.add(RawRuntimeModuleDescriptor.create(RuntimeModuleId.raw(id), resources, dependencies.map { RuntimeModuleId.raw(it) })) } } -const val RUNTIME_REPOSITORY_MARKER_MODULE: String = "intellij.idea.community.main" \ No newline at end of file +internal val RUNTIME_REPOSITORY_MARKER_MODULE: RuntimeModuleId = RuntimeModuleId.module("intellij.idea.community.main") +internal val RUNTIME_REPOSITORY_TESTS_MARKER_MODULE: RuntimeModuleId = RuntimeModuleId.moduleTests("intellij.idea.community.main") \ No newline at end of file diff --git a/plugins/devkit/runtimeModuleRepository/jps/testSrc/build/RuntimeModuleRepositoryTestCase.kt b/plugins/devkit/runtimeModuleRepository/jps/testSrc/build/RuntimeModuleRepositoryTestCase.kt index b732656ef80b..2d7e81efdfec 100644 --- a/plugins/devkit/runtimeModuleRepository/jps/testSrc/build/RuntimeModuleRepositoryTestCase.kt +++ b/plugins/devkit/runtimeModuleRepository/jps/testSrc/build/RuntimeModuleRepositoryTestCase.kt @@ -14,7 +14,7 @@ import kotlin.io.path.writeText abstract class RuntimeModuleRepositoryTestCase : JpsBuildTestCase() { override fun setUp() { super.setUp() - addModule(RUNTIME_REPOSITORY_MARKER_MODULE) + addModule(RUNTIME_REPOSITORY_MARKER_MODULE.stringId) JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(myProject).outputUrl = getUrl("out") val projectDir = Path(getAbsolutePath("project")) val modulesXml = projectDir.resolve(".idea/modules.xml")