minor: Make script dependencies classpath processing more robust

This commit is contained in:
Ilya Chernikov
2016-07-12 09:39:29 +02:00
parent 9fd78ac1ff
commit ee2c5c1b73
@@ -36,11 +36,11 @@ import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.script.* import org.jetbrains.kotlin.script.*
import org.jetbrains.kotlin.utils.PathUtil import org.jetbrains.kotlin.utils.PathUtil
import java.io.File import java.io.File
import java.io.FileNotFoundException
import java.util.concurrent.locks.ReentrantReadWriteLock import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.read import kotlin.concurrent.read
import kotlin.concurrent.write import kotlin.concurrent.write
@Suppress("SimplifyAssertNotNull")
class KotlinScriptConfigurationManager( class KotlinScriptConfigurationManager(
private val project: Project, private val project: Project,
private val scriptDefinitionProvider: KotlinScriptDefinitionProvider, private val scriptDefinitionProvider: KotlinScriptDefinitionProvider,
@@ -73,7 +73,7 @@ class KotlinScriptConfigurationManager(
private val cacheLock = ReentrantReadWriteLock() private val cacheLock = ReentrantReadWriteLock()
private val allScriptsClasspathCache = ClearableLazyValue(cacheLock) { private val allScriptsClasspathCache = ClearableLazyValue(cacheLock) {
scriptExternalImportsProvider.getKnownCombinedClasspath().distinct().map { it.classpathEntryToVfs() } scriptExternalImportsProvider.getKnownCombinedClasspath().distinct().mapNotNull { it.classpathEntryToVfs() }
} }
private val allLibrarySourcesCache = ClearableLazyValue(cacheLock) { private val allLibrarySourcesCache = ClearableLazyValue(cacheLock) {
@@ -89,17 +89,22 @@ class KotlinScriptConfigurationManager(
fun getScriptClasspath(file: VirtualFile): List<VirtualFile> = fun getScriptClasspath(file: VirtualFile): List<VirtualFile> =
scriptExternalImportsProvider.getExternalImports(file) scriptExternalImportsProvider.getExternalImports(file)
.flatMap { it.classpath } .flatMap { it.classpath }
.map { it.classpathEntryToVfs() } .mapNotNull { it.classpathEntryToVfs() }
fun getAllScriptsClasspath(): List<VirtualFile> = allScriptsClasspathCache.get() fun getAllScriptsClasspath(): List<VirtualFile> = allScriptsClasspathCache.get()
fun getAllLibrarySources(): List<VirtualFile> = allLibrarySourcesCache.get() fun getAllLibrarySources(): List<VirtualFile> = allLibrarySourcesCache.get()
private fun File.classpathEntryToVfs(): VirtualFile = private fun File.classpathEntryToVfs(): VirtualFile? {
if (isDirectory) val res = when {
StandardFileSystems.local()?.findFileByPath(this.canonicalPath) ?: throw FileNotFoundException("Classpath entry points to a non-existent location: ${this}") !exists() -> null
else isDirectory -> StandardFileSystems.local()?.findFileByPath(this.canonicalPath) ?: null
StandardFileSystems.jar()?.findFileByPath(this.canonicalPath + URLUtil.JAR_SEPARATOR) ?: throw FileNotFoundException("Classpath entry points to a file that is not a JAR archive: ${this}") isFile -> StandardFileSystems.jar()?.findFileByPath(this.canonicalPath + URLUtil.JAR_SEPARATOR) ?: null
else -> null
}
// TODO: report this somewhere, but do not throw: assert(res != null, { "Invalid classpath entry '$this': exists: ${exists()}, is directory: $isDirectory, is file: $isFile" })
return res
}
fun getAllScriptsClasspathScope() = NonClasspathDirectoriesScope(getAllScriptsClasspath()) fun getAllScriptsClasspathScope() = NonClasspathDirectoriesScope(getAllScriptsClasspath())