From bceb138ed1aacc4de8c9ec2c3a64db4987450ebc Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Fri, 1 Dec 2017 18:49:24 +0300 Subject: [PATCH] REPL, Refactoring: Get rid of nasty enum-like String literals --- .../messages/ReplSystemOutWrapperForIde.kt | 48 ++++++++----------- .../kotlin/utils/repl/ReplEscapeType.kt | 42 ++++++++++++++++ .../kotlin/console/ReplOutputHandler.kt | 30 ++++++------ 3 files changed, 77 insertions(+), 43 deletions(-) create mode 100644 compiler/util/src/org/jetbrains/kotlin/utils/repl/ReplEscapeType.kt diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/messages/ReplSystemOutWrapperForIde.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/messages/ReplSystemOutWrapperForIde.kt index 402266860bc..85ffb12a4bc 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/messages/ReplSystemOutWrapperForIde.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/messages/ReplSystemOutWrapperForIde.kt @@ -18,26 +18,14 @@ package org.jetbrains.kotlin.cli.jvm.repl.messages import com.intellij.openapi.util.text.StringUtil import com.intellij.util.LineSeparator +import org.jetbrains.kotlin.utils.repl.ReplEscapeType import java.io.PrintStream +import org.jetbrains.kotlin.utils.repl.ReplEscapeType.* -val END_LINE: String = LineSeparator.getSystemLineSeparator().separatorString -val XML_PREAMBLE = "" +internal val END_LINE: String = LineSeparator.getSystemLineSeparator().separatorString +internal val XML_PREAMBLE = "" class ReplSystemOutWrapperForIde(standardOut: PrintStream) : PrintStream(standardOut, true), ReplWriter { - private enum class EscapeType { - INITIAL_PROMPT, - HELP_PROMPT, - USER_OUTPUT, - REPL_RESULT, - READLINE_START, - READLINE_END, - REPL_INCOMPLETE, - COMPILE_ERROR, - RUNTIME_ERROR, - INTERNAL_ERROR, - SUCCESS - } - override fun print(x: Boolean) = printWithEscaping(x.toString()) override fun print(x: Char) = printWithEscaping(x.toString()) override fun print(x: Int) = printWithEscaping(x.toString()) @@ -47,25 +35,27 @@ class ReplSystemOutWrapperForIde(standardOut: PrintStream) : PrintStream(standar override fun print(x: String) = printWithEscaping(x) override fun print(x: Any?) = printWithEscaping(x.toString()) - private fun printlnWithEscaping(text: String, escapeType: EscapeType = EscapeType.USER_OUTPUT) = printWithEscaping("$text\n", escapeType) + private fun printlnWithEscaping(text: String, escapeType: ReplEscapeType = USER_OUTPUT) { + printWithEscaping("$text\n", escapeType) + } - private fun printWithEscaping(text: String, escapeType: EscapeType = EscapeType.USER_OUTPUT) { + private fun printWithEscaping(text: String, escapeType: ReplEscapeType = USER_OUTPUT) { super.print("${xmlEscape(text, escapeType)}$END_LINE") } - private fun xmlEscape(s: String, escapeType: EscapeType): String { + private fun xmlEscape(s: String, escapeType: ReplEscapeType): String { val singleLine = StringUtil.replace(s, SOURCE_CHARS, XML_REPLACEMENTS) return "$XML_PREAMBLE${StringUtil.escapeXml(singleLine)}" } - override fun printlnWelcomeMessage(x: String) = printlnWithEscaping(x, EscapeType.INITIAL_PROMPT) - override fun printlnHelpMessage(x: String) = printlnWithEscaping(x, EscapeType.HELP_PROMPT) - override fun outputCommandResult(x: String) = printlnWithEscaping(x, 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) + override fun printlnWelcomeMessage(x: String) = printlnWithEscaping(x, INITIAL_PROMPT) + override fun printlnHelpMessage(x: String) = printlnWithEscaping(x, HELP_PROMPT) + override fun outputCommandResult(x: String) = printlnWithEscaping(x, REPL_RESULT) + override fun notifyReadLineStart() = printlnWithEscaping("", READLINE_START) + override fun notifyReadLineEnd() = printlnWithEscaping("", READLINE_END) + override fun notifyCommandSuccess() = printlnWithEscaping("", SUCCESS) + override fun notifyIncomplete() = printlnWithEscaping("", REPL_INCOMPLETE) + override fun outputCompileError(x: String) = printlnWithEscaping(x, COMPILE_ERROR) + override fun outputRuntimeError(x: String) = printlnWithEscaping(x, RUNTIME_ERROR) + override fun sendInternalErrorReport(x: String) = printlnWithEscaping(x, INTERNAL_ERROR) } \ No newline at end of file diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/repl/ReplEscapeType.kt b/compiler/util/src/org/jetbrains/kotlin/utils/repl/ReplEscapeType.kt new file mode 100644 index 00000000000..2b493ea711d --- /dev/null +++ b/compiler/util/src/org/jetbrains/kotlin/utils/repl/ReplEscapeType.kt @@ -0,0 +1,42 @@ +/* + * 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.utils.repl + +enum class ReplEscapeType { + INITIAL_PROMPT, + HELP_PROMPT, + USER_OUTPUT, + REPL_RESULT, + READLINE_START, + READLINE_END, + REPL_INCOMPLETE, + COMPILE_ERROR, + RUNTIME_ERROR, + INTERNAL_ERROR, + SUCCESS; + + companion object { + fun valueOfOrNull(string: String): ReplEscapeType? { + return try { + valueOf(string) + } + catch (e: IllegalArgumentException) { + null + } + } + } +} \ No newline at end of file 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 386e4dffb27..3b30553ebf4 100644 --- a/idea/idea-repl/src/org/jetbrains/kotlin/console/ReplOutputHandler.kt +++ b/idea/idea-repl/src/org/jetbrains/kotlin/console/ReplOutputHandler.kt @@ -24,11 +24,13 @@ import com.intellij.openapi.util.text.StringUtil import org.jetbrains.annotations.NotNull import org.jetbrains.kotlin.console.actions.logError import org.jetbrains.kotlin.diagnostics.Severity +import org.jetbrains.kotlin.utils.repl.ReplEscapeType import org.w3c.dom.Element import org.xml.sax.InputSource import java.io.ByteArrayInputStream import java.nio.charset.Charset import javax.xml.parsers.DocumentBuilderFactory +import org.jetbrains.kotlin.utils.repl.ReplEscapeType.* val XML_REPLACEMENTS: Array = arrayOf("#n", "#diez") val SOURCE_CHARS: Array = arrayOf("\n", "#") @@ -76,25 +78,25 @@ class ReplOutputHandler( } val root = output.firstChild as Element - val outputType = root.getAttribute("type") + val outputType = ReplEscapeType.valueOfOrNull(root.getAttribute("type")) val content = StringUtil.replace(root.textContent, XML_REPLACEMENTS, SOURCE_CHARS) when (outputType) { - "INITIAL_PROMPT" -> buildWarningIfNeededBeforeInit(content) - "HELP_PROMPT" -> outputProcessor.printHelp(content) - "USER_OUTPUT" -> outputProcessor.printUserOutput(content) - "REPL_RESULT" -> outputProcessor.printResultWithGutterIcon(content) - "READLINE_START" -> runner.isReadLineMode = true - "READLINE_END" -> runner.isReadLineMode = false - "REPL_INCOMPLETE", - "COMPILE_ERROR" -> outputProcessor.highlightCompilerErrors(createCompilerMessages(content)) - "RUNTIME_ERROR" -> outputProcessor.printRuntimeError("${content.trim()}\n") - "INTERNAL_ERROR" -> outputProcessor.printInternalErrorMessage(content) - "SUCCESS" -> runner.commandHistory.lastUnprocessedEntry()?.entryText?.let { runner.successfulLine(it) } - else -> logError(ReplOutputHandler::class.java, "Unexpected output type:\n$outputType") + INITIAL_PROMPT -> buildWarningIfNeededBeforeInit(content) + HELP_PROMPT -> outputProcessor.printHelp(content) + USER_OUTPUT -> outputProcessor.printUserOutput(content) + REPL_RESULT -> outputProcessor.printResultWithGutterIcon(content) + READLINE_START -> runner.isReadLineMode = true + READLINE_END -> runner.isReadLineMode = false + REPL_INCOMPLETE, + COMPILE_ERROR -> outputProcessor.highlightCompilerErrors(createCompilerMessages(content)) + RUNTIME_ERROR -> outputProcessor.printRuntimeError("${content.trim()}\n") + INTERNAL_ERROR -> outputProcessor.printInternalErrorMessage(content) + SUCCESS -> runner.commandHistory.lastUnprocessedEntry()?.entryText?.let { runner.successfulLine(it) } + null -> logError(ReplOutputHandler::class.java, "Unexpected output type:\n$outputType") } - if (outputType in setOf("SUCCESS", "COMPILE_ERROR", "INTERNAL_ERROR", "RUNTIME_ERROR", "READLINE_END")) { + if (outputType in setOf(SUCCESS, COMPILE_ERROR, INTERNAL_ERROR, RUNTIME_ERROR, READLINE_END)) { runner.commandHistory.entryProcessed() } }