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