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 com.intellij.openapi.util.Disposer
|
||||||
import org.jetbrains.kotlin.cli.common.repl.KotlinJsr223JvmScriptEngineFactoryBase
|
import org.jetbrains.kotlin.cli.common.repl.KotlinJsr223JvmScriptEngineFactoryBase
|
||||||
import org.jetbrains.kotlin.utils.PathUtil
|
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.ScriptContext
|
||||||
import javax.script.ScriptEngine
|
import javax.script.ScriptEngine
|
||||||
|
|
||||||
@@ -29,9 +35,64 @@ class KotlinJsr223StandardScriptEngineFactory4Idea : KotlinJsr223JvmScriptEngine
|
|||||||
KotlinJsr223JvmScriptEngine4Idea(
|
KotlinJsr223JvmScriptEngine4Idea(
|
||||||
Disposer.newDisposable(),
|
Disposer.newDisposable(),
|
||||||
this,
|
this,
|
||||||
listOf(PathUtil.getKotlinPathsForIdeaPlugin().runtimePath, PathUtil.getKotlinPathsForIdeaPlugin().scriptRuntimePath),
|
scriptCompilationClasspathFromContext(Thread.currentThread().contextClassLoader),
|
||||||
"kotlin.script.templates.standard.ScriptTemplateWithBindings",
|
"kotlin.script.templates.standard.ScriptTemplateWithBindings",
|
||||||
{ ctx -> arrayOf(ctx.getBindings(ScriptContext.ENGINE_SCOPE)) },
|
{ ctx -> arrayOf(ctx.getBindings(ScriptContext.ENGINE_SCOPE)) },
|
||||||
arrayOf(Map::class.java)
|
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 {
|
private val kotlinCompilerJar: File by lazy {
|
||||||
// highest prio - explicit property
|
// highest prio - explicit property
|
||||||
System.getProperty("kotlin.compiler.jar")?.let(::File)?.existsOrNull()
|
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)
|
?: (classpathFromClass(Thread.currentThread().contextClassLoader, K2JVMCompiler::class)
|
||||||
?: contextClasspath(KOTLIN_COMPILER_JAR, Thread.currentThread().contextClassLoader)
|
?: contextClasspath(KOTLIN_COMPILER_JAR, Thread.currentThread().contextClassLoader)
|
||||||
?: classpathFromClasspathProperty()
|
?: classpathFromClasspathProperty()
|
||||||
|
|||||||
-3
@@ -1,7 +1,5 @@
|
|||||||
package org.jetbrains.kotlin.script.util
|
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.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
@@ -9,7 +7,6 @@ import java.net.URLClassLoader
|
|||||||
import java.util.jar.Manifest
|
import java.util.jar.Manifest
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
|
||||||
private fun URL.toFile() =
|
private fun URL.toFile() =
|
||||||
try {
|
try {
|
||||||
File(toURI().schemeSpecificPart)
|
File(toURI().schemeSpecificPart)
|
||||||
|
|||||||
Reference in New Issue
Block a user