Add new REPL API JVM implementation

This commit is contained in:
Ilya Muradyan
2020-02-28 19:45:20 +03:00
committed by Ilya Chernikov
parent 4c2c44b106
commit d2fec96f38
51 changed files with 2557 additions and 503 deletions
@@ -24,16 +24,13 @@ import kotlin.concurrent.write
data class LineId(override val no: Int, override val generation: Int, private val codeHash: Int) : ILineId, Serializable {
constructor(codeLine: ReplCodeLine): this(codeLine.no, codeLine.generation, codeLine.code.hashCode())
override fun compareTo(other: ILineId): Int = (other as? LineId)?.let {
no.compareTo(it.no).takeIf { it != 0 }
?: generation.compareTo(it.generation).takeIf { it != 0 }
?: codeHash.compareTo(it.codeHash)
override fun compareTo(other: ILineId): Int = (other as? LineId)?.let { lineId ->
no.compareTo(lineId.no).takeIf { no -> no != 0 }
?: codeHash.compareTo(lineId.codeHash)
} ?: -1 // TODO: check if it doesn't break something
companion object {
private val serialVersionUID: Long = 8328353000L
private const val serialVersionUID: Long = 8328354000L
}
}
@@ -21,7 +21,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.write
open class GenericReplCompilingEvaluatorBase(
val compiler: ReplCompiler,
val compiler: ReplCompilerWithoutCheck,
val evaluator: ReplEvaluator,
private val fallbackScriptArgs: ScriptArgsWithTypes? = null
) : ReplFullEvaluator {
@@ -46,7 +46,7 @@ open class GenericReplCompilingEvaluatorBase(
}
ReplEvalResult.Error.CompileTime(compiled.message, compiled.location)
}
is ReplCompileResult.Incomplete -> ReplEvalResult.Incomplete()
is ReplCompileResult.Incomplete -> ReplEvalResult.Incomplete(compiled.message)
is ReplCompileResult.CompiledClasses -> {
val result = eval(state, compiled, scriptArgs, invokeWrapper)
when (result) {
@@ -75,8 +75,6 @@ open class GenericReplCompilingEvaluatorBase(
override fun eval(state: IReplStageState<*>, compileResult: ReplCompileResult.CompiledClasses, scriptArgs: ScriptArgsWithTypes?, invokeWrapper: InvokeWrapper?): ReplEvalResult =
evaluator.eval(state, compileResult, scriptArgs, invokeWrapper)
override fun check(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCheckResult = compiler.check(state, codeLine)
override fun compileToEvaluable(state: IReplStageState<*>, codeLine: ReplCodeLine, defaultScriptArgs: ScriptArgsWithTypes?): Pair<ReplCompileResult, Evaluable?> {
val compiled = compiler.compile(state, codeLine)
return when (compiled) {
@@ -96,7 +94,7 @@ open class GenericReplCompilingEvaluatorBase(
}
class GenericReplCompilingEvaluator(
compiler: ReplCompiler,
compiler: ReplCompilerWithoutCheck,
baseClasspath: Iterable<File>,
baseClassloader: ClassLoader? = Thread.currentThread().contextClassLoader,
fallbackScriptArgs: ScriptArgsWithTypes? = null,
@@ -25,7 +25,7 @@ const val KOTLIN_SCRIPT_ENGINE_BINDINGS_KEY = "kotlin.script.engine"
abstract class KotlinJsr223JvmScriptEngineBase(protected val myFactory: ScriptEngineFactory) : AbstractScriptEngine(), ScriptEngine, Compilable {
protected abstract val replCompiler: ReplCompiler
protected abstract val replCompiler: ReplCompilerWithoutCheck
protected abstract val replEvaluator: ReplFullEvaluator
override fun eval(script: String, context: ScriptContext): Any? = compileAndEval(script, context)
@@ -72,7 +72,7 @@ abstract class KotlinJsr223JvmScriptEngineBase(protected val myFactory: ScriptEn
val result = replCompiler.compile(state, codeLine)
val compiled = when (result) {
is ReplCompileResult.Error -> throw ScriptException("Error${result.locationString()}: ${result.message}")
is ReplCompileResult.Incomplete -> throw ScriptException("error: incomplete code")
is ReplCompileResult.Incomplete -> throw ScriptException("Error: incomplete code; ${result.message}")
is ReplCompileResult.CompiledClasses -> result
}
return CompiledKotlinScript(this, codeLine, compiled)
@@ -103,7 +103,7 @@ abstract class KotlinJsr223JvmScriptEngineBase(protected val myFactory: ScriptEn
throw ScriptException(result.message, result.location.path, result.location.line, result.location.column)
else -> throw ScriptException(result.message)
}
is ReplEvalResult.Incomplete -> throw ScriptException("error: incomplete code")
is ReplEvalResult.Incomplete -> throw ScriptException("Error: incomplete code. ${result.message}")
is ReplEvalResult.HistoryMismatch -> throw ScriptException("Repl history mismatch at line: ${result.lineNo}")
}
}
@@ -96,7 +96,7 @@ sealed class ReplCompileResult : Serializable {
companion object { private val serialVersionUID: Long = 2L }
}
class Incomplete : ReplCompileResult() {
class Incomplete(val message: String) : ReplCompileResult() {
companion object { private val serialVersionUID: Long = 1L }
}
@@ -110,7 +110,9 @@ sealed class ReplCompileResult : Serializable {
}
}
interface ReplCompiler : ReplCompileAction, ReplCheckAction, CreateReplStageStateAction
interface ReplCompilerWithoutCheck : ReplCompileAction, CreateReplStageStateAction
interface ReplCompiler : ReplCompilerWithoutCheck, ReplCheckAction
// --- eval
@@ -137,7 +139,7 @@ sealed class ReplEvalResult : Serializable {
companion object { private val serialVersionUID: Long = 1L }
}
class Incomplete : ReplEvalResult() {
class Incomplete(val message: String) : ReplEvalResult() {
companion object { private val serialVersionUID: Long = 1L }
}
@@ -175,7 +177,7 @@ interface ReplAtomicEvalAction {
invokeWrapper: InvokeWrapper? = null): ReplEvalResult
}
interface ReplAtomicEvaluator : ReplAtomicEvalAction, ReplCheckAction
interface ReplAtomicEvaluator : ReplAtomicEvalAction
interface ReplDelayedEvalAction {
fun compileToEvaluable(state: IReplStageState<*>,