From ebe6f1ce8d9a9915fcbfd6f7773360e656989248 Mon Sep 17 00:00:00 2001 From: Jendrik Wenke Date: Mon, 12 Mar 2018 14:48:21 +0100 Subject: [PATCH 1/2] fix escaping backslash for char and string show --- library/src/dotty/Show.scala | 46 +++++++++++++----------------- library/test/dotty/ShowTests.scala | 4 ++- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/library/src/dotty/Show.scala b/library/src/dotty/Show.scala index 0a1bfd89d8a0..f57d6c0e0ac8 100644 --- a/library/src/dotty/Show.scala +++ b/library/src/dotty/Show.scala @@ -20,25 +20,28 @@ object Show extends LowPrioShow { ev.show(v) } + /** 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 { + 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] { // 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 - } + 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 = { From 07d2bb6749786e7ec99c055d3318248f56a98378 Mon Sep 17 00:00:00 2001 From: Jendrik Wenke Date: Mon, 12 Mar 2018 17:14:12 +0100 Subject: [PATCH 2/2] move comment to escapeChar --- library/src/dotty/Show.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/src/dotty/Show.scala b/library/src/dotty/Show.scala index f57d6c0e0ac8..42f7953cd528 100644 --- a/library/src/dotty/Show.scala +++ b/library/src/dotty/Show.scala @@ -27,6 +27,8 @@ object Show extends LowPrioShow { * @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‘ | ‘"‘ | ‘'‘ | ‘\‘) case '\b' => "\\b" case '\t' => "\\t" case '\n' => "\\n" @@ -39,8 +41,6 @@ object Show extends LowPrioShow { } implicit val stringShow: Show[String] = new Show[String] { - // From 2.12 spec, `charEscapeSeq`: - // ‘\‘ (‘b‘ | ‘t‘ | ‘n‘ | ‘f‘ | ‘r‘ | ‘"‘ | ‘'‘ | ‘\‘) def show(str: String) = str.flatMap(escapeChar).mkString("\"", "", "\"") }