Making kts-compiler able to dig out the ClassPath from the intellij PluginClassLoader

This commit is contained in:
Nicolay Mitropolsky
2019-02-21 14:14:00 +03:00
parent ec7315e6da
commit 9bf55d81ca
@@ -43,7 +43,7 @@ internal const val KOTLIN_SCRIPT_RUNTIME_JAR_PROPERTY = "kotlin.script.runtime.j
private val validClasspathFilesExtensions = setOf("jar", "zip", "java")
fun classpathFromClassloader(classLoader: ClassLoader): List<File>? =
generateSequence(classLoader) { it.parent }.toList().flatMap {
allRelatedClassLoaders(classLoader).toList().flatMap {
val urls = (it as? URLClassLoader)?.urLs?.asList()
?: try {
// e.g. for IDEA platform UrlClassLoader
@@ -89,6 +89,24 @@ fun File.hasParentNamed(baseName: String): Boolean =
private const val KOTLIN_COMPILER_EMBEDDABLE_JAR = "$KOTLIN_COMPILER_NAME-embeddable.jar"
private fun allRelatedClassLoaders(clsLoader: ClassLoader, visited: MutableSet<ClassLoader> = HashSet()): Sequence<ClassLoader> {
if (!visited.add(clsLoader)) return emptySequence()
val singleParent = clsLoader.parent
if (singleParent != null)
return sequenceOf(clsLoader) + sequenceOf(singleParent).flatMap { allRelatedClassLoaders(it, visited) }
return try {
val field = clsLoader.javaClass.getDeclaredField("myParents") // com.intellij.ide.plugins.cl.PluginClassLoader
field.isAccessible = true
val arrayOfClassLoaders = field.get(clsLoader) as Array<ClassLoader>
sequenceOf(clsLoader) + arrayOfClassLoaders.asSequence().flatMap { allRelatedClassLoaders(it, visited) }
} catch (e: Throwable) {
sequenceOf(clsLoader)
}
}
internal fun List<File>.takeIfContainsAll(vararg keyNames: String): List<File>? =
takeIf { classpath ->
keyNames.all { key -> classpath.any { it.matchMaybeVersionedFile(key) } }