From 84f9cb9bfd71009459bd1b3222dd0842d5de6e3c Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 1 Feb 2016 19:06:17 +0100 Subject: [PATCH] correctly separate stdout and stderr when parsing REPL output --- .../kotlin/console/ReplOutputHandler.kt | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) 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 96b5d659c01..0656d25154e 100644 --- a/idea/idea-repl/src/org/jetbrains/kotlin/console/ReplOutputHandler.kt +++ b/idea/idea-repl/src/org/jetbrains/kotlin/console/ReplOutputHandler.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.console import com.intellij.execution.process.OSProcessHandler +import com.intellij.execution.process.ProcessOutputTypes import com.intellij.openapi.util.Key import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.text.StringUtil @@ -28,8 +29,6 @@ import java.io.ByteArrayInputStream import java.nio.charset.Charset import javax.xml.parsers.DocumentBuilderFactory -private val XML_PREFIX = " = arrayOf("#n", "#diez") val SOURCE_CHARS: Array = arrayOf("\n", "#") @@ -42,7 +41,7 @@ class ReplOutputHandler( ) : OSProcessHandler(process, commandLine) { private var isBuildInfoChecked = false - private val dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder() + private val factory = DocumentBuilderFactory.newInstance() private val outputProcessor = ReplOutputProcessor(runner) private val inputBuffer = StringBuilder() @@ -52,19 +51,28 @@ class ReplOutputHandler( // hide warning about adding test folder to classpath if (text.startsWith("warning: classpath entry points to a non-existent location")) return - // skip "/usr/lib/jvm/java-8-oracle/bin/java -cp ..." intro - if (!text.startsWith(XML_PREFIX) && inputBuffer.length == 0) return super.notifyTextAvailable(text, key) - - inputBuffer.append(text) - val resultingText = inputBuffer.toString() - if (resultingText.endsWith("\n")) { - handleReplMessage(resultingText) - inputBuffer.setLength(0) + if (key == ProcessOutputTypes.STDOUT) { + inputBuffer.append(text) + val resultingText = inputBuffer.toString() + if (resultingText.endsWith("\n")) { + handleReplMessage(resultingText) + inputBuffer.setLength(0) + } + } + else { + super.notifyTextAvailable(text, key) } } private fun handleReplMessage(text: String) { - val output = dBuilder.parse(strToSource(text)) + val output = try { + factory.newDocumentBuilder().parse(strToSource(text)) + } + catch (e: Exception) { + logError(ReplOutputHandler::class.java, "Couldn't parse REPL output: $text") + return + } + val root = output.firstChild as Element val outputType = root.getAttribute("type") val content = StringUtil.replace(root.textContent, XML_REPLACEMENTS, SOURCE_CHARS) @@ -102,7 +110,7 @@ class ReplOutputHandler( private fun createCompilerMessages(runtimeErrorsReport: String): List { val compilerMessages = arrayListOf() - val report = dBuilder.parse(strToSource(runtimeErrorsReport, Charsets.UTF_16)) + val report = factory.newDocumentBuilder().parse(strToSource(runtimeErrorsReport, Charsets.UTF_16)) val entries = report.getElementsByTagName("reportEntry") for (i in 0..entries.length - 1) { val reportEntry = entries.item(i) as Element