Repository: scalameta/scalameta (scala)

Issue:
Lit.String and Lit.Char format is not preserved
Obtained:

```scala
import scala.meta._
"\"\\n\"".parse[Term].get.asInstanceOf[Lit.String].value
res31: String =
"
"
"\'\\n\'".parse[Term].get.asInstanceOf[Lit.Char].value
res33: Char =


```

Expected:

```scala
import scala.meta._
"\"\\n\"".parse[Term].get.asInstanceOf[Lit.String].value == "\\n"
"\'\\n\'".parse[Term].get.asInstanceOf[Lit.Char].value == "\\n"
```

Pull request:
Fixes #1384.

Patch:
diff --git a/scalameta/trees/shared/src/main/scala/scala/meta/internal/prettyprinters/TreeSyntax.scala b/scalameta/trees/shared/src/main/scala/scala/meta/internal/prettyprinters/TreeSyntax.scala
index bc8aa9c359..3f16814ca4 100644
--- a/scalameta/trees/shared/src/main/scala/scala/meta/internal/prettyprinters/TreeSyntax.scala
+++ b/scalameta/trees/shared/src/main/scala/scala/meta/internal/prettyprinters/TreeSyntax.scala
@@ -819,13 +819,19 @@ object TreeSyntax {
               s(value, "d")
           }
         }
-      case Lit.Char(value) => m(Literal, s(enquote(value.toString, SingleQuotes)))
-      // Strings should be triple-quoted regardless of what newline style is used.
-      case Lit.String(value) =>
-        m(
-          Literal,
-          s(enquote(value.toString, if (value.contains("\n")) TripleQuotes else DoubleQuotes))
-        )
+      case t @ Lit.Char(value) =>
+        val syntax = t.pos match {
+          case Position.None => enquote(value.toString, SingleQuotes)
+          case pos => pos.text
+        }
+        m(Literal, s(syntax))
+      case t @ Lit.String(value) =>
+        val syntax = t.pos match {
+          case Position.None =>
+            enquote(value, if (value.contains('\n')) TripleQuotes else DoubleQuotes)
+          case pos => pos.text
+        }
+        m(Literal, s(syntax))
       case Lit.Symbol(value) => m(Literal, s("'", value.name))
       case Lit.Null() => m(Literal, s(kw("null")))
       case Lit.Unit() => m(Literal, s("()"))


Test patch:
diff --git a/tests/shared/src/test/scala/scala/meta/tests/parsers/TermSuite.scala b/tests/shared/src/test/scala/scala/meta/tests/parsers/TermSuite.scala
index 52fd4e4668..dc98d6de24 100644
--- a/tests/shared/src/test/scala/scala/meta/tests/parsers/TermSuite.scala
+++ b/tests/shared/src/test/scala/scala/meta/tests/parsers/TermSuite.scala
@@ -10,6 +10,10 @@ class TermSuite extends ParseSuite {
     assertTree(term(expr))(tree)
   }
 
+  private def checkTerm(expr: String, syntax: String = null)(tree: Tree): Unit = {
+    checkTree(term(expr), syntax)(tree)
+  }
+
   test("x") {
     assertTerm("x") {
       Term.Name("x")
@@ -1371,4 +1375,16 @@ class TermSuite extends ParseSuite {
     )
   }
 
+  test("#1384 string") {
+    val tq = "\"" * 3
+    val exprDq = raw"""("\n", "bar\n", "\nbaz")"""
+    val exprTq = s"""($tq\n$tq, ${tq}bar\n$tq, $tq\nbaz$tq)"""
+    checkTerm(exprDq, exprDq)(
+      Term.Tuple(List(Lit.String("\n"), Lit.String("bar\n"), Lit.String("\nbaz")))
+    )
+    checkTerm(exprTq, exprTq)(
+      Term.Tuple(List(Lit.String("\n"), Lit.String("bar\n"), Lit.String("\nbaz")))
+    )
+  }
+
 }
diff --git a/tests/shared/src/test/scala/scala/meta/tests/prettyprinters/SyntacticSuite.scala b/tests/shared/src/test/scala/scala/meta/tests/prettyprinters/SyntacticSuite.scala
index fc801dcd31..b18c47afcc 100644
--- a/tests/shared/src/test/scala/scala/meta/tests/prettyprinters/SyntacticSuite.scala
+++ b/tests/shared/src/test/scala/scala/meta/tests/prettyprinters/SyntacticSuite.scala
@@ -3,6 +3,7 @@ package prettyprinters
 
 import scala.meta._
 import scala.meta.dialects.Scala211
+import scala.meta.internal.tokens._
 import scala.meta.internal.trees._
 import scala.meta.prettyprinters.Show
 
@@ -1651,10 +1652,19 @@ class SyntacticSuite extends scala.meta.tests.parsers.ParseSuite {
   }
 
   test("#1384 char ok escaped LF") {
-    val expr = "('\\n', '\\u000a')"
+    val exprU = "'\\u000a'"
+    val expr = s"('\\n', $exprU)"
+    val syntax = "('\\n', '\\n')"
     val tree = super.term(expr)
-    assertNoDiff(tree.syntax, expr)
-    assertNoDiff(tree.resetAllOrigins.syntax, "('\\n', '\\n')")
+    val charN = Lit.Char('\n')
+    val origin = Origin.Parsed(Input.String(exprU), implicitly[Dialect], TokenStreamPosition(1, 2))
+    val charU = charN.withOrigin(origin)
+    checkTree(tree, expr) {
+      Term.Tuple(List(charN, charU))
+    }
+    checkTree(tree.resetAllOrigins, syntax) {
+      Term.Tuple(List(charN, charN))
+    }
   }
 
 }