diff --git a/library/src/dotty/Show.scala b/library/src/dotty/Show.scala index 0a1bfd89d8a0..42f7953cd528 100644 --- a/library/src/dotty/Show.scala +++ b/library/src/dotty/Show.scala @@ -20,25 +20,28 @@ object Show extends LowPrioShow { ev.show(v) } - implicit val stringShow: Show[String] = new Show[String] { + /** Adds escaping backslashes in a string so that it could be put in source code. + * For example, a newline character is shown as '\n' (without the quotes). + * Chars that don't have to be escaped are simply converted to a string. + * @param c the char to be escaped + * @return a string describing how to escape the give char in source code. + */ + private def escapeChar(c: Char): String = c match { // From 2.12 spec, `charEscapeSeq`: // ‘\‘ (‘b‘ | ‘t‘ | ‘n‘ | ‘f‘ | ‘r‘ | ‘"‘ | ‘'‘ | ‘\‘) - def show(str: String) = { - val sb = new StringBuilder - sb.append("\"") - str.foreach { - case '\b' => sb.append("\\b") - case '\t' => sb.append("\\t") - case '\n' => sb.append("\\n") - case '\f' => sb.append("\\f") - case '\r' => sb.append("\\r") - case '\'' => sb.append("\\'") - case '\"' => sb.append("\\\"") - case c => sb.append(c) - } - sb.append("\"") - sb.toString - } + case '\b' => "\\b" + case '\t' => "\\t" + case '\n' => "\\n" + case '\f' => "\\f" + case '\r' => "\\r" + case '\'' => "\\'" + case '\"' => "\\\"" + case '\\' => "\\\\" + case c => c.toString + } + + implicit val stringShow: Show[String] = new Show[String] { + def show(str: String) = str.flatMap(escapeChar).mkString("\"", "", "\"") } implicit val floatShow: Show[Float] = new Show[Float] { @@ -46,16 +49,7 @@ object Show extends LowPrioShow { } implicit val charShow: Show[Char] = new Show[Char] { - def show(c: Char) = "'" + (c match { - case '\b' => "\\b" - case '\t' => "\\t" - case '\n' => "\\n" - case '\f' => "\\f" - case '\r' => "\\r" - case '\'' => "\\'" - case '\"' => "\\\"" - case c => c - }) + "'" + def show(c: Char) = s"'${escapeChar(c)}'" } implicit def showList[T](implicit st: Show[T]): Show[List[T]] = new Show[List[T]] { diff --git a/library/test/dotty/ShowTests.scala b/library/test/dotty/ShowTests.scala index d114f62881a2..b7f41b2866a0 100644 --- a/library/test/dotty/ShowTests.scala +++ b/library/test/dotty/ShowTests.scala @@ -7,10 +7,11 @@ class ShowTests { import Show._ @Test def showString = { + assertEquals(""""\\"""", "\\".show) assertEquals("\"\\thello world!\"", "\thello world!".show) assertEquals("\"\\nhello world!\"", "\nhello world!".show) assertEquals("\"\\rhello world!\"", "\rhello world!".show) - assertEquals("\"\\b\\t\\n\\f\\r\\\'\\\"\"", "\b\t\n\f\r\'\"".show) + assertEquals(""""\b\t\n\f\r\'\"\\"""", "\b\t\n\f\r\'\"\\".show) } @Test def showFloat = { @@ -31,6 +32,7 @@ class ShowTests { assertEquals("'\\r'", '\r'.show) assertEquals("'\\''", '\''.show) assertEquals("'\\\"'", '\"'.show) + assertEquals("'\\\\'", '\\'.show) } @Test def showCar = {