Abstract script compiled module implementation used in saving/caching

removes classloading problem when main-kts is loaded from a CL
without scripting compiler.
Also relax dependencies collection on saving to a jar and hide redundant
logging.
Running main.kts script via a run configuration works now.
#KT-37765 fixed
This commit is contained in:
Ilya Chernikov
2020-04-01 14:14:18 +02:00
parent 278f77713d
commit c64ba50655
6 changed files with 14 additions and 13 deletions
@@ -8,7 +8,7 @@ package kotlin.script.experimental.jvmhost.test
import junit.framework.TestCase import junit.framework.TestCase
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.CompiledScriptClassLoader import org.jetbrains.kotlin.scripting.compiler.plugin.impl.CompiledScriptClassLoader
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmCompiledModuleInMemory import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmCompiledModuleInMemoryImpl
import org.jetbrains.org.objectweb.asm.ClassReader import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.ClassVisitor import org.jetbrains.org.objectweb.asm.ClassVisitor
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
@@ -348,7 +348,7 @@ class ScriptingHostTest : TestCase() {
assertTrue(compiledScript is ResultWithDiagnostics.Success) assertTrue(compiledScript is ResultWithDiagnostics.Success)
val jvmCompiledScript = compiledScript.valueOrNull()!! as KJvmCompiledScript val jvmCompiledScript = compiledScript.valueOrNull()!! as KJvmCompiledScript
val jvmCompiledModule = jvmCompiledScript.compiledModule as KJvmCompiledModuleInMemory val jvmCompiledModule = jvmCompiledScript.compiledModule as KJvmCompiledModuleInMemoryImpl
val bytes = jvmCompiledModule.compilerOutputFiles["SavedScript.class"]!! val bytes = jvmCompiledModule.compilerOutputFiles["SavedScript.class"]!!
var classFileVersion: Int? = null var classFileVersion: Int? = null
@@ -5,7 +5,6 @@
package kotlin.script.experimental.jvmhost package kotlin.script.experimental.jvmhost
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmCompiledModuleInMemory
import org.jetbrains.kotlin.utils.KotlinPaths import org.jetbrains.kotlin.utils.KotlinPaths
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
@@ -14,11 +13,9 @@ import java.util.jar.JarOutputStream
import java.util.jar.Manifest import java.util.jar.Manifest
import kotlin.script.experimental.api.* import kotlin.script.experimental.api.*
import kotlin.script.experimental.jvm.JvmDependency import kotlin.script.experimental.jvm.JvmDependency
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript import kotlin.script.experimental.jvm.impl.*
import kotlin.script.experimental.jvm.impl.copyWithoutModule
import kotlin.script.experimental.jvm.impl.scriptMetadataPath
import kotlin.script.experimental.jvm.impl.toBytes
import kotlin.script.experimental.jvm.util.scriptCompilationClasspathFromContext import kotlin.script.experimental.jvm.util.scriptCompilationClasspathFromContext
import kotlin.script.experimental.jvm.util.scriptCompilationClasspathFromContextOrNull
// TODO: generate execution code (main) // TODO: generate execution code (main)
@@ -57,11 +54,11 @@ fun KJvmCompiledScript<*>.saveToJar(outputJar: File) {
?.filterIsInstance<JvmDependency>() ?.filterIsInstance<JvmDependency>()
?.flatMap { it.classpath } ?.flatMap { it.classpath }
.orEmpty() .orEmpty()
val dependenciesForMain = scriptCompilationClasspathFromContext( val dependenciesForMain = scriptCompilationClasspathFromContextOrNull(
KotlinPaths.Jar.ScriptingLib.baseName, KotlinPaths.Jar.ScriptingJvmLib.baseName, KotlinPaths.Jar.ScriptingLib.baseName, KotlinPaths.Jar.ScriptingJvmLib.baseName,
classLoader = this::class.java.classLoader, classLoader = this::class.java.classLoader,
wholeClasspath = false wholeClasspath = false
) ) ?: emptyList()
val dependencies = (dependenciesFromScript + dependenciesForMain).distinct() val dependencies = (dependenciesFromScript + dependenciesForMain).distinct()
FileOutputStream(outputJar).use { fileStream -> FileOutputStream(outputJar).use { fileStream ->
val manifest = Manifest() val manifest = Manifest()
@@ -15,6 +15,10 @@ interface KJvmCompiledModule {
fun createClassLoader(baseClassLoader: ClassLoader?): ClassLoader fun createClassLoader(baseClassLoader: ClassLoader?): ClassLoader
} }
interface KJvmCompiledModuleInMemory : KJvmCompiledModule {
val compilerOutputFiles: Map<String, ByteArray>
}
class KJvmCompiledModuleFromClassPath(val classpath: Collection<File>) : KJvmCompiledModule { class KJvmCompiledModuleFromClassPath(val classpath: Collection<File>) : KJvmCompiledModule {
override fun createClassLoader(baseClassLoader: ClassLoader?): ClassLoader = override fun createClassLoader(baseClassLoader: ClassLoader?): ClassLoader =
@@ -341,7 +341,7 @@ private fun loadScriptDefinition(
ScriptDefinition.FromLegacyTemplate(hostConfiguration, cls.kotlin) ScriptDefinition.FromLegacyTemplate(hostConfiguration, cls.kotlin)
} }
messageReporter( messageReporter(
ScriptDiagnostic.Severity.INFO, ScriptDiagnostic.Severity.DEBUG,
"Added script definition $template to configuration: name = ${def.name}" "Added script definition $template to configuration: name = ${def.name}"
) )
return def return def
@@ -6,9 +6,9 @@
package org.jetbrains.kotlin.scripting.compiler.plugin.impl package org.jetbrains.kotlin.scripting.compiler.plugin.impl
import java.io.Serializable import java.io.Serializable
import kotlin.script.experimental.jvm.impl.KJvmCompiledModule import kotlin.script.experimental.jvm.impl.KJvmCompiledModuleInMemory
class KJvmCompiledModuleInMemory(val compilerOutputFiles: Map<String, ByteArray>) : KJvmCompiledModule, class KJvmCompiledModuleInMemoryImpl(override val compilerOutputFiles: Map<String, ByteArray>) : KJvmCompiledModuleInMemory,
Serializable { Serializable {
override fun createClassLoader(baseClassLoader: ClassLoader?): ClassLoader = override fun createClassLoader(baseClassLoader: ClassLoader?): ClassLoader =
@@ -28,7 +28,7 @@ import kotlin.script.experimental.host.getMergedScriptText
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
internal fun makeCompiledModule(generationState: GenerationState) = internal fun makeCompiledModule(generationState: GenerationState) =
KJvmCompiledModuleInMemory( KJvmCompiledModuleInMemoryImpl(
generationState.factory.asList() generationState.factory.asList()
.associateTo(sortedMapOf<String, ByteArray>()) { it.relativePath to it.asByteArray() } .associateTo(sortedMapOf<String, ByteArray>()) { it.relativePath to it.asByteArray() }
) )