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 ->
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.cli.jvm.repl.messages.DiagnosticMessageHolder
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.script.KotlinScriptExternalDependencies
import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.locks.ReentrantReadWriteLock
class ReplCompilerStageHistory(private val state: GenericReplCompilerState) : BasicReplStageHistory<ScriptDescriptor>(state.lock) {
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.script.KotlinScriptDefinition
import java.util.concurrent.locks.ReentrantReadWriteLock
// TODO: remove if unused after switching old repl to the new infrastruct
open class GenericRepl protected constructor(
disposable: Disposable,
scriptDefinition: KotlinScriptDefinition,
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplTerminalDiagnosticMessageH
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.psi.KtFile
@@ -185,7 +185,7 @@ class ReplInterpreter(
private fun renderStackTrace(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
}
@@ -214,8 +214,8 @@ class ReplInterpreter(
state.beforeCompile()
KotlinCodegenFacade.generatePackage(
state,
script.getContainingKtFile().packageFqName,
setOf(script.getContainingKtFile()),
script.containingKtFile.packageFqName,
setOf(script.containingKtFile),
errorHandler
)
}
@@ -20,8 +20,6 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.repl.*
import org.jetbrains.kotlin.daemon.common.*
import java.io.File
import java.io.InputStream
import java.io.OutputStream
import java.util.concurrent.locks.ReentrantReadWriteLock
// TODO: reduce number of ports used then SOCKET_ANY_FREE_PORT is passed (same problem with other calls)
@@ -740,7 +740,7 @@ class CompileServiceImpl(
operationsTracer: RemoteOperationsTracer?,
body: (PrintStream, EventManager, Profiler) -> ExitCode): CompileService.CallResult<Int> =
ifAlive {
withValidClientOrSessionProxy(sessionId) { session ->
withValidClientOrSessionProxy(sessionId) { _ ->
operationsTracer?.before("compile")
val rpcProfiler = if (daemonOptions.reportPerf) WallAndThreadTotalProfiler() else DummyProfiler()
val eventManger = EventManagerImpl()
@@ -770,7 +770,7 @@ class CompileServiceImpl(
tracer: RemoteOperationsTracer?,
body: (EventManager, Profiler) -> ExitCode): CompileService.CallResult<Int> =
ifAlive {
withValidClientOrSessionProxy(sessionId) { session ->
withValidClientOrSessionProxy(sessionId) { _ ->
tracer?.before("compile")
val rpcProfiler = if (daemonOptions.reportPerf) WallAndThreadTotalProfiler() else DummyProfiler()
val eventManger = EventManagerImpl()
@@ -362,7 +362,7 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
val daemon = KotlinCompilerClient.connectToCompileService(compilerId, flagFile, daemonJVMOptions, daemonOptions, DaemonReportingTargets(out = System.err), autostart = true)
assertNotNull("failed to connect daemon", daemon)
val (registry, port) = findPortAndCreateRegistry(10, 16384, 65535)
val (_, port) = findPortAndCreateRegistry(10, 16384, 65535)
val tracer = SynchronizationTracer(CountDownLatch(1), CountDownLatch(PARALLEL_THREADS_TO_COMPILE), port)
val resultCodes = arrayOfNulls<Int>(PARALLEL_THREADS_TO_COMPILE)
@@ -683,13 +683,13 @@ internal fun File.ifLogNotContainsSequence(vararg patterns: String, body: (LineP
internal fun File.assertLogContainsSequence(vararg patterns: String) {
ifLogNotContainsSequence(*patterns)
{
pattern,lineNo -> fail("Pattern '${pattern.regex}' is not found in the log file '$absolutePath'")
pattern, _ -> fail("Pattern '${pattern.regex}' is not found in the log file '$absolutePath'")
}
}
internal fun File.isLogContainsSequence(vararg patterns: String): Boolean {
var res = true
ifLogNotContainsSequence(*patterns) { l,c -> res = false }
ifLogNotContainsSequence(*patterns) { _, _ -> res = false }
return res
}
@@ -736,7 +736,7 @@ open class TestKotlinScriptDummyDependenciesResolver : ScriptDependenciesResolve
}
@ScriptTemplateDefinition(resolver = TestKotlinScriptDummyDependenciesResolver::class)
abstract class ScriptWithNoParam()
abstract class ScriptWithNoParam
internal fun classpathFromClassloader(): List<File> =
(TestKotlinScriptDummyDependenciesResolver::class.java.classLoader as? URLClassLoader)?.urLs