Copy (partly) context classpath extraction code from script-util to JSR223 4 Idea, use it there
This commit is contained in:
+62
-1
@@ -19,6 +19,12 @@ package org.jetbrains.kotlin.jsr223
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import org.jetbrains.kotlin.cli.common.repl.KotlinJsr223JvmScriptEngineFactoryBase
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_JAVA_RUNTIME_JAR
|
||||
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_JAVA_SCRIPT_RUNTIME_JAR
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.net.URL
|
||||
import java.net.URLClassLoader
|
||||
import javax.script.ScriptContext
|
||||
import javax.script.ScriptEngine
|
||||
|
||||
@@ -29,9 +35,64 @@ class KotlinJsr223StandardScriptEngineFactory4Idea : KotlinJsr223JvmScriptEngine
|
||||
KotlinJsr223JvmScriptEngine4Idea(
|
||||
Disposer.newDisposable(),
|
||||
this,
|
||||
listOf(PathUtil.getKotlinPathsForIdeaPlugin().runtimePath, PathUtil.getKotlinPathsForIdeaPlugin().scriptRuntimePath),
|
||||
scriptCompilationClasspathFromContext(Thread.currentThread().contextClassLoader),
|
||||
"kotlin.script.templates.standard.ScriptTemplateWithBindings",
|
||||
{ ctx -> arrayOf(ctx.getBindings(ScriptContext.ENGINE_SCOPE)) },
|
||||
arrayOf(Map::class.java)
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: some common parts with the code from script-utils, consider placing in a shared lib
|
||||
|
||||
private fun URL.toFile() =
|
||||
try {
|
||||
File(toURI().schemeSpecificPart)
|
||||
}
|
||||
catch (e: java.net.URISyntaxException) {
|
||||
if (protocol != "file") null
|
||||
else File(file)
|
||||
}
|
||||
|
||||
fun classpathFromClassloader(classLoader: ClassLoader): List<File>? =
|
||||
generateSequence(classLoader) { it.parent }.toList().flatMap { (it as? URLClassLoader)?.urLs?.mapNotNull(URL::toFile) ?: emptyList() }
|
||||
|
||||
private fun File.existsOrNull(): File? = existsAndCheckOrNull { true }
|
||||
private inline fun File.existsAndCheckOrNull(check: (File.() -> Boolean)): File? = if (exists() && check()) this else null
|
||||
|
||||
private val kotlinCompilerJar: File by lazy {
|
||||
// highest prio - explicit property
|
||||
System.getProperty("kotlin.compiler.jar")?.let(::File)?.existsOrNull()
|
||||
?: PathUtil.getKotlinPathsForIdeaPlugin().compilerPath
|
||||
?: throw FileNotFoundException("Cannot find kotlin compiler jar, set kotlin.compiler.jar property to proper location")
|
||||
}
|
||||
private fun <T> Iterable<T>.anyOrNull(predicate: (T) -> Boolean) = if (any(predicate)) this else null
|
||||
|
||||
private fun File.matchMaybeVersionedFile(baseName: String) =
|
||||
name == baseName ||
|
||||
name == baseName.removeSuffix(".jar") || // for classes dirs
|
||||
name.startsWith(baseName.removeSuffix(".jar") + "-")
|
||||
|
||||
private fun contextClasspath(keyName: String, classLoader: ClassLoader): List<File>? =
|
||||
( classpathFromClassloader(classLoader)?.anyOrNull { it.matchMaybeVersionedFile(keyName) }
|
||||
)?.toList()
|
||||
|
||||
|
||||
private fun scriptCompilationClasspathFromContext(classLoader: ClassLoader): List<File> =
|
||||
( System.getProperty("kotlin.script.classpath")?.split(File.pathSeparator)?.map(::File)
|
||||
?: contextClasspath(KOTLIN_JAVA_RUNTIME_JAR, classLoader)
|
||||
?: listOf(kotlinRuntimeJar, kotlinScriptRuntimeJar)
|
||||
)
|
||||
.map { it?.canonicalFile }
|
||||
.distinct()
|
||||
.mapNotNull { it?.existsOrNull() }
|
||||
|
||||
|
||||
private val kotlinRuntimeJar: File? by lazy {
|
||||
System.getProperty("kotlin.java.runtime.jar")?.let(::File)?.existsOrNull()
|
||||
?: kotlinCompilerJar.let { File(it.parentFile, KOTLIN_JAVA_RUNTIME_JAR) }.existsOrNull()
|
||||
}
|
||||
|
||||
private val kotlinScriptRuntimeJar: File? by lazy {
|
||||
System.getProperty("kotlin.script.runtime.jar")?.let(::File)?.existsOrNull()
|
||||
?: kotlinCompilerJar.let { File(it.parentFile, KOTLIN_JAVA_SCRIPT_RUNTIME_JAR) }.existsOrNull()
|
||||
}
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ private inline fun File.existsAndCheckOrNull(check: (File.() -> Boolean)): File?
|
||||
private val kotlinCompilerJar: File by lazy {
|
||||
// highest prio - explicit property
|
||||
System.getProperty("kotlin.compiler.jar")?.let(::File)?.existsOrNull()
|
||||
// search classpath from context classloader and `java.calss.path` property
|
||||
// search classpath from context classloader and `java.class.path` property
|
||||
?: (classpathFromClass(Thread.currentThread().contextClassLoader, K2JVMCompiler::class)
|
||||
?: contextClasspath(KOTLIN_COMPILER_JAR, Thread.currentThread().contextClassLoader)
|
||||
?: classpathFromClasspathProperty()
|
||||
|
||||
-3
@@ -1,7 +1,5 @@
|
||||
package org.jetbrains.kotlin.script.util
|
||||
|
||||
import org.jetbrains.kotlin.script.util.resolvers.DirectResolver
|
||||
import org.jetbrains.kotlin.script.util.resolvers.MavenResolver
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.net.URL
|
||||
@@ -9,7 +7,6 @@ import java.net.URLClassLoader
|
||||
import java.util.jar.Manifest
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
private fun URL.toFile() =
|
||||
try {
|
||||
File(toURI().schemeSpecificPart)
|
||||
|
||||
Reference in New Issue
Block a user