Fix evaluation part of the scripting API - mostly renaming

This commit is contained in:
Ilya Chernikov
2018-08-31 13:36:56 +02:00
parent 539e0f4961
commit 1e85a26b62
4 changed files with 37 additions and 36 deletions
@@ -130,5 +130,5 @@ interface CompiledScript<out ScriptBase : Any> {
val compilationConfiguration: ScriptCompilationConfiguration val compilationConfiguration: ScriptCompilationConfiguration
suspend fun instantiate(scriptEvaluationConfiguration: ScriptEvaluationConfiguration?): ResultWithDiagnostics<ScriptBase> suspend fun getClass(scriptEvaluationConfiguration: ScriptEvaluationConfiguration?): ResultWithDiagnostics<KClass<*>>
} }
@@ -20,7 +20,7 @@ class ScriptEvaluationConfiguration(baseEvaluationEnvironments: Iterable<ScriptE
) : this(baseConfigurations.asIterable(), body) ) : this(baseConfigurations.asIterable(), body)
class Builder internal constructor(baseEvaluationEnvironments: Iterable<ScriptEvaluationConfiguration>) : class Builder internal constructor(baseEvaluationEnvironments: Iterable<ScriptEvaluationConfiguration>) :
ScriptCompilationConfigurationKeys, ScriptEvaluationConfigurationKeys,
PropertiesCollection.Builder(baseEvaluationEnvironments) PropertiesCollection.Builder(baseEvaluationEnvironments)
companion object : ScriptEvaluationConfigurationKeys companion object : ScriptEvaluationConfigurationKeys
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.script.util.KotlinJars import org.jetbrains.kotlin.script.util.KotlinJars
import java.io.File import java.io.File
import java.net.URLClassLoader import java.net.URLClassLoader
import kotlin.reflect.KClass
import kotlin.script.experimental.api.* import kotlin.script.experimental.api.*
import kotlin.script.experimental.dependencies.DependenciesResolver import kotlin.script.experimental.dependencies.DependenciesResolver
import kotlin.script.experimental.host.ScriptingHostConfiguration import kotlin.script.experimental.host.ScriptingHostConfiguration
@@ -56,24 +57,22 @@ class KJvmCompiledScript<out ScriptBase : Any>(
private val scriptClassFQName: String private val scriptClassFQName: String
) : CompiledScript<ScriptBase> { ) : CompiledScript<ScriptBase> {
override suspend fun instantiate(scriptEvaluationConfiguration: ScriptEvaluationConfiguration?): ResultWithDiagnostics<ScriptBase> = override suspend fun getClass(scriptEvaluationConfiguration: ScriptEvaluationConfiguration?): ResultWithDiagnostics<KClass<*>> = try {
try { val baseClassLoader = scriptEvaluationConfiguration?.get(JvmScriptEvaluationEnvironment.baseClassLoader)
val baseClassLoader = scriptEvaluationConfiguration?.get(JvmScriptEvaluationEnvironment.baseClassLoader) ?: Thread.currentThread().contextClassLoader
?: Thread.currentThread().contextClassLoader val dependencies = compilationConfiguration[ScriptCompilationConfiguration.dependencies]
val dependencies = compilationConfiguration[ScriptCompilationConfiguration.dependencies] ?.flatMap { (it as? JvmDependency)?.classpath?.map { it.toURI().toURL() } ?: emptyList() }
?.flatMap { (it as? JvmDependency)?.classpath?.map { it.toURI().toURL() } ?: emptyList() } // TODO: previous dependencies and classloaders should be taken into account here
// TODO: previous dependencies and classloaders should be taken into account here val classLoaderWithDeps =
val classLoaderWithDeps = if (dependencies == null) baseClassLoader
if (dependencies == null) baseClassLoader else URLClassLoader(dependencies.toTypedArray(), baseClassLoader)
else URLClassLoader(dependencies.toTypedArray(), baseClassLoader) val classLoader = GeneratedClassLoader(generationState.factory, classLoaderWithDeps)
val classLoader = GeneratedClassLoader(generationState.factory, classLoaderWithDeps)
val clazz = classLoader.loadClass(scriptClassFQName) val clazz = classLoader.loadClass(scriptClassFQName).kotlin
(clazz as? ScriptBase)?.asSuccess() clazz.asSuccess()
?: ResultWithDiagnostics.Failure("Compiled class expected to be a subclass of the <ScriptBase>, but got ${clazz.javaClass.name}".asErrorDiagnostics()) } catch (e: Throwable) {
} catch (e: Throwable) { ResultWithDiagnostics.Failure(ScriptDiagnostic("Unable to instantiate class $scriptClassFQName", exception = e))
ResultWithDiagnostics.Failure(ScriptDiagnostic("Unable to instantiate class $scriptClassFQName", exception = e)) }
}
} }
class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvmCompilerProxy { class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvmCompilerProxy {
@@ -26,30 +26,32 @@ open class BasicJvmScriptEvaluator : ScriptEvaluator {
scriptEvaluationConfiguration: ScriptEvaluationConfiguration? scriptEvaluationConfiguration: ScriptEvaluationConfiguration?
): ResultWithDiagnostics<EvaluationResult> = ): ResultWithDiagnostics<EvaluationResult> =
try { try {
val obj = compiledScript.instantiate(scriptEvaluationConfiguration) val res = compiledScript.getClass(scriptEvaluationConfiguration)
when (obj) { when (res) {
is ResultWithDiagnostics.Failure -> obj is ResultWithDiagnostics.Failure -> res
is ResultWithDiagnostics.Success -> { is ResultWithDiagnostics.Success -> {
// in the future, when (if) we'll stop to compile everything into constructor // in the future, when (if) we'll stop to compile everything into constructor
// run as SAM // run as SAM
// return res // return res
val scriptObject = obj.value val scriptClass = res.value
if (scriptObject !is Class<*>) val args = ArrayList<Any?>()
ResultWithDiagnostics.Failure(ScriptDiagnostic("expecting class in this implementation, got ${scriptObject?.javaClass}")) scriptEvaluationConfiguration?.get(ScriptEvaluationConfiguration.contextVariables)?.forEach {
else { args.add(it.value)
val receivers = scriptEvaluationConfiguration?.get(ScriptEvaluationConfiguration.implicitReceivers)
val instance = if (receivers == null) {
scriptObject.getConstructor().newInstance()
} else {
scriptObject.getConstructor(Array<Any>::class.java).newInstance(receivers.toTypedArray())
}
// TODO: fix result value
ResultWithDiagnostics.Success(EvaluationResult(ResultValue.Value("", instance, ""), scriptEvaluationConfiguration))
} }
scriptEvaluationConfiguration?.get(ScriptEvaluationConfiguration.implicitReceivers)?.let {
args.addAll(it)
}
scriptEvaluationConfiguration?.get(ScriptEvaluationConfiguration.constructorArgs)?.let {
args.addAll(it)
}
val ctor = scriptClass.java.constructors.first()
val instance = ctor.newInstance(*args.toArray())
// TODO: fix result value
ResultWithDiagnostics.Success(EvaluationResult(ResultValue.Value("", instance, ""), scriptEvaluationConfiguration))
} }
} }
} catch (e: Throwable) { } catch (e: Throwable) {
ResultWithDiagnostics.Failure(e.asDiagnostics()) ResultWithDiagnostics.Failure(e.asDiagnostics("Error evaluating script"))
} }
} }