Skip to content

Commit 2b8f5fa

Browse files
som-snytttgodzik
authored andcommitted
Relocate to Chars and share
1 parent 7e07fe4 commit 2b8f5fa

File tree

3 files changed

+64
-126
lines changed

3 files changed

+64
-126
lines changed

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 4 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,12 @@ import ast.Trees.*
1111
import typer.Implicits.*
1212
import typer.ImportInfo
1313
import Variances.varianceSign
14-
import util.SourcePosition
14+
import util.{Chars, SourcePosition}
1515
import scala.util.control.NonFatal
1616
import scala.annotation.switch
1717
import config.{Config, Feature}
1818
import cc.{CapturingType, EventuallyCapturingType, CaptureSet, isBoxed}
1919

20-
import java.lang.StringBuilder
21-
2220
class PlainPrinter(_ctx: Context) extends Printer {
2321

2422
/** The context of all public methods in Printer and subclasses.
@@ -581,18 +579,10 @@ class PlainPrinter(_ctx: Context) extends Printer {
581579

582580
def toText(denot: Denotation): Text = toText(denot.symbol) ~ "/D"
583581

584-
private def escapedChar(ch: Char): String =
585-
if requiresFormat(ch) then
586-
val b = StringBuilder().append('\'')
587-
escapedChar(b, ch)
588-
b.append('\'').toString
589-
else
590-
"'" + ch + "'"
591-
592582
def toText(const: Constant): Text = const.tag match {
593-
case StringTag => stringText(escapedString(const.value.toString, quoted = true))
583+
case StringTag => stringText(Chars.escapedString(const.value.toString, quoted = true))
594584
case ClazzTag => "classOf[" ~ toText(const.typeValue) ~ "]"
595-
case CharTag => literalText(escapedChar(const.charValue))
585+
case CharTag => literalText(Chars.escapedChar(const.charValue))
596586
case LongTag => literalText(const.longValue.toString + "L")
597587
case DoubleTag => literalText(const.doubleValue.toString + "d")
598588
case FloatTag => literalText(const.floatValue.toString + "f")
@@ -610,57 +600,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
610600
~ (if param.isTypeParam then "" else ": ")
611601
~ toText(param.paramInfo)
612602

613-
protected final def escapedString(str: String): String = escapedString(str, quoted = false)
614-
615-
private def requiresFormat(c: Char): Boolean = (c: @switch) match
616-
case '\b' | '\t' | '\n' | '\f' | '\r' | '"' | '\'' | '\\' => true
617-
case c => c.isControl
618-
619-
private def escapedString(text: String, quoted: Boolean): String =
620-
def mustBuild: Boolean =
621-
var i = 0
622-
while i < text.length do
623-
if requiresFormat(text.charAt(i)) then return true
624-
i += 1
625-
false
626-
if mustBuild then
627-
val b = StringBuilder(text.length + 16)
628-
if quoted then
629-
b.append('"')
630-
var i = 0
631-
while i < text.length do
632-
escapedChar(b, text.charAt(i))
633-
i += 1
634-
if quoted then
635-
b.append('"')
636-
b.toString
637-
else if quoted then "\"" + text + "\""
638-
else text
639-
640-
private def escapedChar(b: StringBuilder, c: Char): Unit =
641-
def quadNibble(b: StringBuilder, x: Int, i: Int): Unit =
642-
if i < 4 then
643-
quadNibble(b, x >> 4, i + 1)
644-
val n = x & 0xF
645-
val c = if (n < 10) '0' + n else 'a' + (n - 10)
646-
b.append(c.toChar)
647-
val replace = (c: @switch) match
648-
case '\b' => "\\b"
649-
case '\t' => "\\t"
650-
case '\n' => "\\n"
651-
case '\f' => "\\f"
652-
case '\r' => "\\r"
653-
case '"' => "\\\""
654-
case '\'' => "\\\'"
655-
case '\\' => "\\\\"
656-
case c =>
657-
if c.isControl then
658-
b.append("\\u")
659-
quadNibble(b, c.toInt, 0)
660-
else
661-
b.append(c)
662-
return
663-
b.append(replace)
603+
protected final def escapedString(str: String): String = Chars.escapedString(str, quoted = false)
664604

665605
def dclsText(syms: List[Symbol], sep: String): Text = Text(syms map dclText, sep)
666606

compiler/src/dotty/tools/dotc/util/Chars.scala

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ package dotty.tools.dotc.util
33
import scala.annotation.switch
44
import Character.{LETTER_NUMBER, LOWERCASE_LETTER, OTHER_LETTER, TITLECASE_LETTER, UPPERCASE_LETTER}
55
import Character.{MATH_SYMBOL, OTHER_SYMBOL}
6-
import Character.{isJavaIdentifierPart, isUnicodeIdentifierStart, isUnicodeIdentifierPart}
6+
import Character.{isISOControl as isControl, isJavaIdentifierPart, isUnicodeIdentifierStart, isUnicodeIdentifierPart}
7+
import java.lang.StringBuilder
78

89
/** Contains constants and classifier methods for characters */
910
object Chars:
@@ -110,3 +111,59 @@ object Chars:
110111

111112
/** Would the character be encoded by `NameTransformer.encode`? */
112113
def willBeEncoded(c: Char): Boolean = !isJavaIdentifierPart(c)
114+
115+
private inline def requiresFormat(c: Char): Boolean = (c: @switch) match
116+
case '\b' | '\t' | '\n' | '\f' | '\r' | '"' | '\'' | '\\' => true
117+
case c => isControl(c)
118+
119+
def escapedString(text: String, quoted: Boolean): String =
120+
inline def doBuild: String =
121+
val b = StringBuilder(text.length + 16)
122+
if quoted then
123+
b.append('"')
124+
var i = 0
125+
while i < text.length do
126+
escapedChar(b, text.charAt(i))
127+
i += 1
128+
if quoted then
129+
b.append('"')
130+
b.toString
131+
var i = 0
132+
while i < text.length do
133+
if requiresFormat(text.charAt(i)) then return doBuild
134+
i += 1
135+
if quoted then "\"" + text + "\""
136+
else text
137+
138+
def escapedChar(ch: Char): String =
139+
if requiresFormat(ch) then
140+
val b = StringBuilder().append('\'')
141+
escapedChar(b, ch)
142+
b.append('\'').toString
143+
else
144+
"'" + ch + "'"
145+
146+
private def escapedChar(b: StringBuilder, c: Char): Unit =
147+
inline def quadNibble(x: Int, i: Int): Unit =
148+
if i < 4 then
149+
quadNibble(x >> 4, i + 1)
150+
val n = x & 0xF
151+
val c = if (n < 10) '0' + n else 'a' + (n - 10)
152+
b.append(c.toChar)
153+
val replace = (c: @switch) match
154+
case '\b' => "\\b"
155+
case '\t' => "\\t"
156+
case '\n' => "\\n"
157+
case '\f' => "\\f"
158+
case '\r' => "\\r"
159+
case '"' => "\\\""
160+
case '\'' => "\\\'"
161+
case '\\' => "\\\\"
162+
case c =>
163+
if isControl(c) then
164+
b.append("\\u")
165+
quadNibble(c.toInt, 0)
166+
else
167+
b.append(c)
168+
return
169+
b.append(replace)

compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala

Lines changed: 2 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -962,9 +962,6 @@ object SourceCode {
962962

963963
}
964964

965-
inline private val qc = "\'"
966-
inline private val qSc = "\""
967-
968965
def printConstant(const: Constant): this.type = const match {
969966
case UnitConstant() => this += highlightLiteral("()")
970967
case NullConstant() => this += highlightLiteral("null")
@@ -975,8 +972,8 @@ object SourceCode {
975972
case LongConstant(v) => this += highlightLiteral(v.toString + "L")
976973
case FloatConstant(v) => this += highlightLiteral(v.toString + "f")
977974
case DoubleConstant(v) => this += highlightLiteral(v.toString)
978-
case CharConstant(v) => this += highlightString(escapedChar(v))
979-
case StringConstant(v) => this += highlightString(escapedString(v))
975+
case CharConstant(v) => this += highlightString(Chars.escapedChar(v))
976+
case StringConstant(v) => this += highlightString(Chars.escapedString(v, quoted = true))
980977
case ClassOfConstant(v) =>
981978
this += "classOf"
982979
inSquare(printType(v))
@@ -1449,62 +1446,6 @@ object SourceCode {
14491446
private def +=(x: Char): this.type = { sb.append(x); this }
14501447
private def +=(x: String): this.type = { sb.append(x); this }
14511448

1452-
private def escapedChar(ch: Char): String =
1453-
if requiresFormat(ch) then
1454-
val b = StringBuilder().append(qc)
1455-
escapedChar(b, ch)
1456-
b.append(qc).toString
1457-
else
1458-
qc + ch + qc
1459-
1460-
private def escapedChar(b: StringBuilder, c: Char): Unit =
1461-
def quadNibble(b: StringBuilder, x: Int, i: Int): Unit =
1462-
if i < 4 then
1463-
quadNibble(b, x >> 4, i + 1)
1464-
val n = x & 0xF
1465-
val c = if (n < 10) '0' + n else 'a' + (n - 10)
1466-
b.append(c.toChar)
1467-
val replace = (c: @switch) match
1468-
case '\b' => "\\b"
1469-
case '\t' => "\\t"
1470-
case '\n' => "\\n"
1471-
case '\f' => "\\f"
1472-
case '\r' => "\\r"
1473-
case '"' => "\\\""
1474-
case '\'' => "\\\'"
1475-
case '\\' => "\\\\"
1476-
case c =>
1477-
if c.isControl then
1478-
b.append("\\u")
1479-
quadNibble(b, c.toInt, 0)
1480-
else
1481-
b.append(c)
1482-
return
1483-
b.append(replace)
1484-
1485-
private def requiresFormat(c: Char): Boolean = (c: @switch) match
1486-
case '\b' | '\t' | '\n' | '\f' | '\r' | '"' | '\'' | '\\' => true
1487-
case c => c.isControl
1488-
1489-
private def escapedString(text: String): String =
1490-
def mustBuild: Boolean =
1491-
var i = 0
1492-
while i < text.length do
1493-
if requiresFormat(text.charAt(i)) then return true
1494-
i += 1
1495-
false
1496-
if mustBuild then
1497-
val b = StringBuilder(text.length + 16)
1498-
b.append(qSc)
1499-
var i = 0
1500-
while i < text.length do
1501-
escapedChar(b, text.charAt(i))
1502-
i += 1
1503-
b.append(qSc)
1504-
b.toString
1505-
else
1506-
qSc + text + qSc
1507-
15081449
private val names = collection.mutable.Map.empty[Symbol, String]
15091450
private val namesIndex = collection.mutable.Map.empty[String, Int]
15101451

0 commit comments

Comments
 (0)