This commit is contained in:
Ilya Chernikov
2017-02-08 09:49:26 +01:00
parent 1032f0d39c
commit a3a782613a
13 changed files with 17 additions and 111 deletions
@@ -69,7 +69,7 @@ open class AggregatedReplStateHistory<T1, T2>(val history1: IReplStageHistory<T1
}
}
open class AggregatedReplStageState<T1, T2>(val state1: IReplStageState<T1>, val state2: IReplStageState<T2>, override val lock: ReentrantReadWriteLock = ReentrantReadWriteLock())
open class AggregatedReplStageState<T1, T2>(val state1: IReplStageState<T1>, val state2: IReplStageState<T2>, final override val lock: ReentrantReadWriteLock = ReentrantReadWriteLock())
: IReplStageState<Pair<T1, T2>>
{
override val history: IReplStageHistory<Pair<T1, T2>> = AggregatedReplStateHistory(state1.history, state2.history, lock)
@@ -24,7 +24,6 @@ import kotlin.concurrent.write
data class LineId(override val no: Int, override val generation: Int, private val codeHash: Int) : ILineId, Serializable {
constructor(no: Int, generation: Int, code: String): this(no, generation, code.hashCode())
constructor(codeLine: ReplCodeLine): this(codeLine.no, codeLine.generation, codeLine.code.hashCode())
override fun compareTo(other: ILineId): Int = (other as? LineId)?.let {
@@ -65,11 +64,9 @@ open class BasicReplStageHistory<T>(override val lock: ReentrantReadWriteLock =
}
}
open class BasicReplStageState<HistoryItemT>: IReplStageState<HistoryItemT> {
open class BasicReplStageState<HistoryItemT>(override final val lock: ReentrantReadWriteLock = ReentrantReadWriteLock()): IReplStageState<HistoryItemT> {
override val currentGeneration: Int get() = history.currentGeneration.get()
override val lock = ReentrantReadWriteLock()
override val history: BasicReplStageHistory<HistoryItemT> = BasicReplStageHistory(lock)
}
@@ -27,19 +27,6 @@ open class GenericReplEvaluator(val baseClasspath: Iterable<File>,
protected val repeatingMode: ReplRepeatingMode = ReplRepeatingMode.REPEAT_ONLY_MOST_RECENT
) : ReplEvaluator {
// private val evaluatedHistory = ReplHistory<EvalClassWithInstanceAndLoader>()
// override val history: List<ReplCodeLine> get() = stateLock.read { evaluatedHistory.copySources() }
// private class HistoryActions(
// val effectiveHistory: List<EvalClassWithInstanceAndLoader>,
// val verify: (compareHistory: SourceList?) -> Int?,
// val addPlaceholder: (line: CompiledReplCodeLine, value: EvalClassWithInstanceAndLoader) -> Unit,
// val removePlaceholder: (line: CompiledReplCodeLine) -> Boolean,
// val addFinal: (line: CompiledReplCodeLine, value: EvalClassWithInstanceAndLoader) -> Unit,
// val processClasses: (compileResult: ReplCompileResult.CompiledClasses) -> Pair<ClassLoader, Class<out Any>>
// )
override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = GenericReplEvaluatorState(baseClasspath, baseClassloader, lock)
override fun eval(state: IReplStageState<*>,
@@ -48,17 +35,6 @@ open class GenericReplEvaluator(val baseClasspath: Iterable<File>,
invokeWrapper: InvokeWrapper?): ReplEvalResult {
state.lock.write {
val evalState = state.asState(GenericReplEvaluatorState::class.java)
// val verifyHistory = compileResult.state.dropLast(1)
// val defaultHistoryActor = HistoryActions(
// effectiveHistory = evalState.history.map { it.item },
// verify = { line -> evalState.history.firstMismatchingHistory(line) },
// addPlaceholder = { line, value -> evalState.history.add(line, value) },
// removePlaceholder = { line -> evalState.history.removeLast(line) },
// addFinal = { line, value -> evalState.history.add(line, value) },
// processClasses = { compiled ->
// prependClassLoaderWithNewClasses(evalState.history.copyValues(), compiled, )
// })
val historyActor = when (repeatingMode) {
ReplRepeatingMode.NONE -> HistoryActionsForNoRepeat(evalState)
ReplRepeatingMode.REPEAT_ONLY_MOST_RECENT -> {
@@ -68,19 +44,6 @@ open class GenericReplEvaluator(val baseClasspath: Iterable<File>,
}
else {
HistoryActionsForRepeatRecentOnly(evalState)
// val trimmedHistory = ReplHistory(evalState.history.copyAll().dropLast(1))
// HistoryActions
// effectiveHistory = trimmedHistory.copyValues(),
// verify = { trimmedHistory.firstMismatchingHistory(it) },
// addPlaceholder = { _, _ -> NO_ACTION() },
// removePlaceholder = { NO_ACTION_THAT_RETURNS(true) },
// addFinal = { line, value ->
// evalState.history.removeLast(line)
// evalState.history.add(line, value)
// },
// processClasses = { _ ->
// Pair(lastItem.second.classLoader, lastItem.second.klass.java)
// })
}
}
ReplRepeatingMode.REPEAT_ANY_PREVIOUS -> {
@@ -90,25 +53,6 @@ open class GenericReplEvaluator(val baseClasspath: Iterable<File>,
}
else {
HistoryActionsForRepeatAny(evalState, matchingItem)
// val historyCopy = evalState.history.copyAll()
// val matchingItem = historyCopy.first { it.first.source == compileResult.compiledCodeLine.source }
// val trimmedHistory = ReplHistory(evalState.history.copyAll().takeWhile { it != matchingItem })
// HistoryActions(
// effectiveHistory = trimmedHistory.copyValues(),
// verify = { trimmedHistory.firstMismatchingHistory(it) },
// addPlaceholder = { _, _ -> NO_ACTION() },
// removePlaceholder = { NO_ACTION_THAT_RETURNS(true) },
// addFinal = { line, value ->
// val extraLines = evalState.history.resetToLine(line)
// evalState.history.removeLast(line)
// evalState.history.add(line, value)
// extraLines.forEach {
// evalState.history.add(it.first, it.second)
// }
// },
// processClasses = { _ ->
// Pair(matchingItem.second.classLoader, matchingItem.second.klass.java)
// })
}
}
}
@@ -60,10 +60,10 @@ interface KotlinJsr223JvmInvocableScriptEngine : Invocable {
private fun invokeImpl(prioritizedCallOrder: List<EvalClassWithInstanceAndLoader>, name: String, args: Array<out Any?>): Any? {
// TODO: cache the method lookups?
val (fn, mapping, invokeWrapper) = prioritizedCallOrder.asSequence().map { attempt ->
val candidates = attempt.klass.functions.filter { it.name == name }
candidates.findMapping(listOf<Any?>(attempt.instance) + args)?.let {
Triple(it.first, it.second, attempt.invokeWrapper)
val (fn, mapping, invokeWrapper) = prioritizedCallOrder.asSequence().map { (klass, instance, _, invokeWrapper) ->
val candidates = klass.functions.filter { it.name == name }
candidates.findMapping(listOf(instance) + args)?.let {
Triple(it.first, it.second, invokeWrapper)
}
}.filterNotNull().firstOrNull() ?: throw NoSuchMethodException("no suitable function '$name' found")
@@ -110,33 +110,6 @@ interface KotlinJsr223JvmInvocableScriptEngine : Invocable {
}
}
private fun invokeImpl(prioritizedCallOrder: List<EvalClassWithInstanceAndLoader>, name: String, args: Array<out Any?>): Any? {
// TODO: cache the method lookups?
val (fn, mapping, invokeWrapper) = prioritizedCallOrder.asSequence().map { attempt ->
val candidates = attempt.klass.functions.filter { it.name == name }
candidates.findMapping(listOf<Any?>(attempt.instance) + args)?.let {
Triple(it.first, it.second, attempt.invokeWrapper)
}
}.filterNotNull().firstOrNull() ?: throw NoSuchMethodException("no suitable function '$name' found")
val res = try {
if (invokeWrapper != null) {
invokeWrapper.invoke {
fn.callBy(mapping)
}
}
else {
fn.callBy(mapping)
}
}
catch (e: Throwable) {
// ignore everything in the stack trace until this constructor call
throw ScriptException(renderReplStackTrace(e.cause!!, startFromMethodName = fn.name))
}
return if (fn.returnType.classifier == Unit::class) Unit else res
}
private fun Iterable<KFunction<*>>.findMapping(args: List<Any?>): Pair<KFunction<*>, Map<KParameter, Any?>>? {
for (fn in this) {
val mapping = tryCreateCallableMapping(fn, args)
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.cli.common.repl
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import java.io.Reader
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.locks.ReentrantReadWriteLock
import javax.script.*
@@ -26,7 +26,7 @@ fun makeScriptBaseName(codeLine: ReplCodeLine) =
fun renderReplStackTrace(cause: Throwable, startFromMethodName: String): String {
val newTrace = arrayListOf<StackTraceElement>()
var skip = true
for ((i, element) in cause.stackTrace.withIndex().reversed()) {
for ((_, element) in cause.stackTrace.withIndex().reversed()) {
if ("${element.className}.${element.methodName}" == startFromMethodName) {
skip = false
}
@@ -43,10 +43,6 @@ fun renderReplStackTrace(cause: Throwable, startFromMethodName: String): String
return Throwables.getStackTraceAsString(cause)
}
fun NO_ACTION(): Unit = Unit
fun <T> NO_ACTION_THAT_RETURNS(v: T): T = v
internal fun ClassLoader.listAllUrlsAsFiles(): List<File> {
val parents = generateSequence(this) { loader -> loader.parent }.filterIsInstance(URLClassLoader::class.java)
return parents.fold(emptyList<File>()) { accum, loader ->