Add total reset to repl history and state interfaces
This commit is contained in:
+9
-1
@@ -52,11 +52,19 @@ open class AggregatedReplStateHistory<T1, T2>(val history1: IReplStageHistory<T1
|
||||
ReplHistoryRecord(r1.id, r1.item to r2.item)
|
||||
}
|
||||
|
||||
override fun reset(): Iterable<ILineId> = lock.write {
|
||||
assertSameSize()
|
||||
val i1 = history1.reset().toList()
|
||||
val i2 = history2.reset().toList()
|
||||
if (i1 != i2) throw IllegalStateException("Aggregated history reset lines mismatch: $i1 != $i2")
|
||||
i1
|
||||
}
|
||||
|
||||
override fun resetTo(id: ILineId): Iterable<ILineId> = lock.write {
|
||||
assertSameSize()
|
||||
val i1 = history1.resetTo(id).toList()
|
||||
val i2 = history2.resetTo(id).toList()
|
||||
if (i1 != i2) throw IllegalStateException("Aggregated history resetted lines mismatch: $i1 != $i2")
|
||||
if (i1 != i2) throw IllegalStateException("Aggregated history reset lines mismatch: $i1 != $i2")
|
||||
i1
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,14 @@ open class BasicReplStageHistory<T>(override val lock: ReentrantReadWriteLock =
|
||||
|
||||
override fun pop(): ReplHistoryRecord<T>? = lock.write { if (isEmpty()) null else removeAt(lastIndex) }
|
||||
|
||||
override fun reset(): Iterable<ILineId> {
|
||||
lock.write {
|
||||
val removed = map { it.id }
|
||||
clear()
|
||||
return removed
|
||||
}
|
||||
}
|
||||
|
||||
override fun resetTo(id: ILineId): Iterable<ILineId> {
|
||||
lock.write {
|
||||
val idx = indexOfFirst { it.id == id }
|
||||
|
||||
+7
-2
@@ -46,8 +46,13 @@ class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
|
||||
aggregatedState.apply {
|
||||
lock.write {
|
||||
if (state1.history.size > state2.history.size) {
|
||||
state2.history.peek()?.let {
|
||||
state1.history.resetTo(it.id)
|
||||
if (state2.history.size == 0) {
|
||||
state1.history.reset()
|
||||
}
|
||||
else {
|
||||
state2.history.peek()?.let {
|
||||
state1.history.resetTo(it.id)
|
||||
}
|
||||
}
|
||||
assert(state1.history.size == state2.history.size)
|
||||
}
|
||||
|
||||
@@ -52,6 +52,13 @@ class ReplHistory<T>(startingHistory: CompiledHistoryList<T> = emptyList()) : Se
|
||||
}
|
||||
}
|
||||
|
||||
/* resets back complete history and returns the lines removed */
|
||||
fun reset(): SourceHistoryList<T> {
|
||||
val removed = history.map { Pair(it.first.source, it.second) }
|
||||
history.clear()
|
||||
return removed
|
||||
}
|
||||
|
||||
/* resets back to a previous line number and returns the lines removed */
|
||||
fun resetToLine(lineNumber: Int): SourceHistoryList<T> {
|
||||
val removed = arrayListOf<SourceHistoryItem<T>>()
|
||||
|
||||
@@ -41,6 +41,8 @@ interface IReplStageHistory<T> : List<ReplHistoryRecord<T>> {
|
||||
else null
|
||||
}
|
||||
|
||||
fun reset(): Iterable<ILineId>
|
||||
|
||||
fun resetTo(id: ILineId): Iterable<ILineId>
|
||||
|
||||
val lock: ReentrantReadWriteLock
|
||||
|
||||
@@ -26,16 +26,28 @@ import kotlin.script.dependencies.KotlinScriptExternalDependencies
|
||||
|
||||
class ReplCompilerStageHistory(private val state: GenericReplCompilerState) : BasicReplStageHistory<ScriptDescriptor>(state.lock) {
|
||||
|
||||
override fun reset(): Iterable<ILineId> {
|
||||
val removedCompiledLines = super.reset()
|
||||
val removedAnalyzedLines = state.analyzerEngine.reset()
|
||||
|
||||
checkConsistent(removedCompiledLines, removedAnalyzedLines)
|
||||
return removedCompiledLines
|
||||
}
|
||||
|
||||
override fun resetTo(id: ILineId): Iterable<ILineId> {
|
||||
val removedCompiledLines = super.resetTo(id)
|
||||
val removedAnalyzedLines = state.analyzerEngine.resetToLine(id.no)
|
||||
val removedAnalyzedLines = state.analyzerEngine.resetToLine(id)
|
||||
|
||||
checkConsistent(removedCompiledLines, removedAnalyzedLines)
|
||||
return removedCompiledLines
|
||||
}
|
||||
|
||||
private fun checkConsistent(removedCompiledLines: Iterable<ILineId>, removedAnalyzedLines: List<ReplCodeLine>) {
|
||||
removedCompiledLines.zip(removedAnalyzedLines).forEach {
|
||||
if (it.first != LineId(it.second)) {
|
||||
throw IllegalStateException("History mismatch when resetting lines: ${it.first.no} != ${it.second}")
|
||||
}
|
||||
}
|
||||
return removedCompiledLines
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package org.jetbrains.kotlin.cli.jvm.repl
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.repl.CompiledReplCodeLine
|
||||
import org.jetbrains.kotlin.cli.common.repl.ILineId
|
||||
import org.jetbrains.kotlin.cli.common.repl.ReplCodeLine
|
||||
import org.jetbrains.kotlin.cli.common.repl.ReplHistory
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport
|
||||
@@ -88,7 +89,9 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
|
||||
}
|
||||
}
|
||||
|
||||
fun resetToLine(lineNumber: Int): List<ReplCodeLine> = replState.resetToLine(lineNumber)
|
||||
fun resetToLine(lineId: ILineId): List<ReplCodeLine> = replState.resetToLine(lineId)
|
||||
|
||||
fun reset(): List<ReplCodeLine> = replState.reset()
|
||||
|
||||
fun analyzeReplLine(psiFile: KtFile, codeLine: ReplCodeLine): ReplLineAnalysisResult {
|
||||
topDownAnalysisContext.scripts.clear()
|
||||
@@ -172,12 +175,17 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
|
||||
private val successfulLines = ReplHistory<LineInfo.SuccessfulLine>()
|
||||
private val submittedLines = hashMapOf<KtFile, LineInfo>()
|
||||
|
||||
fun resetToLine(lineNumber: Int): List<ReplCodeLine> {
|
||||
val removed = successfulLines.resetToLine(lineNumber)
|
||||
fun resetToLine(lineId: ILineId): List<ReplCodeLine> {
|
||||
val removed = successfulLines.resetToLine(lineId.no)
|
||||
removed.forEach { submittedLines.remove(it.second.linePsi) }
|
||||
return removed.map { it.first }
|
||||
}
|
||||
|
||||
fun reset(): List<ReplCodeLine> {
|
||||
submittedLines.clear()
|
||||
return successfulLines.reset().map { it.first }
|
||||
}
|
||||
|
||||
fun submitLine(ktFile: KtFile, codeLine: ReplCodeLine) {
|
||||
val line = LineInfo.SubmittedLine(ktFile, successfulLines.lastValue())
|
||||
submittedLines[ktFile] = line
|
||||
|
||||
+5
-3
@@ -37,10 +37,12 @@ class RemoteReplCompilerStateHistory(private val state: RemoteReplCompilerState)
|
||||
throw NotImplementedError("pop from remote history is not supported")
|
||||
}
|
||||
|
||||
override fun reset(): Iterable<ILineId> = state.replStateFacade.historyReset().apply {
|
||||
currentGeneration.incrementAndGet()
|
||||
}
|
||||
|
||||
override fun resetTo(id: ILineId): Iterable<ILineId> = state.replStateFacade.historyResetTo(id).apply {
|
||||
if (isNotEmpty()) {
|
||||
currentGeneration.incrementAndGet()
|
||||
}
|
||||
currentGeneration.incrementAndGet()
|
||||
}
|
||||
|
||||
val currentGeneration = AtomicInteger(REPL_CODE_LINE_FIRST_GEN)
|
||||
|
||||
+3
@@ -31,6 +31,9 @@ interface ReplStateFacade : Remote {
|
||||
@Throws(RemoteException::class)
|
||||
fun historyGet(index: Int): ILineId
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun historyReset(): List<ILineId>
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun historyResetTo(id: ILineId): List<ILineId>
|
||||
}
|
||||
@@ -35,5 +35,7 @@ class RemoteReplStateFacadeServer(val _id: Int,
|
||||
|
||||
override fun historyGet(index: Int): ILineId = state.history[index].id
|
||||
|
||||
override fun historyReset(): List<ILineId> = state.history.reset().toList()
|
||||
|
||||
override fun historyResetTo(id: ILineId): List<ILineId> = state.history.resetTo(id).toList()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user