Implement API to get source roots of script dependencies in KotlinScriptConfigurationManager and KotlinScriptConfigurationManager
This commit is contained in:
+4
@@ -126,6 +126,10 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri
|
|||||||
cache.values.flatMap { it.classpath }
|
cache.values.flatMap { it.classpath }
|
||||||
}.distinct()
|
}.distinct()
|
||||||
|
|
||||||
|
fun getKnownSourceRoots(): List<File> = cacheLock.read {
|
||||||
|
cache.values.flatMap { it.sources }
|
||||||
|
}.distinct()
|
||||||
|
|
||||||
fun <TF> getCombinedClasspathFor(files: Iterable<TF>): List<File> =
|
fun <TF> getCombinedClasspathFor(files: Iterable<TF>): List<File> =
|
||||||
getExternalImports(files)
|
getExternalImports(files)
|
||||||
.flatMap { it.classpath }
|
.flatMap { it.classpath }
|
||||||
|
|||||||
+27
-3
@@ -58,11 +58,12 @@ class KotlinScriptConfigurationManager(
|
|||||||
|
|
||||||
project.messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() {
|
project.messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() {
|
||||||
override fun after(events: List<VFileEvent>) {
|
override fun after(events: List<VFileEvent>) {
|
||||||
val isChanged = scriptExternalImportsProvider?.updateExternalImportsCache( events.mapNotNull { it.file })?.any() ?: false
|
val isChanged = scriptExternalImportsProvider?.updateExternalImportsCache(events.mapNotNull { it.file })?.any() ?: false
|
||||||
if (isChanged) {
|
if (isChanged) {
|
||||||
// TODO: consider more fine-grained update
|
// TODO: consider more fine-grained update
|
||||||
cacheLock.write {
|
cacheLock.write {
|
||||||
allScriptsClasspathCache = null
|
allScriptsClasspathCache = null
|
||||||
|
allLibrarySourcesCache = null
|
||||||
}
|
}
|
||||||
notifyRootsChanged()
|
notifyRootsChanged()
|
||||||
}
|
}
|
||||||
@@ -71,6 +72,7 @@ class KotlinScriptConfigurationManager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var allScriptsClasspathCache: List<VirtualFile>? = null
|
private var allScriptsClasspathCache: List<VirtualFile>? = null
|
||||||
|
private var allLibrarySourcesCache: List<VirtualFile>? = null
|
||||||
private val cacheLock = ReentrantReadWriteLock()
|
private val cacheLock = ReentrantReadWriteLock()
|
||||||
|
|
||||||
private fun notifyRootsChanged() {
|
private fun notifyRootsChanged() {
|
||||||
@@ -99,15 +101,37 @@ class KotlinScriptConfigurationManager(
|
|||||||
return allScriptsClasspathCache ?: emptyList()
|
return allScriptsClasspathCache ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getAllLibrarySources(): List<VirtualFile> = cacheLock.read {
|
||||||
|
if (allLibrarySourcesCache == null) {
|
||||||
|
dumbService.runWhenSmart {
|
||||||
|
cacheLock.write {
|
||||||
|
allLibrarySourcesCache =
|
||||||
|
(scriptExternalImportsProvider?.getKnownSourceRoots() ?: emptyList())
|
||||||
|
.distinct()
|
||||||
|
.mapNotNull { it.classpathEntryToVfs() }
|
||||||
|
}
|
||||||
|
notifyRootsChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allLibrarySourcesCache ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
private fun File.classpathEntryToVfs(): VirtualFile =
|
private fun File.classpathEntryToVfs(): VirtualFile =
|
||||||
if (isDirectory)
|
if (isDirectory)
|
||||||
StandardFileSystems.local()?.findFileByPath(this.canonicalPath) ?: throw FileNotFoundException("Classpath entry points to a non-existent location: ${this}")
|
StandardFileSystems.local()?.findFileByPath(this.canonicalPath) ?: throw FileNotFoundException("Classpath entry points to a non-existent location: ${this}")
|
||||||
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(): GlobalSearchScope {
|
||||||
return getAllScriptsClasspath().let { cp ->
|
return getAllScriptsClasspath().let { cp ->
|
||||||
if (cp.isEmpty()) null
|
if (cp.isEmpty()) GlobalSearchScope.EMPTY_SCOPE
|
||||||
|
else GlobalSearchScope.union(cp.map { FileLibraryScope(project, it) }.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAllLibrarySourcesScope(): GlobalSearchScope {
|
||||||
|
return getAllLibrarySources().let { cp ->
|
||||||
|
if (cp.isEmpty()) GlobalSearchScope.EMPTY_SCOPE
|
||||||
else GlobalSearchScope.union(cp.map { FileLibraryScope(project, it) }.toTypedArray())
|
else GlobalSearchScope.union(cp.map { FileLibraryScope(project, it) }.toTypedArray())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user