Repository: scalameta/scalameta (scala)

Issue:
`.syntax` creates invalid Scala code for string literals that contains \"\"\"
Scalameta version: 4.7.3

```scala
import scala.meta._
object Main extends App {
  println(Lit.String("\n\"\"\"").syntax)
}
```

Expected output:
```
"\n\"\"\""
```
Actual output:
```
"""
""""""
```

https://scastie.scala-lang.org/0Xe1ehUxRwiI0Ifr4YrAyw

Pull request description:
Fixes #3065.

Patch:
diff --git a/scalameta/common/shared/src/main/scala/scala/meta/internal/prettyprinters/Enquote.scala b/scalameta/common/shared/src/main/scala/scala/meta/internal/prettyprinters/Enquote.scala
index 65cf264912..1ab5d054da 100644
--- a/scalameta/common/shared/src/main/scala/scala/meta/internal/prettyprinters/Enquote.scala
+++ b/scalameta/common/shared/src/main/scala/scala/meta/internal/prettyprinters/Enquote.scala
@@ -2,6 +2,8 @@ package scala.meta
 package internal
 package prettyprinters
 
+import scala.annotation.tailrec
+
 sealed trait QuoteStyle
 case object SingleQuotes extends QuoteStyle { override def toString = "'" }
 case object DoubleQuotes extends QuoteStyle { override def toString = "\"" }
@@ -9,10 +11,21 @@ case object TripleQuotes extends QuoteStyle { override def toString = "\"\"\"" }
 
 object enquote {
   def apply(s: String, style: QuoteStyle): String = {
-    val sb = new StringBuilder(style.toString)
-    if (style == TripleQuotes)
-      sb.append(s)
-    else {
+    val styleStr = style.toString
+    val sb = new java.lang.StringBuilder(styleStr)
+    if (style == TripleQuotes) {
+      val styleLen = styleStr.length
+      @tailrec def iter(off: Int): Unit = {
+        val newoff = s.indexOf(styleStr, off)
+        if (newoff < 0) sb.append(s, off, s.length)
+        else {
+          sb.append(s, off, newoff)
+          sb.append("\\\"\\\"\\\"")
+          iter(newoff + styleLen)
+        }
+      }
+      iter(0)
+    } else {
       s.foreach {
         case '\t' => sb.append("\\t")
         case '\b' => sb.append("\\b")
@@ -30,7 +43,7 @@ object enquote {
           else sb.append(c)
       }
     }
-    sb.append(style.toString)
+    sb.append(styleStr)
     sb.toString
   }
 }


Test patch:
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 3fb389872c..efbb1c6246 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
@@ -1926,4 +1926,9 @@ class SyntacticSuite extends scala.meta.tests.parsers.ParseSuite {
     }
   }
 
+  test("#3065 embedded triple quotes") {
+    val tree = Lit.String("\n\"\"\"")
+    assertSyntax(tree, "\"\"\"\n\\\"\\\"\\\"\"\"\"")(tree)
+  }
+
 }