@@ -117,55 +117,57 @@ class StringInterpolatorOpt extends MiniPhase {
117
117
}
118
118
119
119
override def transformApply (tree : Apply )(using Context ): Tree = {
120
+ def mkConcat (strs : List [Literal ], elems : List [Tree ]): Tree =
121
+ val stri = strs.iterator
122
+ val elemi = elems.iterator
123
+ var result : Tree = stri.next
124
+ def concat (tree : Tree ): Unit =
125
+ result = result.select(defn.String_+ ).appliedTo(tree).withSpan(tree.span)
126
+ while elemi.hasNext
127
+ do
128
+ concat(elemi.next)
129
+ val str = stri.next
130
+ if ! str.const.stringValue.isEmpty then concat(str)
131
+ result
132
+ end mkConcat
120
133
val sym = tree.symbol
121
- val isInterpolatedMethod = // Test names first to avoid loading scala.StringContext if not used
122
- (sym.name == nme.raw_ && sym.eq(defn.StringContext_raw )) ||
123
- (sym.name == nme.f && sym.eq(defn.StringContext_f )) ||
124
- (sym.name == nme.s && sym.eq(defn.StringContext_s ))
134
+ // Test names first to avoid loading scala.StringContext if not used, and common names first
135
+ val isInterpolatedMethod =
136
+ sym.name match
137
+ case nme.s => sym eq defn.StringContext_s
138
+ case nme.raw_ => sym eq defn.StringContext_raw
139
+ case nme.f => sym eq defn.StringContext_f
140
+ case _ => false
125
141
def transformF (fun : Tree , args : Tree ): Tree =
126
142
val (parts1, args1) = FormatInterpolatorTransform .checked(fun, args)
127
143
resolveConstructor(defn.StringOps .typeRef, List (parts1))
128
144
.select(nme.format)
129
145
.appliedTo(args1)
130
- if (isInterpolatedMethod)
131
- (tree : @ unchecked) match {
146
+ // Starting with Scala 2.13, s and raw are macros in the standard
147
+ // library, so we need to expand them manually.
148
+ // sc.s(args) --> standardInterpolator(processEscapes, args, sc.parts)
149
+ // sc.raw(args) --> standardInterpolator(x => x, args, sc.parts)
150
+ def transformS (fun : Tree , args : Tree , isRaw : Boolean ): Tree =
151
+ val pre = fun match
152
+ case Select (pre, _) => pre
153
+ case intp : Ident => tpd.desugarIdentPrefix(intp)
154
+ val stringToString = defn.StringContextModule_processEscapes .info.asInstanceOf [MethodType ]
155
+ val process = tpd.Lambda (stringToString, args =>
156
+ if isRaw then args.head else ref(defn.StringContextModule_processEscapes ).appliedToTermArgs(args)
157
+ )
158
+ evalOnce(pre) { sc =>
159
+ val parts = sc.select(defn.StringContext_parts )
160
+ ref(defn.StringContextModule_standardInterpolator )
161
+ .appliedToTermArgs(List (process, args, parts))
162
+ }
163
+ end transformS
164
+ if isInterpolatedMethod then
165
+ (tree : @ unchecked) match
132
166
case StringContextIntrinsic (strs : List [Literal ], elems : List [Tree ]) =>
133
- val stri = strs.iterator
134
- val elemi = elems.iterator
135
- var result : Tree = stri.next
136
- def concat (tree : Tree ): Unit = {
137
- result = result.select(defn.String_+ ).appliedTo(tree).withSpan(tree.span)
138
- }
139
- while (elemi.hasNext) {
140
- concat(elemi.next)
141
- val str = stri.next
142
- if (! str.const.stringValue.isEmpty) concat(str)
143
- }
144
- result
145
- case Apply (intp, args :: Nil ) if sym.eq(defn.StringContext_f ) =>
146
- transformF(intp, args)
147
- // Starting with Scala 2.13, s and raw are macros in the standard
148
- // library, so we need to expand them manually.
149
- // sc.s(args) --> standardInterpolator(processEscapes, args, sc.parts)
150
- // sc.raw(args) --> standardInterpolator(x => x, args, sc.parts)
167
+ mkConcat(strs, elems)
151
168
case Apply (intp, args :: Nil ) =>
152
- val pre = intp match {
153
- case Select (pre, _) => pre
154
- case intp : Ident => tpd.desugarIdentPrefix(intp)
155
- }
156
- val isRaw = sym eq defn.StringContext_raw
157
- val stringToString = defn.StringContextModule_processEscapes .info.asInstanceOf [MethodType ]
158
-
159
- val process = tpd.Lambda (stringToString, args =>
160
- if (isRaw) args.head else ref(defn.StringContextModule_processEscapes ).appliedToTermArgs(args))
161
-
162
- evalOnce(pre) { sc =>
163
- val parts = sc.select(defn.StringContext_parts )
164
-
165
- ref(defn.StringContextModule_standardInterpolator )
166
- .appliedToTermArgs(List (process, args, parts))
167
- }
168
- }
169
+ if sym eq defn.StringContext_f then transformF(intp, args)
170
+ else transformS(intp, args, isRaw = sym eq defn.StringContext_raw )
169
171
else
170
172
tree.tpe match
171
173
case _ : ConstantType => tree
0 commit comments