Skip to content

Commit 0ee13ca

Browse files
committed
Inline extractors to avoid indirection to sym checks
1 parent eb4d2c8 commit 0ee13ca

File tree

1 file changed

+26
-43
lines changed

1 file changed

+26
-43
lines changed

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

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -41,62 +41,45 @@ class StringInterpolatorOpt extends MiniPhase {
4141
}
4242
}
4343

44-
/** Matches an s or raw string interpolator */
45-
private object SOrRawInterpolator {
46-
def unapply(tree: Tree)(implicit ctx: Context): Option[(List[Literal], List[Tree])] = {
47-
if (tree.symbol.eq(defn.StringContextRaw) || tree.symbol.eq(defn.StringContextS)) {
48-
tree match {
49-
case Apply(Select(Apply(StringContextApply(), List(Literals(strs))), _),
50-
List(SeqLiteral(elems, _))) if elems.length == strs.length - 1 =>
51-
Some(strs, elems)
52-
case _ => None
53-
}
54-
} else None
55-
}
56-
}
57-
58-
/**
59-
* Match trees that resemble s and raw string interpolations. In the case of the s
60-
* interpolator, escapes the string constants. Exposes the string constants as well as
61-
* the variable references.
62-
*/
63-
private object StringContextIntrinsic {
64-
def unapply(tree: Apply)(implicit ctx: Context): Option[(List[Literal], List[Tree])] = {
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)) {
6547
tree match {
66-
case SOrRawInterpolator(strs, elems) =>
67-
if (tree.symbol == defn.StringContextRaw) Some(strs, elems)
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)
6855
else { // tree.symbol == defn.StringContextS
6956
try {
7057
val escapedStrs = strs.map { str =>
7158
val escapedValue = StringContext.processEscapes(str.const.stringValue)
7259
cpy.Literal(str)(Constant(escapedValue))
7360
}
74-
Some(escapedStrs, elems)
61+
interpolate(escapedStrs, elems)
7562
} catch {
76-
case _: StringContext.InvalidEscapeException => None
63+
case _: StringContext.InvalidEscapeException => tree
7764
}
7865
}
79-
case _ => None
66+
case _ => tree
8067
}
81-
}
68+
} else tree
8269
}
8370

84-
override def transformApply(tree: Apply)(implicit ctx: Context): Tree = {
85-
tree match {
86-
case StringContextIntrinsic(strs: List[Literal], elems: List[Tree]) =>
87-
val stri = strs.iterator
88-
val elemi = elems.iterator
89-
var result: Tree = stri.next
90-
def concat(tree: Tree): Unit = {
91-
result = result.select(defn.String_+).appliedTo(tree)
92-
}
93-
while (elemi.hasNext) {
94-
concat(elemi.next)
95-
val str = stri.next
96-
if (!str.const.stringValue.isEmpty) concat(str)
97-
}
98-
result
99-
case _ => tree
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)
10082
}
83+
result
10184
}
10285
}

0 commit comments

Comments
 (0)