diff --git a/idea/idea-repl/src/org/jetbrains/kotlin/console/CommandHistory.kt b/idea/idea-repl/src/org/jetbrains/kotlin/console/CommandHistory.kt index beb228e3f98..6d406c9900e 100644 --- a/idea/idea-repl/src/org/jetbrains/kotlin/console/CommandHistory.kt +++ b/idea/idea-repl/src/org/jetbrains/kotlin/console/CommandHistory.kt @@ -25,6 +25,8 @@ class CommandHistory { ) private val entries = arrayListOf() + private var processedEntriesCount: Int = 0 + val listeners = arrayListOf() 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 } diff --git a/idea/idea-repl/src/org/jetbrains/kotlin/console/ReplOutputHandler.kt b/idea/idea-repl/src/org/jetbrains/kotlin/console/ReplOutputHandler.kt index 0d985cc6760..ea4125b2d54 100644 --- a/idea/idea-repl/src/org/jetbrains/kotlin/console/ReplOutputHandler.kt +++ b/idea/idea-repl/src/org/jetbrains/kotlin/console/ReplOutputHandler.kt @@ -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() } } diff --git a/idea/idea-repl/src/org/jetbrains/kotlin/console/ReplOutputProcessor.kt b/idea/idea-repl/src/org/jetbrains/kotlin/console/ReplOutputProcessor.kt index 7d7f7c0946e..44efc636c51 100644 --- a/idea/idea-repl/src/org/jetbrains/kotlin/console/ReplOutputProcessor.kt +++ b/idea/idea-repl/src/org/jetbrains/kotlin/console/ReplOutputProcessor.kt @@ -105,7 +105,11 @@ public class ReplOutputProcessor( fun highlightCompilerErrors(compilerMessages: List) = 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 diff --git a/idea/tests/org/jetbrains/kotlin/idea/console/KotlinReplTest.kt b/idea/tests/org/jetbrains/kotlin/idea/console/KotlinReplTest.kt index 4e926cc9bb6..b5e95feddc0 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/console/KotlinReplTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/console/KotlinReplTest.kt @@ -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) + } } \ No newline at end of file