.kotlin.kotlin-compiler.1.3.11.source-code.BasicReplState.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.*
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.locks.ReentrantReadWriteLock
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)
} ?: -1 // TODO: check if it doesn't break something
companion object {
private val serialVersionUID: Long = 8328353000L
}
}
open class BasicReplStageHistory(override val lock: ReentrantReadWriteLock = ReentrantReadWriteLock()) : IReplStageHistory, ArrayList>() {
val currentGeneration = AtomicInteger(REPL_CODE_LINE_FIRST_GEN)
override fun push(id: ILineId, item: T) {
lock.write {
add(ReplHistoryRecord(id, item))
}
}
override fun pop(): ReplHistoryRecord? = lock.write { if (isEmpty()) null else removeAt(lastIndex) }
override fun reset(): Iterable {
lock.write {
val removed = map { it.id }
clear()
currentGeneration.incrementAndGet()
return removed
}
}
override fun resetTo(id: ILineId): Iterable {
lock.write {
val idx = indexOfFirst { it.id == id }
if (idx < 0) throw java.util.NoSuchElementException("Cannot rest to inexistent line ${id.no}")
return if (idx < lastIndex) {
val removed = asSequence().drop(idx + 1).map { it.id }.toList()
removeRange(idx + 1, size)
currentGeneration.incrementAndGet()
removed
}
else {
currentGeneration.incrementAndGet()
emptyList()
}
}
}
}
open class BasicReplStageState(override final val lock: ReentrantReadWriteLock = ReentrantReadWriteLock()): IReplStageState {
override val currentGeneration: Int get() = history.currentGeneration.get()
override val history: BasicReplStageHistory = BasicReplStageHistory(lock)
}