@@ -22,64 +22,67 @@ class StringInterpolatorOpt extends MiniPhase {
22
22
override def phaseName : String = " stringInterpolatorOpt"
23
23
24
24
/** 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
+ }
43
34
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
+ }
70
43
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
+ }
85
88
}
0 commit comments