Skip to content

Commit 0d8a423

Browse files
committed
wip
1 parent c56508c commit 0d8a423

File tree

1 file changed

+61
-58
lines changed

1 file changed

+61
-58
lines changed

compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala

Lines changed: 61 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -22,64 +22,67 @@ class StringInterpolatorOpt extends MiniPhase {
2222
override def phaseName: String = "stringInterpolatorOpt"
2323

2424
/** Matches a list of constant literals */
25-
// private object Literals {
26-
// def unapply(tree: SeqLiteral)(implicit ctx: Context): Option[List[Literal]] = {
27-
// tree.elems match {
28-
// case literals if literals.forall(_.isInstanceOf[Literal]) =>
29-
// Some(literals.map(_.asInstanceOf[Literal]))
30-
// case _ => None
31-
// }
32-
// }
33-
// }
34-
//
35-
// private object StringContextApply {
36-
// def unapply(tree: Select)(implicit ctx: Context): Boolean = {
37-
// tree.symbol.eq(defn.StringContextModule_apply) && {
38-
// val qualifier = tree.qualifier
39-
// qualifier.isInstanceOf[Ident] && qualifier.symbol.eq(defn.StringContextModule)
40-
// }
41-
// }
42-
// }
25+
private object Literals {
26+
def unapply(tree: SeqLiteral)(implicit ctx: Context): Option[List[Literal]] = {
27+
tree.elems match {
28+
case literals if literals.forall(_.isInstanceOf[Literal]) =>
29+
Some(literals.map(_.asInstanceOf[Literal]))
30+
case _ => None
31+
}
32+
}
33+
}
4334

44-
// override def transformApply(tree: Apply)(implicit ctx: Context): Tree = {
45-
// /** Matches an s or raw string interpolator */
46-
// if (tree.symbol.eq(defn.StringContextRaw) || tree.symbol.eq(defn.StringContextS)) {
47-
// tree match {
48-
// case Apply(Select(Apply(StringContextApply(), List(Literals(strs))), _),
49-
// List(SeqLiteral(elems, _))) if elems.length == strs.length - 1 =>
50-
// /** Match trees that resemble s and raw string interpolations. In the case of the s
51-
// * interpolator, escapes the string constants. Exposes the string constants as well as
52-
// * the variable references.
53-
// */
54-
// if (tree.symbol == defn.StringContextRaw) interpolate(strs, elems)
55-
// else { // tree.symbol == defn.StringContextS
56-
// try {
57-
// val escapedStrs = strs.map { str =>
58-
// val escapedValue = StringContext.processEscapes(str.const.stringValue)
59-
// cpy.Literal(str)(Constant(escapedValue))
60-
// }
61-
// interpolate(escapedStrs, elems)
62-
// } catch {
63-
// case _: StringContext.InvalidEscapeException => tree
64-
// }
65-
// }
66-
// case _ => tree
67-
// }
68-
// } else tree
69-
// }
35+
private object StringContextApply {
36+
def unapply(tree: Select)(implicit ctx: Context): Boolean = {
37+
tree.symbol.eq(defn.StringContextModule_apply) && {
38+
val qualifier = tree.qualifier
39+
qualifier.isInstanceOf[Ident] && qualifier.symbol.eq(defn.StringContextModule)
40+
}
41+
}
42+
}
7043

71-
// private def interpolate(strs: List[Literal], elems: List[Tree])(implicit ctx: Context): Tree = {
72-
// val stri = strs.iterator
73-
// val elemi = elems.iterator
74-
// var result: Tree = stri.next
75-
// def concat(tree: Tree): Unit = {
76-
// result = result.select(defn.String_+).appliedTo(tree)
77-
// }
78-
// while (elemi.hasNext) {
79-
// concat(elemi.next)
80-
// val str = stri.next
81-
// if (!str.const.stringValue.isEmpty) concat(str)
82-
// }
83-
// result
84-
// }
44+
override def transformApply(tree: Apply)(implicit ctx: Context): Tree = {
45+
val sym = tree.symbol
46+
if (sym.ne(defn.StringContextS) && sym.ne(defn.StringContextRaw)) tree
47+
else transformStringInterpolator(tree)
48+
}
49+
50+
private def transformStringInterpolator(tree: Tree)(implicit ctx: Context): Tree = {
51+
tree match {
52+
case Apply(Select(Apply(StringContextApply(), List(Literals(strs))), _),
53+
List(SeqLiteral(elems, _))) if elems.length == strs.length - 1 =>
54+
/** Match trees that resemble s and raw string interpolations. In the case of the s
55+
* interpolator, escapes the string constants. Exposes the string constants as well as
56+
* the variable references.
57+
*/
58+
if (tree.symbol == defn.StringContextRaw) interpolate(strs, elems)
59+
else { // tree.symbol == defn.StringContextS
60+
try {
61+
val escapedStrs = strs.map { str =>
62+
val escapedValue = StringContext.processEscapes(str.const.stringValue)
63+
cpy.Literal(str)(Constant(escapedValue))
64+
}
65+
interpolate(escapedStrs, elems)
66+
} catch {
67+
case _: StringContext.InvalidEscapeException => tree
68+
}
69+
}
70+
case _ => tree
71+
}
72+
}
73+
74+
private def interpolate(strs: List[Literal], elems: List[Tree])(implicit ctx: Context): Tree = {
75+
val stri = strs.iterator
76+
val elemi = elems.iterator
77+
var result: Tree = stri.next
78+
def concat(tree: Tree): Unit = {
79+
result = result.select(defn.String_+).appliedTo(tree)
80+
}
81+
while (elemi.hasNext) {
82+
concat(elemi.next)
83+
val str = stri.next
84+
if (!str.const.stringValue.isEmpty) concat(str)
85+
}
86+
result
87+
}
8588
}

0 commit comments

Comments
 (0)