[cli-repl][ide-console] Correct escaping

This commit is contained in:
Dmitry Kovanikov
2015-08-22 19:23:38 +03:00
committed by Pavel V. Talanov
parent e4ffe8b145
commit e23441907c
10 changed files with 87 additions and 23 deletions
@@ -25,7 +25,7 @@ import jline.console.history.FileHistory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.cli.common.KotlinVersion;
import org.jetbrains.kotlin.cli.jvm.repl.messages.FromIdeXmlMessagesParser;
import org.jetbrains.kotlin.cli.jvm.repl.messages.IdeXmlMessagesParser;
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplSystemOutWrapper;
import org.jetbrains.kotlin.config.CompilerConfiguration;
import org.jetbrains.kotlin.utils.UtilsPackage;
@@ -42,6 +42,7 @@ public class ReplFromTerminal {
private final boolean ideMode;
private final ReplSystemOutWrapper replWriter;
private final IdeXmlMessagesParser ideXmlParser = new IdeXmlMessagesParser();
private final ConsoleReader consoleReader;
@@ -186,7 +187,7 @@ public class ReplFromTerminal {
private String readLine(@Nullable String prompt) throws IOException {
String line = consoleReader.readLine(prompt);
if (ideMode && line != null) {
line = FromIdeXmlMessagesParser.parse(line);
line = ideXmlParser.parse(line);
}
return line;
}
@@ -0,0 +1,25 @@
/*
* 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
public object EscapeConstants {
public val XML_PREAMBLE: String = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
// using '#' to avoid collisions with xml escaping
public val SOURCE_CHARS: Array<String> = arrayOf("\n", "#")
public val XML_REPLACEMENTS: Array<String> = arrayOf("#n", "#diez")
}
@@ -21,18 +21,17 @@ import org.w3c.dom.Element
import org.xml.sax.InputSource
import java.io.ByteArrayInputStream
import javax.xml.parsers.DocumentBuilderFactory
import kotlin.platform.platformStatic
public object FromIdeXmlMessagesParser {
public class IdeXmlMessagesParser {
private fun strToSource(s: String) = InputSource(ByteArrayInputStream(s.toByteArray()))
platformStatic fun parse(inputMessage: String): String {
fun parse(inputMessage: String): String {
val docFactory = DocumentBuilderFactory.newInstance()
val docBuilder = docFactory.newDocumentBuilder()
val input = docBuilder.parse(strToSource(inputMessage))
val root = input.firstChild as Element
val inputContent = StringUtil.unescapeStringCharacters(root.textContent).trim()
val inputContent = StringUtil.replace(root.textContent, EscapeConstants.XML_REPLACEMENTS, EscapeConstants.SOURCE_CHARS).trim()
return inputContent
}
@@ -27,7 +27,7 @@ public class ReplIdeDiagnosticMessageHolder : DiagnosticMessageHolder {
private val diagnostics = arrayListOf<Pair<Diagnostic, String>>()
override fun report(diagnostic: Diagnostic, file: PsiFile, render: String) {
diagnostics.add(diagnostic to render)
diagnostics.add(Pair(diagnostic, render))
}
override val renderedDiagnostics: String
@@ -21,7 +21,6 @@ import com.intellij.util.LineSeparator
import java.io.PrintStream
public class ReplSystemOutWrapper(private val standardOut: PrintStream, private val ideMode: Boolean) : PrintStream(standardOut, true) {
private val XML_PREFIX = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
private val END_LINE = LineSeparator.getSystemLineSeparator().separatorString
private enum class EscapeType {
@@ -51,8 +50,8 @@ public class ReplSystemOutWrapper(private val standardOut: PrintStream, private
}
private fun xmlEscape(s: String, escapeType: EscapeType): String {
val singleLine = StringUtil.escapeLineBreak(s)
return "$XML_PREFIX<output type=\"$escapeType\">${StringUtil.escapeXml(singleLine)}</output>"
val singleLine = StringUtil.replace(s, EscapeConstants.SOURCE_CHARS, EscapeConstants.XML_REPLACEMENTS)
return "${EscapeConstants.XML_PREAMBLE}<output type=\"$escapeType\">${StringUtil.escapeXml(singleLine)}</output>"
}
fun printlnResult(x: Any?) = printlnWithEscaping(x.toString(), EscapeType.REPL_RESULT)