From 1da3efea8144364754497e244cbc08aedc11baa3 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Thu, 16 Jun 2016 18:51:19 +0300 Subject: [PATCH] Implement API to get source roots of script dependencies in KotlinScriptConfigurationManager and KotlinScriptConfigurationManager --- .../KotlinScriptExternalImportsProvider.kt | 4 +++ .../KotlinScriptConfigurationManager.kt | 30 +++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptExternalImportsProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptExternalImportsProvider.kt index 80b7606e6f6..b3999d3e193 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptExternalImportsProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptExternalImportsProvider.kt @@ -126,6 +126,10 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri cache.values.flatMap { it.classpath } }.distinct() + fun getKnownSourceRoots(): List = cacheLock.read { + cache.values.flatMap { it.sources } + }.distinct() + fun getCombinedClasspathFor(files: Iterable): List = getExternalImports(files) .flatMap { it.classpath } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptConfigurationManager.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptConfigurationManager.kt index 9e02f20e4f4..8501df0ddc3 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptConfigurationManager.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptConfigurationManager.kt @@ -58,11 +58,12 @@ class KotlinScriptConfigurationManager( project.messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() { override fun after(events: List) { - val isChanged = scriptExternalImportsProvider?.updateExternalImportsCache( events.mapNotNull { it.file })?.any() ?: false + val isChanged = scriptExternalImportsProvider?.updateExternalImportsCache(events.mapNotNull { it.file })?.any() ?: false if (isChanged) { // TODO: consider more fine-grained update cacheLock.write { allScriptsClasspathCache = null + allLibrarySourcesCache = null } notifyRootsChanged() } @@ -71,6 +72,7 @@ class KotlinScriptConfigurationManager( } private var allScriptsClasspathCache: List? = null + private var allLibrarySourcesCache: List? = null private val cacheLock = ReentrantReadWriteLock() private fun notifyRootsChanged() { @@ -99,15 +101,37 @@ class KotlinScriptConfigurationManager( return allScriptsClasspathCache ?: emptyList() } + fun getAllLibrarySources(): List = 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 = if (isDirectory) StandardFileSystems.local()?.findFileByPath(this.canonicalPath) ?: throw FileNotFoundException("Classpath entry points to a non-existent location: ${this}") else 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 -> - 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()) } }