Repl: clearer separation of ide and console logic
Fix a bug with redundant new lines printed in console mode
This commit is contained in:
@@ -20,10 +20,7 @@ import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.cli.common.KotlinVersion;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplErrorLogger;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplSystemInWrapper;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplSystemOutWrapper;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.UnescapeUtilsKt;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.*;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.reader.ConsoleReplCommandReader;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.reader.IdeReplCommandReader;
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.reader.ReplCommandReader;
|
||||
@@ -43,7 +40,7 @@ public class ReplFromTerminal {
|
||||
|
||||
private final boolean ideMode;
|
||||
private ReplSystemInWrapper replReader;
|
||||
private final ReplSystemOutWrapper replWriter;
|
||||
private final ReplWriter replWriter;
|
||||
private final ReplErrorLogger replErrorLogger;
|
||||
|
||||
private ReplCommandReader commandReader;
|
||||
@@ -58,8 +55,14 @@ public class ReplFromTerminal {
|
||||
// wrapper for `out` is required to escape every input in [ideMode];
|
||||
// if [ideMode == false] then just redirects all input to [System.out]
|
||||
// if user calls [System.setOut(...)] then undefined behaviour
|
||||
replWriter = new ReplSystemOutWrapper(ideMode, System.out);
|
||||
System.setOut(replWriter);
|
||||
if (ideMode) {
|
||||
ReplSystemOutWrapperForIde soutWrapper = new ReplSystemOutWrapperForIde(System.out);
|
||||
replWriter = soutWrapper;
|
||||
System.setOut(soutWrapper);
|
||||
}
|
||||
else {
|
||||
replWriter = new ReplConsoleWriter();
|
||||
}
|
||||
|
||||
// wrapper for `in` is required to give user possibility of calling
|
||||
// [readLine] from ide-console repl
|
||||
@@ -216,7 +219,7 @@ public class ReplFromTerminal {
|
||||
return true;
|
||||
}
|
||||
else if (split.size() >= 2 && split.get(0).equals("dump") && split.get(1).equals("bytecode")) {
|
||||
getReplInterpreter().dumpClasses(new PrintWriter(replWriter));
|
||||
getReplInterpreter().dumpClasses(new PrintWriter(System.out));
|
||||
return true;
|
||||
}
|
||||
else if (split.size() >= 1 && split.get(0).equals("quit")) {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.jvm.repl.messages
|
||||
|
||||
class ReplConsoleWriter : ReplWriter {
|
||||
override fun printlnWelcomeMessage(x: String) = println(x)
|
||||
override fun printlnHelpMessage(x: String) = println(x)
|
||||
override fun outputCompileError(x: String) = println(x)
|
||||
override fun outputCommandResult(x: Any?) = println(x)
|
||||
override fun outputRuntimeError(x: String) = println(x)
|
||||
|
||||
override fun notifyReadLineStart() {}
|
||||
override fun notifyReadLineEnd() {}
|
||||
override fun notifyIncomplete() {}
|
||||
override fun notifyCommandSuccess() {}
|
||||
override fun sendInternalErrorReport(x: String) {}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.utils.rethrow
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
|
||||
public class ReplErrorLogger(private val ideMode: Boolean, private val replWriter: ReplSystemOutWrapper) {
|
||||
public class ReplErrorLogger(private val ideMode: Boolean, private val replWriter: ReplWriter) {
|
||||
fun logException(e: Throwable?) {
|
||||
if (ideMode) {
|
||||
val errorStringWriter = StringWriter()
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.io.InputStream
|
||||
|
||||
public class ReplSystemInWrapper(
|
||||
private val stdin: InputStream,
|
||||
private val replWriter: ReplSystemOutWrapper
|
||||
private val replWriter: ReplWriter
|
||||
) : InputStream() {
|
||||
private var isXmlIncomplete = true
|
||||
private var isLastByteProcessed = false
|
||||
|
||||
+12
-15
@@ -23,7 +23,7 @@ import java.io.PrintStream
|
||||
val END_LINE: String = LineSeparator.getSystemLineSeparator().separatorString
|
||||
val XML_PREAMBLE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
||||
|
||||
public class ReplSystemOutWrapper(private val ideMode: Boolean, standardOut: PrintStream) : PrintStream(standardOut, true) {
|
||||
public class ReplSystemOutWrapperForIde(standardOut: PrintStream) : PrintStream(standardOut, true), ReplWriter {
|
||||
private enum class EscapeType {
|
||||
INITIAL_PROMPT,
|
||||
HELP_PROMPT,
|
||||
@@ -50,10 +50,7 @@ public class ReplSystemOutWrapper(private val ideMode: Boolean, standardOut: Pri
|
||||
private fun printlnWithEscaping(text: String, escapeType: EscapeType = EscapeType.USER_OUTPUT) = printWithEscaping("$text\n", escapeType)
|
||||
|
||||
private fun printWithEscaping(text: String, escapeType: EscapeType = EscapeType.USER_OUTPUT) {
|
||||
if (ideMode)
|
||||
super.print("${xmlEscape(text, escapeType)}$END_LINE")
|
||||
else
|
||||
super.print(text)
|
||||
super.print("${xmlEscape(text, escapeType)}$END_LINE")
|
||||
}
|
||||
|
||||
private fun xmlEscape(s: String, escapeType: EscapeType): String {
|
||||
@@ -61,14 +58,14 @@ public class ReplSystemOutWrapper(private val ideMode: Boolean, standardOut: Pri
|
||||
return "$XML_PREAMBLE<output type=\"$escapeType\">${StringUtil.escapeXml(singleLine)}</output>"
|
||||
}
|
||||
|
||||
fun printlnWelcomeMessage(x: String) = printlnWithEscaping(x, EscapeType.INITIAL_PROMPT)
|
||||
fun printlnHelpMessage(x: String) = printlnWithEscaping(x, EscapeType.HELP_PROMPT)
|
||||
fun outputCommandResult(x: Any?) = printlnWithEscaping(x.toString(), EscapeType.REPL_RESULT)
|
||||
fun notifyReadLineStart() = printlnWithEscaping("", EscapeType.READLINE_START)
|
||||
fun notifyReadLineEnd() = printlnWithEscaping("", EscapeType.READLINE_END)
|
||||
fun notifyCommandSuccess() = printlnWithEscaping("", EscapeType.SUCCESS)
|
||||
fun notifyIncomplete() = printlnWithEscaping("", EscapeType.REPL_INCOMPLETE)
|
||||
fun outputCompileError(x: String) = printlnWithEscaping(x, EscapeType.COMPILE_ERROR)
|
||||
fun outputRuntimeError(x: String) = printlnWithEscaping(x, EscapeType.RUNTIME_ERROR)
|
||||
fun sendInternalErrorReport(x: String) = printlnWithEscaping(x, EscapeType.INTERNAL_ERROR)
|
||||
override fun printlnWelcomeMessage(x: String) = printlnWithEscaping(x, EscapeType.INITIAL_PROMPT)
|
||||
override fun printlnHelpMessage(x: String) = printlnWithEscaping(x, EscapeType.HELP_PROMPT)
|
||||
override fun outputCommandResult(x: Any?) = printlnWithEscaping(x.toString(), EscapeType.REPL_RESULT)
|
||||
override fun notifyReadLineStart() = printlnWithEscaping("", EscapeType.READLINE_START)
|
||||
override fun notifyReadLineEnd() = printlnWithEscaping("", EscapeType.READLINE_END)
|
||||
override fun notifyCommandSuccess() = printlnWithEscaping("", EscapeType.SUCCESS)
|
||||
override fun notifyIncomplete() = printlnWithEscaping("", EscapeType.REPL_INCOMPLETE)
|
||||
override fun outputCompileError(x: String) = printlnWithEscaping(x, EscapeType.COMPILE_ERROR)
|
||||
override fun outputRuntimeError(x: String) = printlnWithEscaping(x, EscapeType.RUNTIME_ERROR)
|
||||
override fun sendInternalErrorReport(x: String) = printlnWithEscaping(x, EscapeType.INTERNAL_ERROR)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.jvm.repl.messages
|
||||
|
||||
interface ReplWriter {
|
||||
fun printlnWelcomeMessage(x: String)
|
||||
fun printlnHelpMessage(x: String)
|
||||
fun outputCommandResult(x: Any?)
|
||||
fun notifyReadLineStart()
|
||||
fun notifyReadLineEnd()
|
||||
fun notifyIncomplete()
|
||||
fun notifyCommandSuccess()
|
||||
fun outputCompileError(x: String)
|
||||
fun outputRuntimeError(x: String)
|
||||
fun sendInternalErrorReport(x: String)
|
||||
}
|
||||
Reference in New Issue
Block a user