Skip to content

Commit 67fe08d

Browse files
authored
Merge pull request #4107 from jendrikw/fix-char-show
Fix #3788 escape backslash for char and string show
2 parents b294b6c + 07d2bb6 commit 67fe08d

File tree

2 files changed

+24
-28
lines changed

2 files changed

+24
-28
lines changed

library/src/dotty/Show.scala

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,42 +20,36 @@ object Show extends LowPrioShow {
2020
ev.show(v)
2121
}
2222

23-
implicit val stringShow: Show[String] = new Show[String] {
23+
/** Adds escaping backslashes in a string so that it could be put in source code.
24+
* For example, a newline character is shown as '\n' (without the quotes).
25+
* Chars that don't have to be escaped are simply converted to a string.
26+
* @param c the char to be escaped
27+
* @return a string describing how to escape the give char in source code.
28+
*/
29+
private def escapeChar(c: Char): String = c match {
2430
// From 2.12 spec, `charEscapeSeq`:
2531
// ‘\‘ (‘b‘ | ‘t‘ | ‘n‘ | ‘f‘ | ‘r‘ | ‘"‘ | ‘'‘ | ‘\‘)
26-
def show(str: String) = {
27-
val sb = new StringBuilder
28-
sb.append("\"")
29-
str.foreach {
30-
case '\b' => sb.append("\\b")
31-
case '\t' => sb.append("\\t")
32-
case '\n' => sb.append("\\n")
33-
case '\f' => sb.append("\\f")
34-
case '\r' => sb.append("\\r")
35-
case '\'' => sb.append("\\'")
36-
case '\"' => sb.append("\\\"")
37-
case c => sb.append(c)
38-
}
39-
sb.append("\"")
40-
sb.toString
41-
}
32+
case '\b' => "\\b"
33+
case '\t' => "\\t"
34+
case '\n' => "\\n"
35+
case '\f' => "\\f"
36+
case '\r' => "\\r"
37+
case '\'' => "\\'"
38+
case '\"' => "\\\""
39+
case '\\' => "\\\\"
40+
case c => c.toString
41+
}
42+
43+
implicit val stringShow: Show[String] = new Show[String] {
44+
def show(str: String) = str.flatMap(escapeChar).mkString("\"", "", "\"")
4245
}
4346

4447
implicit val floatShow: Show[Float] = new Show[Float] {
4548
def show(f: Float) = f + "f"
4649
}
4750

4851
implicit val charShow: Show[Char] = new Show[Char] {
49-
def show(c: Char) = "'" + (c match {
50-
case '\b' => "\\b"
51-
case '\t' => "\\t"
52-
case '\n' => "\\n"
53-
case '\f' => "\\f"
54-
case '\r' => "\\r"
55-
case '\'' => "\\'"
56-
case '\"' => "\\\""
57-
case c => c
58-
}) + "'"
52+
def show(c: Char) = s"'${escapeChar(c)}'"
5953
}
6054

6155
implicit def showList[T](implicit st: Show[T]): Show[List[T]] = new Show[List[T]] {

library/test/dotty/ShowTests.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ class ShowTests {
77
import Show._
88

99
@Test def showString = {
10+
assertEquals(""""\\"""", "\\".show)
1011
assertEquals("\"\\thello world!\"", "\thello world!".show)
1112
assertEquals("\"\\nhello world!\"", "\nhello world!".show)
1213
assertEquals("\"\\rhello world!\"", "\rhello world!".show)
13-
assertEquals("\"\\b\\t\\n\\f\\r\\\'\\\"\"", "\b\t\n\f\r\'\"".show)
14+
assertEquals(""""\b\t\n\f\r\'\"\\"""", "\b\t\n\f\r\'\"\\".show)
1415
}
1516

1617
@Test def showFloat = {
@@ -31,6 +32,7 @@ class ShowTests {
3132
assertEquals("'\\r'", '\r'.show)
3233
assertEquals("'\\''", '\''.show)
3334
assertEquals("'\\\"'", '\"'.show)
35+
assertEquals("'\\\\'", '\\'.show)
3436
}
3537

3638
@Test def showCar = {

0 commit comments

Comments
 (0)