KotlinScriptConfigurationManager: refactor roots caching and use NonClasspathDirectoriesScope
This commit is contained in:
+35
-43
@@ -29,8 +29,8 @@ import com.intellij.openapi.vfs.newvfs.BulkFileListener
|
|||||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
||||||
import com.intellij.psi.search.FileTypeIndex
|
import com.intellij.psi.search.FileTypeIndex
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.psi.search.NonClasspathDirectoriesScope
|
||||||
import com.intellij.util.io.URLUtil
|
import com.intellij.util.io.URLUtil
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.FileLibraryScope
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.script.*
|
import org.jetbrains.kotlin.script.*
|
||||||
@@ -70,10 +70,16 @@ class KotlinScriptConfigurationManager(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private var allScriptsClasspathCache: List<VirtualFile>? = null
|
|
||||||
private var allLibrarySourcesCache: List<VirtualFile>? = null
|
|
||||||
private val cacheLock = ReentrantReadWriteLock()
|
private val cacheLock = ReentrantReadWriteLock()
|
||||||
|
|
||||||
|
private val allScriptsClasspathCache = ClearableLazyValue(cacheLock) {
|
||||||
|
scriptExternalImportsProvider.getKnownCombinedClasspath().distinct().map { it.classpathEntryToVfs() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val allLibrarySourcesCache = ClearableLazyValue(cacheLock) {
|
||||||
|
scriptExternalImportsProvider.getKnownSourceRoots().distinct().mapNotNull { it.classpathEntryToVfs() }
|
||||||
|
}
|
||||||
|
|
||||||
private fun notifyRootsChanged() {
|
private fun notifyRootsChanged() {
|
||||||
ApplicationManager.getApplication().invokeLater {
|
ApplicationManager.getApplication().invokeLater {
|
||||||
runWriteAction { ProjectRootManagerEx.getInstanceEx(project)?.makeRootsChange(EmptyRunnable.getInstance(), false, true) }
|
runWriteAction { ProjectRootManagerEx.getInstanceEx(project)?.makeRootsChange(EmptyRunnable.getInstance(), false, true) }
|
||||||
@@ -85,31 +91,9 @@ class KotlinScriptConfigurationManager(
|
|||||||
.flatMap { it.classpath }
|
.flatMap { it.classpath }
|
||||||
.map { it.classpathEntryToVfs() }
|
.map { it.classpathEntryToVfs() }
|
||||||
|
|
||||||
fun getAllScriptsClasspath(): List<VirtualFile> = cacheLock.read {
|
fun getAllScriptsClasspath(): List<VirtualFile> = allScriptsClasspathCache.get()
|
||||||
if (allScriptsClasspathCache == null) {
|
|
||||||
cacheLock.write {
|
|
||||||
allScriptsClasspathCache =
|
|
||||||
scriptExternalImportsProvider.getKnownCombinedClasspath()
|
|
||||||
.distinct()
|
|
||||||
.mapNotNull { it.classpathEntryToVfs() }
|
|
||||||
}
|
|
||||||
notifyRootsChanged()
|
|
||||||
}
|
|
||||||
return allScriptsClasspathCache ?: emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getAllLibrarySources(): List<VirtualFile> = cacheLock.read {
|
fun getAllLibrarySources(): List<VirtualFile> = allLibrarySourcesCache.get()
|
||||||
if (allLibrarySourcesCache == null) {
|
|
||||||
cacheLock.write {
|
|
||||||
allLibrarySourcesCache =
|
|
||||||
scriptExternalImportsProvider.getKnownSourceRoots()
|
|
||||||
.distinct()
|
|
||||||
.mapNotNull { it.classpathEntryToVfs() }
|
|
||||||
}
|
|
||||||
notifyRootsChanged()
|
|
||||||
}
|
|
||||||
return allLibrarySourcesCache ?: emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun File.classpathEntryToVfs(): VirtualFile =
|
private fun File.classpathEntryToVfs(): VirtualFile =
|
||||||
if (isDirectory)
|
if (isDirectory)
|
||||||
@@ -117,19 +101,9 @@ class KotlinScriptConfigurationManager(
|
|||||||
else
|
else
|
||||||
StandardFileSystems.jar()?.findFileByPath(this.canonicalPath + URLUtil.JAR_SEPARATOR) ?: throw FileNotFoundException("Classpath entry points to a file that is not a JAR archive: ${this}")
|
StandardFileSystems.jar()?.findFileByPath(this.canonicalPath + URLUtil.JAR_SEPARATOR) ?: throw FileNotFoundException("Classpath entry points to a file that is not a JAR archive: ${this}")
|
||||||
|
|
||||||
fun getAllScriptsClasspathScope(): GlobalSearchScope {
|
fun getAllScriptsClasspathScope() = NonClasspathDirectoriesScope(getAllScriptsClasspath())
|
||||||
return getAllScriptsClasspath().let { cp ->
|
|
||||||
if (cp.isEmpty()) GlobalSearchScope.EMPTY_SCOPE
|
|
||||||
else GlobalSearchScope.union(cp.map { FileLibraryScope(project, it) }.toTypedArray())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getAllLibrarySourcesScope(): GlobalSearchScope {
|
fun getAllLibrarySourcesScope() = NonClasspathDirectoriesScope(getAllLibrarySources())
|
||||||
return getAllLibrarySources().let { cp ->
|
|
||||||
if (cp.isEmpty()) GlobalSearchScope.EMPTY_SCOPE
|
|
||||||
else GlobalSearchScope.union(cp.map { FileLibraryScope(project, it) }.toTypedArray())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun reloadScriptDefinitions() {
|
private fun reloadScriptDefinitions() {
|
||||||
(makeScriptDefsFromTemplateProviderExtensions(project, { ep, ex -> /* TODO: add logging here */ }) +
|
(makeScriptDefsFromTemplateProviderExtensions(project, { ep, ex -> /* TODO: add logging here */ }) +
|
||||||
@@ -159,10 +133,8 @@ class KotlinScriptConfigurationManager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun invalidateLocalCaches() {
|
private fun invalidateLocalCaches() {
|
||||||
cacheLock.write {
|
allScriptsClasspathCache.clear()
|
||||||
allScriptsClasspathCache = null
|
allLibrarySourcesCache.clear()
|
||||||
allLibrarySourcesCache = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -173,3 +145,23 @@ class KotlinScriptConfigurationManager(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ClearableLazyValue<out T : Any>(private val lock: ReentrantReadWriteLock, private val compute: () -> T) {
|
||||||
|
private var value: T? = null
|
||||||
|
|
||||||
|
fun get(): T {
|
||||||
|
lock.read {
|
||||||
|
if (value == null) {
|
||||||
|
lock.write {
|
||||||
|
value = compute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
lock.write {
|
||||||
|
value = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user