Refactoring: move ScriptBinariesScopeCache to ScriptDependenciesCache

This commit is contained in:
Natalia Selezneva
2019-04-26 15:18:34 +03:00
parent c2717b3006
commit 5bc7b61497
3 changed files with 30 additions and 18 deletions
@@ -5,20 +5,15 @@
package org.jetbrains.kotlin.idea.caches.project
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.NonClasspathDirectoriesScope
import com.intellij.util.containers.SLRUCache
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesCache.Companion.MAX_SCRIPTS_CACHED
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager
import org.jetbrains.kotlin.idea.core.script.dependencies.ScriptAdditionalIdeaDependenciesProvider
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.scripting.definitions.KotlinScriptDefinition
import kotlin.script.experimental.dependencies.ScriptDependencies
data class ScriptModuleInfo(
val project: Project,
@@ -76,9 +71,6 @@ sealed class ScriptDependenciesInfo(val project: Project) : IdeaModuleInfo, Bina
val scriptFile: VirtualFile,
val scriptDefinition: KotlinScriptDefinition
) : ScriptDependenciesInfo(project) {
private val externalDependencies: ScriptDependencies
get() = ScriptDependenciesManager.getInstance(project).getScriptDependencies(scriptFile)
override val sdk: Sdk?
get() {
val manager = ScriptDependenciesManager.getInstance(project)
@@ -86,7 +78,10 @@ sealed class ScriptDependenciesInfo(val project: Project) : IdeaModuleInfo, Bina
}
override fun contentScope(): GlobalSearchScope {
return ServiceManager.getService(project, ScriptBinariesScopeCache::class.java).get(externalDependencies)
// TODO: this is not very efficient because KotlinSourceFilterScope already checks if the files are in scripts classpath
return KotlinSourceFilterScope.libraryClassFiles(
ScriptDependenciesManager.getInstance(project).getScriptDependenciesClassFilesScope(scriptFile), project
)
}
}
@@ -118,13 +113,4 @@ sealed class ScriptDependenciesSourceInfo(val project: Project) : IdeaModuleInfo
override fun equals(other: Any?): Boolean = other is ScriptDependenciesSourceInfo && this.project == other.project
class ForProject(project: Project) : ScriptDependenciesSourceInfo(project)
}
private class ScriptBinariesScopeCache(private val project: Project) : SLRUCache<ScriptDependencies, GlobalSearchScope>(MAX_SCRIPTS_CACHED, MAX_SCRIPTS_CACHED) {
override fun createValue(key: ScriptDependencies?): GlobalSearchScope {
val roots = key?.classpath ?: emptyList()
val classpath = ScriptDependenciesManager.toVfsRoots(roots)
// TODO: this is not very efficient because KotlinSourceFilterScope already checks if the files are in scripts classpath
return KotlinSourceFilterScope.libraryClassFiles(NonClasspathDirectoriesScope(classpath), project)
}
}
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.PsiManager
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.NonClasspathDirectoriesScope
import com.intellij.util.containers.SLRUMap
import kotlinx.coroutines.GlobalScope
@@ -52,6 +53,16 @@ class ScriptDependenciesCache(private val project: Project) {
return scriptsModificationStampsCache.replace(file, file.modificationStamp) != file.modificationStamp
}
private val scriptsDependenciesClasspathScopeCache = SLRUCacheWithLock<GlobalSearchScope>()
fun scriptDependenciesClasspathScope(file: VirtualFile): GlobalSearchScope {
return scriptsDependenciesClasspathScopeCache.getOrPut(file) {
val dependencies = scriptDependenciesCache.get(file)
val roots = dependencies?.classpath ?: emptyList()
NonClasspathDirectoriesScope.compose(ScriptDependenciesManager.toVfsRoots(roots))
}
}
val allScriptsClasspath by ClearableLazyValue(cacheLock) {
val files = scriptDependenciesCache.getAll().flatMap { it.value.classpath }.distinct()
ScriptDependenciesManager.toVfsRoots(files)
@@ -75,6 +86,8 @@ class ScriptDependenciesCache(private val project: Project) {
this::allLibrarySources.clearValue()
this::allLibrarySourcesScope.clearValue()
scriptsDependenciesClasspathScopeCache.clear()
val kotlinScriptDependenciesClassFinder =
Extensions.getArea(project).getExtensionPoint(PsiElementFinder.EP_NAME).extensions
.filterIsInstance<KotlinScriptDependenciesClassFinder>()
@@ -169,6 +182,17 @@ private class SLRUCacheWithLock<T> {
cache[value]
}
fun getOrPut(key: VirtualFile, defaultValue: () -> T): T = lock.write {
val value = cache.get(key)
return if (value == null) {
val answer = defaultValue()
replace(key, answer)
answer
} else {
value
}
}
fun remove(file: VirtualFile) = lock.write {
cache.remove(file)
}
@@ -52,6 +52,8 @@ class ScriptDependenciesManager internal constructor(
fun getScriptDependencies(file: VirtualFile): ScriptDependencies = cacheUpdater.getCurrentDependencies(file)
fun getScriptSdk(file: VirtualFile): Sdk? = getScriptSdk(getScriptDependencies(file))
fun getScriptDependenciesClassFilesScope(file: VirtualFile) = cache.scriptDependenciesClasspathScope(file)
fun getAllScriptsClasspathScope() = cache.allScriptsClasspathScope
fun getAllLibrarySourcesScope() = cache.allLibrarySourcesScope
fun getAllLibrarySources() = cache.allLibrarySources