[kotlin] refactor ScriptClassPathVirtualFileCache

#KTIJ-33351

GitOrigin-RevId: f401644ad6aa3d063bfbb5391c38eaca51f2b9a4
This commit is contained in:
Vlad Koshkin
2025-04-07 20:06:56 +00:00
committed by intellij-monorepo-bot
parent 1a6b73e52b
commit 61eb40745b
4 changed files with 32 additions and 35 deletions
@@ -16,18 +16,7 @@ import kotlin.script.experimental.api.ScriptDependency
import kotlin.script.experimental.jvm.JvmDependency
class ScriptClassPathUtil {
private constructor()
private val cache = mutableMapOf<String, VirtualFile?>()
fun findVirtualFile(pathString: String): VirtualFile? =
cache.computeIfAbsent(pathString) {
ScriptClassPathUtil.findVirtualFile(pathString)
}
companion object {
fun getInstance(): ScriptClassPathUtil = ScriptClassPathUtil()
fun List<ScriptDependency>?.findVirtualFiles(): List<VirtualFile> {
this ?: return emptyList()
return this
@@ -39,7 +28,7 @@ class ScriptClassPathUtil {
fun findVirtualFile(pathString: String): VirtualFile? {
val path = pathString.toNioPathOrNull()
val resultFile = when {
return when {
path == null -> {
scriptingWarnLog("Invalid classpath entry '$pathString'")
null
@@ -63,8 +52,6 @@ class ScriptClassPathUtil {
null
}
}
return resultFile
}
private fun VirtualFileSystem.refreshIfNeededAndFindFileByPath(path: String): VirtualFile? {
@@ -81,3 +68,16 @@ class ScriptClassPathUtil {
}
}
}
class ScriptVirtualFileCache() {
private val cache = mutableMapOf<String, Result<VirtualFile>>()
fun findVirtualFile(pathString: String): VirtualFile? {
val result = cache.computeIfAbsent(pathString) {
val resultFile = ScriptClassPathUtil.findVirtualFile(pathString)
resultFile?.let { Result.success(it) } ?: Result.failure(Throwable())
}
return result.getOrNull()
}
}
@@ -33,23 +33,9 @@ private class ScriptDependenciesData(
) {
operator fun plus(other: ScriptDependenciesData): ScriptDependenciesData {
return ScriptDependenciesData(
this.classes + other.classes,
this.sources + other.sources,
this.sdks + other.sdks
this.classes + other.classes, this.sources + other.sources, this.sdks + other.sdks
)
}
companion object {
fun from(configuration: ScriptConfigurationWithSdk): ScriptDependenciesData {
val cache = ScriptClassPathUtil.getInstance()
return ScriptDependenciesData(
configuration.scriptConfiguration.valueOrNull()?.dependenciesClassPath?.mapNotNull { cache.findVirtualFile(it.path) }
?.toSet() ?: emptySet(),
configuration.scriptConfiguration.valueOrNull()?.dependenciesSources?.mapNotNull { cache.findVirtualFile(it.path) }
?.toSet() ?: emptySet(),
)
}
}
}
class ScriptConfigurationsProviderImpl(project: Project, val coroutineScope: CoroutineScope) : ScriptConfigurationsProvider(project),
@@ -57,8 +43,20 @@ class ScriptConfigurationsProviderImpl(project: Project, val coroutineScope: Cor
private val allDependencies = AtomicReference(ScriptDependenciesData())
fun store(configurations: Collection<ScriptConfigurationWithSdk>) {
val cache = ScriptVirtualFileCache()
val dataToAdd = configurations.fold(ScriptDependenciesData()) { left, right ->
left + ScriptDependenciesData.from(right)
val configurationWrapper = right.scriptConfiguration.valueOrNull()
if (configurationWrapper == null) {
left
} else {
left + ScriptDependenciesData(
configurationWrapper.dependenciesClassPath.mapNotNull { cache.findVirtualFile(it.path) }.toSet(),
configurationWrapper.dependenciesSources.mapNotNull { cache.findVirtualFile(it.path) }.toSet(),
setOfNotNull(right.sdk)
)
}
}
allDependencies.accumulateAndGet(dataToAdd) { left, right -> left + right }
}
@@ -90,16 +90,15 @@ fun MutableEntityStorage.getOrCreateDefinitionDependency(
val libraryId = LibraryId(".${definition.fileExtension} definition dependencies", LibraryTableId.ProjectLibraryTableId)
if (!this.contains(libraryId)) {
val fileUrlManager = WorkspaceModel.getInstance(project).getVirtualFileUrlManager()
val virtualFileCache = ScriptClassPathUtil.getInstance()
val classes = definition.compilationConfiguration[ScriptCompilationConfiguration.dependencies]
.toClassPathOrEmpty()
.mapNotNull { virtualFileCache.findVirtualFile(it.path) }
.mapNotNull { ScriptClassPathUtil.findVirtualFile(it.path) }
.sortedBy { it.name }
val sources = definition.compilationConfiguration[ScriptCompilationConfiguration.ide.dependenciesSources]
.toClassPathOrEmpty()
.mapNotNull { virtualFileCache.findVirtualFile(it.path) }
.mapNotNull { ScriptClassPathUtil.findVirtualFile(it.path) }
.sortedBy { it.name }
val classRoots = classes.map {
@@ -87,7 +87,7 @@ class GradleScriptRefinedConfigurationProvider(
val result = MutableEntityStorage.create()
val urlManager = WorkspaceModel.getInstance(project).getVirtualFileUrlManager()
val virtualFileCache = ScriptClassPathUtil.getInstance()
val virtualFileCache = ScriptVirtualFileCache()
val dependencyFactory = ScriptDependencyFactory(result, configurations, virtualFileCache)
for ((scriptFile, configurationWithSdk) in configurations) {
@@ -179,7 +179,7 @@ class GradleScriptRefinedConfigurationProvider(
inner class ScriptDependencyFactory(
private val entityStorage: MutableEntityStorage,
scripts: Map<VirtualFile, ScriptConfigurationWithSdk>,
virtualFileCache: ScriptClassPathUtil,
virtualFileCache: ScriptVirtualFileCache,
) {
private val nameCache = HashMap<String, Set<VirtualFile>>()