mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[DependencySubstitution] cleanup: encapsulate coordinate matching inside DependencySubstitutionExtension
Encapsulated dependency coordinates allows to misunderstanding what is the dependency coordinates and how they should compare with each other. Also, it forbids dependency coordinate hijack by other extensions. Maven coordinates should be specified only by the Library and Module Maven coordinate entities. ### Code Reviews * IJ-CR-164983 ### Issues * IDEA-370483 Maven performance degradation related to library dependency substitution GitOrigin-RevId: 01461ea4bf0fe44e60a80404a2cf08f16c0d5853
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5a7b7533f6
commit
f10a240e01
@@ -1421,7 +1421,7 @@
|
||||
<externalProjectDataService implementation="com.intellij.externalSystem.JavaModuleDataService"/>
|
||||
<externalWorkspaceDataService implementation="com.intellij.externalSystem.JavaManifestDataService"/>
|
||||
<libraryDataServiceExtension implementation="com.intellij.externalSystem.JavaLibraryDataServiceExtension"/>
|
||||
<dependencySubstitutionCoordinateContributor implementation="com.intellij.java.impl.dependencySubstitution.DependencySubstitutionMavenCoordinateContributor"/>
|
||||
<dependencySubstitutionCoordinateContributor implementation="com.intellij.java.impl.dependencySubstitution.MavenCoordinateDependencySubstitutionExtension"/>
|
||||
<postStartupActivity implementation="com.intellij.pom.java.AcceptedLanguageLevelsSettingsStartupActivity"/>
|
||||
<projectModelModifier implementation="com.intellij.openapi.roots.impl.IdeaProjectModelModifier" order="last"/>
|
||||
<multiHostInjector implementation="com.intellij.psi.impl.source.tree.injected.JavaConcatenationToInjectorAdapter" order="first"/>
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
// 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.java.impl.dependencySubstitution
|
||||
|
||||
import com.intellij.java.library.MavenCoordinates
|
||||
import com.intellij.platform.externalSystem.impl.dependencySubstitution.DependencySubstitutionCoordinateContributor
|
||||
import com.intellij.platform.workspace.jps.entities.LibraryEntity
|
||||
import com.intellij.platform.workspace.jps.entities.ModuleEntity
|
||||
|
||||
private class DependencySubstitutionMavenCoordinateContributor : DependencySubstitutionCoordinateContributor {
|
||||
|
||||
override fun findModuleCoordinate(module: ModuleEntity): MavenCoordinates? {
|
||||
return module.mavenCoordinates?.coordinates
|
||||
}
|
||||
|
||||
override fun findLibraryCoordinate(library: LibraryEntity): MavenCoordinates? {
|
||||
return library.mavenCoordinates?.coordinates
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// 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.java.impl.dependencySubstitution
|
||||
|
||||
import com.intellij.platform.externalSystem.impl.dependencySubstitution.DependencySubstitutionExtension
|
||||
import com.intellij.platform.externalSystem.impl.dependencySubstitution.DependencySubstitutionUtil.intersect
|
||||
import com.intellij.platform.workspace.jps.entities.LibraryId
|
||||
import com.intellij.platform.workspace.jps.entities.ModuleId
|
||||
import com.intellij.platform.workspace.storage.EntityStorage
|
||||
import com.intellij.platform.workspace.storage.entities
|
||||
|
||||
private class MavenCoordinateDependencySubstitutionExtension : DependencySubstitutionExtension {
|
||||
|
||||
override fun buildLibraryToModuleMap(storage: EntityStorage): Map<LibraryId, ModuleId> {
|
||||
val libraries = storage.entities<LibraryMavenCoordinateEntity>()
|
||||
.associate { it.coordinates to it.library.symbolicId }
|
||||
val modules = storage.entities<ModuleMavenCoordinateEntity>()
|
||||
.associate { it.coordinates to it.module.symbolicId }
|
||||
return libraries.intersect(modules)
|
||||
}
|
||||
}
|
||||
@@ -75,8 +75,3 @@ f:com.intellij.openapi.externalSystem.service.ui.ExternalSystemJdkComboBox
|
||||
- sf:INSTANCE:com.intellij.openapi.externalSystem.util.task.TaskExecutionUtil
|
||||
- f:runTask(com.intellij.openapi.externalSystem.util.task.TaskExecutionSpec,kotlin.coroutines.Continuation):java.lang.Object
|
||||
- f:runTask(com.intellij.openapi.externalSystem.util.task.TaskExecutionSpecBuilder,kotlin.coroutines.Continuation):java.lang.Object
|
||||
*:com.intellij.platform.externalSystem.impl.dependencySubstitution.DependencySubstitutionCoordinateContributor
|
||||
- *sf:Companion:com.intellij.platform.externalSystem.impl.dependencySubstitution.DependencySubstitutionCoordinateContributor$Companion
|
||||
- findLibraryCoordinate(com.intellij.platform.workspace.jps.entities.LibraryEntity):java.lang.Object
|
||||
- findModuleCoordinate(com.intellij.platform.workspace.jps.entities.ModuleEntity):java.lang.Object
|
||||
*f:com.intellij.platform.externalSystem.impl.dependencySubstitution.DependencySubstitutionCoordinateContributor$Companion
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
interface="com.intellij.openapi.externalSystem.debugger.DebuggerBackendExtension"
|
||||
dynamic="true"/>
|
||||
<extensionPoint qualifiedName="com.intellij.dependencySubstitutionCoordinateContributor"
|
||||
interface="com.intellij.platform.externalSystem.impl.dependencySubstitution.DependencySubstitutionCoordinateContributor"
|
||||
interface="com.intellij.platform.externalSystem.impl.dependencySubstitution.DependencySubstitutionExtension"
|
||||
dynamic="true"/>
|
||||
<extensionPoint qualifiedName="com.intellij.externalProjectDataService"
|
||||
interface="com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService"
|
||||
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
// 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.externalSystem.impl.dependencySubstitution
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.platform.workspace.jps.entities.LibraryEntity
|
||||
import com.intellij.platform.workspace.jps.entities.ModuleEntity
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* Defines mapping between ide entities and entities' global coordinates.
|
||||
* The import can use that mapping for binary dependencies substitution on module dependencies
|
||||
* across unrelated projects based on any build system or another kind of project modules generator.
|
||||
*
|
||||
* For example, maven coordinates can be used as global coordinates.
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
interface DependencySubstitutionCoordinateContributor {
|
||||
|
||||
/**
|
||||
* Finds global module coordinates. For example, maven coordinates.
|
||||
*
|
||||
* @param module is a module to find artifact coordinates of a corresponding external project.
|
||||
* @return found global module coordinates.
|
||||
*/
|
||||
fun findModuleCoordinate(module: ModuleEntity): Any? = null
|
||||
|
||||
/**
|
||||
* Finds global library coordinates. For example, maven coordinates.
|
||||
*
|
||||
* @param library is a library to find artifact coordinates of a corresponding external library.
|
||||
* @return found global library coordinates.
|
||||
*/
|
||||
fun findLibraryCoordinate(library: LibraryEntity): Any? = null
|
||||
|
||||
companion object {
|
||||
|
||||
@ApiStatus.Internal
|
||||
val EP_NAME: ExtensionPointName<DependencySubstitutionCoordinateContributor> =
|
||||
ExtensionPointName.create("com.intellij.dependencySubstitutionCoordinateContributor")
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
// 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.externalSystem.impl.dependencySubstitution
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.platform.workspace.jps.entities.LibraryId
|
||||
import com.intellij.platform.workspace.jps.entities.ModuleId
|
||||
import com.intellij.platform.workspace.storage.EntityStorage
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* Defines mapping between ide library and module entities.
|
||||
*
|
||||
* The import can use that mapping for library dependencies substitution on module dependencies
|
||||
* across all external projects.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
interface DependencySubstitutionExtension {
|
||||
|
||||
/**
|
||||
* Builds relation between library and module dependencies based on any library and module characteristic.
|
||||
*
|
||||
* Note: this function may be executed under write action.
|
||||
*/
|
||||
fun buildLibraryToModuleMap(storage: EntityStorage): Map<LibraryId, ModuleId>
|
||||
|
||||
companion object {
|
||||
|
||||
val EP_NAME: ExtensionPointName<DependencySubstitutionExtension> =
|
||||
ExtensionPointName.create("com.intellij.dependencySubstitutionCoordinateContributor")
|
||||
}
|
||||
}
|
||||
+14
-38
@@ -9,7 +9,6 @@ import com.intellij.platform.workspace.storage.EntityStorage
|
||||
import com.intellij.platform.workspace.storage.MutableEntityStorage
|
||||
import com.intellij.platform.workspace.storage.entities
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import kotlin.collections.iterator
|
||||
|
||||
@ApiStatus.Internal
|
||||
object DependencySubstitutionUtil {
|
||||
@@ -110,48 +109,25 @@ object DependencySubstitutionUtil {
|
||||
return moduleDependency
|
||||
}
|
||||
|
||||
private fun buildLibraryToCoordinateMap(storage: EntityStorage): Map<LibraryId, Any> {
|
||||
TELEMETRY.spanBuilder("buildLibraryToCoordinateMap").use {
|
||||
val result = HashMap<LibraryId, Any>()
|
||||
DependencySubstitutionCoordinateContributor.EP_NAME.forEachExtensionSafe { contributor ->
|
||||
TELEMETRY.spanBuilder("findLibraryCoordinate").use { span ->
|
||||
span.setAttribute("contributor", contributor.javaClass.name)
|
||||
for (library in storage.entities<LibraryEntity>()) {
|
||||
val libraryCoordinate = contributor.findLibraryCoordinate(library) ?: continue
|
||||
result[library.symbolicId] = libraryCoordinate
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildCoordinateToModuleMap(storage: EntityStorage): Map<Any, ModuleId> {
|
||||
TELEMETRY.spanBuilder("buildCoordinateToModuleMap").use {
|
||||
val result = HashMap<Any, ModuleId>()
|
||||
DependencySubstitutionCoordinateContributor.EP_NAME.forEachExtensionSafe { contributor ->
|
||||
TELEMETRY.spanBuilder("findModuleCoordinate").use { span ->
|
||||
span.setAttribute("contributor", contributor.javaClass.name)
|
||||
for (module in storage.entities<ModuleEntity>()) {
|
||||
val moduleCoordinate = contributor.findModuleCoordinate(module) ?: continue
|
||||
result[moduleCoordinate] = module.symbolicId
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildLibraryToModuleMap(storage: EntityStorage): Map<LibraryId, ModuleId> {
|
||||
TELEMETRY.spanBuilder("buildLibraryToModuleMap").use {
|
||||
val libraryToCoordinateMap = buildLibraryToCoordinateMap(storage)
|
||||
val coordinateToModuleMap = buildCoordinateToModuleMap(storage)
|
||||
val result = HashMap<LibraryId, ModuleId>()
|
||||
for ((libraryId, libraryCoordinate) in libraryToCoordinateMap) {
|
||||
val moduleId = coordinateToModuleMap[libraryCoordinate] ?: continue
|
||||
result[libraryId] = moduleId
|
||||
DependencySubstitutionExtension.EP_NAME.forEachExtensionSafe { contributor ->
|
||||
TELEMETRY.spanBuilder("buildDependencyMap").use { span ->
|
||||
span.setAttribute("contributor", contributor.javaClass.name)
|
||||
result.putAll(contributor.buildLibraryToModuleMap(storage))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
fun <K: Any?, V1, V2> Map<K, V1>.intersect(other: Map<K, V2>): Map<V1, V2> {
|
||||
val result = HashMap<V1, V2>()
|
||||
for ((key, value1) in this) {
|
||||
result[value1] = other[key ?: continue] ?: continue
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
+15
-8
@@ -1,24 +1,31 @@
|
||||
// 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.openapi.externalSystem.dependencySubstitution
|
||||
|
||||
import com.intellij.platform.externalSystem.impl.dependencySubstitution.DependencySubstitutionCoordinateContributor
|
||||
import com.intellij.platform.externalSystem.impl.dependencySubstitution.DependencySubstitutionExtension
|
||||
import com.intellij.platform.externalSystem.impl.dependencySubstitution.DependencySubstitutionUtil.intersect
|
||||
import com.intellij.platform.workspace.jps.entities.LibraryEntity
|
||||
import com.intellij.platform.workspace.jps.entities.LibraryId
|
||||
import com.intellij.platform.workspace.jps.entities.ModuleEntity
|
||||
import com.intellij.platform.workspace.jps.entities.ModuleId
|
||||
import com.intellij.platform.workspace.storage.EntityStorage
|
||||
import com.intellij.platform.workspace.storage.entities
|
||||
import com.intellij.testFramework.junit5.fixture.extensionPointFixture
|
||||
|
||||
abstract class DependencySubstitutionTestCase {
|
||||
|
||||
val coordinates by extensionPointFixture(DependencySubstitutionCoordinateContributor.EP_NAME, ::TestCoordinateContributor)
|
||||
val coordinates by extensionPointFixture(DependencySubstitutionExtension.EP_NAME, ::TestDependencySubstitutionExtension)
|
||||
|
||||
class TestCoordinateContributor : DependencySubstitutionCoordinateContributor {
|
||||
class TestDependencySubstitutionExtension : DependencySubstitutionExtension {
|
||||
|
||||
val modules = HashMap<String, String>()
|
||||
val libraries = HashMap<String, String>()
|
||||
|
||||
override fun findModuleCoordinate(module: ModuleEntity): String? =
|
||||
modules[module.name]
|
||||
|
||||
override fun findLibraryCoordinate(library: LibraryEntity): String? =
|
||||
libraries[library.name]
|
||||
override fun buildLibraryToModuleMap(storage: EntityStorage): Map<LibraryId, ModuleId> {
|
||||
val libraries = storage.entities<LibraryEntity>()
|
||||
.associate { libraries[it.name] to it.symbolicId }
|
||||
val modules = storage.entities<ModuleEntity>()
|
||||
.associate { modules[it.name] to it.symbolicId }
|
||||
return libraries.intersect(modules)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user