.kotlin.kotlin-compiler.1.3.11.source-code.ReplHistory.kt Maven / Gradle / Ivy
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.cli.common.repl
import java.io.Serializable
import java.util.*
typealias CompiledHistoryItem = Pair
typealias SourceHistoryItem = Pair
typealias CompiledHistoryStorage = ArrayDeque>
typealias CompiledHistoryList = List>
typealias SourceHistoryList = List>
typealias SourceList = List
/*
WARNING: Not thread safe, the caller is assumed to lock access.
*/
class ReplHistory(startingHistory: CompiledHistoryList = emptyList()) : Serializable {
private val history: CompiledHistoryStorage = ArrayDeque(startingHistory)
fun isEmpty(): Boolean = history.isEmpty()
fun isNotEmpty(): Boolean = history.isNotEmpty()
fun add(line: CompiledReplCodeLine, value: T) {
history.add(line to value)
}
/* remove last line only if it is the line we think it is */
fun removeLast(line: CompiledReplCodeLine): Boolean {
return if (history.peekLast().first == line) {
history.removeLast()
true
}
else {
false
}
}
/* resets back complete history and returns the lines removed */
fun reset(): SourceHistoryList {
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 {
val removed = arrayListOf>()
while ((history.peekLast()?.first?.source?.no ?: -1) > lineNumber) {
removed.add(history.removeLast().let { Pair(it.first.source, it.second) })
}
return removed.reversed()
}
fun resetToLine(line: ReplCodeLine): SourceHistoryList = resetToLine(line.no)
fun resetToLine(line: CompiledReplCodeLine): CompiledHistoryList {
val removed = arrayListOf>()
while ((history.peekLast()?.first?.source?.no ?: -1) > line.source.no) {
removed.add(history.removeLast())
}
return removed.reversed()
}
fun contains(line: ReplCodeLine): Boolean = history.any { it.first.source == line }
fun contains(line: CompiledReplCodeLine): Boolean = history.any { it.first == line }
fun lastItem(): CompiledHistoryItem? = history.peekLast()
fun lastCodeLine(): CompiledReplCodeLine? = lastItem()?.first
fun lastValue(): T? = lastItem()?.second
fun checkHistoryIsInSync(compareHistory: SourceList?): Boolean {
return firstMismatchingHistory(compareHistory) == null
}
// return from the compareHistory the first line that does not match or null
fun firstMismatchingHistory(compareHistory: SourceList?): Int? = when {
compareHistory == null -> null
compareHistory.size == history.size -> history.zip(compareHistory).firstOrNull { it.first.first.source != it.second }?.second?.no
compareHistory.size > history.size -> compareHistory[history.size].no
else -> history.toList()[compareHistory.size].first.source.no
}
fun copySources(): SourceList = history.map { it.first.source }
fun copyValues(): List = history.map { it.second }
fun copyAll(): CompiledHistoryList = history.toList()
companion object {
private val serialVersionUID: Long = 8328353000L
}
}