Repl: keep track of command entries which were already processed

Fixes race condition
This commit is contained in:
Pavel V. Talanov
2015-10-22 20:34:08 +03:00
parent 0fe3ef7cf4
commit e20bcbde53
4 changed files with 35 additions and 2 deletions
@@ -25,6 +25,8 @@ class CommandHistory {
)
private val entries = arrayListOf<Entry>()
private var processedEntriesCount: Int = 0
val listeners = arrayListOf<HistoryUpdateListener>()
operator fun get(i: Int) = entries[i]
@@ -34,6 +36,19 @@ class CommandHistory {
listeners.forEach { it.onNewEntry(entry) }
}
fun lastUnprocessedEntry(): CommandHistory.Entry? {
if (processedEntriesCount < size) {
return get(processedEntriesCount)
}
else {
return null
}
}
fun entryProcessed() {
processedEntriesCount++
}
val size: Int
get() = entries.size
}
@@ -20,6 +20,7 @@ import com.intellij.execution.process.OSProcessHandler
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.TextRange
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.console.actions.logError
import org.jetbrains.kotlin.diagnostics.Severity
import org.w3c.dom.Element
import org.xml.sax.InputSource
@@ -69,6 +70,12 @@ class ReplOutputHandler(
"COMPILE_ERROR" -> outputProcessor.highlightCompilerErrors(createCompilerMessages(content))
"RUNTIME_ERROR" -> outputProcessor.printRuntimeError("${content.trim()}\n")
"INTERNAL_ERROR" -> outputProcessor.printInternalErrorMessage(content)
"SUCCESS" -> Unit
else -> logError(ReplOutputHandler::class.java, "Unexpected output type:\n$outputType")
}
if (outputType in setOf("SUCCESS", "COMPILE_ERROR", "INTERNAL_ERROR", "RUNTIME_ERROR")) {
runner.commandHistory.entryProcessed()
}
}
@@ -105,7 +105,11 @@ public class ReplOutputProcessor(
fun highlightCompilerErrors(compilerMessages: List<SeverityDetails>) = WriteCommandAction.runWriteCommandAction(project) {
val commandHistory = runner.commandHistory
val lastCommandStartOffset = historyDocument.textLength - commandHistory[commandHistory.size - 1].entryText.length - 1
val lastUnprocessedHistoryEntry = commandHistory.lastUnprocessedEntry() ?: return@runWriteCommandAction logError(
ReplOutputProcessor::class.java,
"Processed more commands than were sent. Sent commands: ${commandHistory.size}. Processed: ${commandHistory.processedEntriesCount}"
)
val lastCommandStartOffset = lastUnprocessedHistoryEntry.rangeInHistoryDocument.startOffset
val lastCommandStartLine = historyDocument.getLineNumber(lastCommandStartOffset)
val historyCommandRunIndicator = historyMarkup.allHighlighters.filter {
historyDocument.getLineNumber(it.startOffset) == lastCommandStartLine && it.gutterIconRenderer != null
@@ -88,7 +88,7 @@ public class KotlinReplTest : PlatformTestCase() {
}
@Test fun testOnePlusOne() = testSimpleCommand("1 + 1", "2")
@Test fun testPrintlnText() = "Hello, console world!" let { testSimpleCommand("println(\"$it\")", it) }
@Test fun testPrintlnText() = "Hello, console world!".let { testSimpleCommand("println(\"$it\")", it) }
@Test fun testDivisionByZeroException() = testSimpleCommand("1 / 0", "java.lang.ArithmeticException: / by zero")
@Test fun testMultilineSupport() {
@@ -125,4 +125,11 @@ public class KotlinReplTest : PlatformTestCase() {
sendCommand("b")
waitForExpectedOutput(readLineTextB)
}
@Test fun testCorrectAfterError() {
val message = "MyMessage"
sendCommand("fun f() { println(x)\n println(y) ")
sendCommand("println(\"$message\")")
waitForExpectedOutput(message)
}
}