@@ -19,20 +19,22 @@ class StringInterpolatorOpt extends MiniPhase {
19
19
private object StringContextIntrinsic {
20
20
def unapply (tree : Apply )(implicit ctx : Context ): Option [(List [Tree ], List [Tree ])] = {
21
21
tree match {
22
- case Apply (Select (Apply (Select (Ident (nme.StringContext ), nme.apply),
23
- List (SeqLiteral (strs, _))), id), List (SeqLiteral (elems, _))) =>
24
- if (id == nme.raw_) Some (strs, elems)
25
- else if (id == nme.s) {
26
- try {
27
- val escapedStrs = strs.mapConserve { str =>
28
- val strValue = str.asInstanceOf [Literal ].const.stringValue
29
- val escapedValue = StringContext .processEscapes(strValue)
30
- cpy.Literal (str)(Constant (escapedValue))
22
+ case Apply (Select (Apply (Select (ident, nme.apply), List (SeqLiteral (strs, _))), fn),
23
+ List (SeqLiteral (elems, _))) =>
24
+ if (ident.symbol.eq(defn.StringContextClass ) && strs.forall(_.isInstanceOf [Literal ])) {
25
+ if (fn == nme.raw_) Some (strs, elems)
26
+ else if (fn == nme.s) {
27
+ try {
28
+ val escapedStrs = strs.mapConserve { str =>
29
+ val strValue = str.asInstanceOf [Literal ].const.stringValue
30
+ val escapedValue = StringContext .processEscapes(strValue)
31
+ cpy.Literal (str)(Constant (escapedValue))
32
+ }
33
+ Some (escapedStrs, elems)
34
+ } catch {
35
+ case _ : StringContext .InvalidEscapeException => None
31
36
}
32
- Some (escapedStrs, elems)
33
- } catch {
34
- case _ : StringContext .InvalidEscapeException => None
35
- }
37
+ } else None
36
38
} else None
37
39
case _ => None
38
40
}
@@ -42,17 +44,18 @@ class StringInterpolatorOpt extends MiniPhase {
42
44
override def transformApply (tree : Apply )(implicit ctx : Context ): Tree = {
43
45
tree match {
44
46
case StringContextIntrinsic (strs : List [Tree ], elems : List [Tree ]) =>
45
- val numLits = strs.length
46
- strs.tail.foldLeft((0 , strs.head)) { (acc : (Int , Tree ), str : Tree ) =>
47
- val (i, result) = acc
48
- val resultWithElem =
49
- if (i < numLits - 1 ) result.select(defn.String_+ ).appliedTo(elems(i))
50
- else result
51
- val resultWithStr =
52
- if (str.asInstanceOf [Literal ].const.stringValue.isEmpty) resultWithElem
53
- else resultWithElem.select(defn.String_+ ).appliedTo(str)
54
- (i + 1 , resultWithStr)
55
- }._2
47
+ val stri = strs.iterator
48
+ val elemi = elems.iterator
49
+ var result = stri.next
50
+ def concat (tree : Tree ): Unit = {
51
+ result = result.select(defn.String_+ ).appliedTo(tree)
52
+ }
53
+ while (elemi.hasNext) {
54
+ concat(elemi.next)
55
+ val str = stri.next
56
+ if (! str.asInstanceOf [Literal ].const.stringValue.isEmpty) concat(str)
57
+ }
58
+ result
56
59
case _ => tree
57
60
}
58
61
}
0 commit comments