Skip to content

Commit 8b91da5

Browse files
committed
Inline extra object to StringInterpOpt
1 parent 436504c commit 8b91da5

File tree

2 files changed

+29
-40
lines changed

2 files changed

+29
-40
lines changed

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

Lines changed: 0 additions & 39 deletions
This file was deleted.

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

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,38 @@ class StringInterpolatorOpt extends MiniPhase:
137137
case _ => false
138138
// Perform format checking and normalization, then make it StringOps(fmt).format(args1) with tweaked args
139139
def transformF(fun: Tree, args: Tree): Tree =
140-
val (fmt, args1) = FormatInterpolatorTransform.checked(fun, args)
140+
// For f"${arg}%xpart", check format conversions and return (format, args) for String.format(format, args).
141+
def checked(args0: Tree)(using Context): (Tree, Tree) =
142+
val (partsExpr, parts) = fun match
143+
case TypeApply(Select(Apply(_, (parts: SeqLiteral) :: Nil), _), _) =>
144+
(parts.elems, parts.elems.map { case Literal(Constant(s: String)) => s })
145+
case _ =>
146+
report.error("Expected statically known StringContext", fun.srcPos)
147+
(Nil, Nil)
148+
val (args, elemtpt) = args0 match
149+
case seqlit: SeqLiteral => (seqlit.elems, seqlit.elemtpt)
150+
case _ =>
151+
report.error("Expected statically known argument list", args0.srcPos)
152+
(Nil, EmptyTree)
153+
154+
def literally(s: String) = Literal(Constant(s))
155+
if parts.lengthIs != args.length + 1 then
156+
val badParts =
157+
if parts.isEmpty then "there are no parts"
158+
else s"too ${if parts.lengthIs > args.length + 1 then "few" else "many"} arguments for interpolated string"
159+
report.error(badParts, fun.srcPos)
160+
(literally(""), args0)
161+
else
162+
val checker = TypedFormatChecker(partsExpr, parts, args)
163+
val (format, formatArgs) = checker.checked
164+
if format.isEmpty then (literally(parts.mkString), args0) // on error just use unchecked inputs
165+
else (literally(format.mkString), SeqLiteral(formatArgs.toList, elemtpt))
166+
end checked
167+
val (fmt, args1) = checked(args)
141168
resolveConstructor(defn.StringOps.typeRef, List(fmt))
142169
.select(nme.format)
143170
.appliedTo(args1)
171+
end transformF
144172
// Starting with Scala 2.13, s and raw are macros in the standard
145173
// library, so we need to expand them manually.
146174
// sc.s(args) --> standardInterpolator(processEscapes, args, sc.parts)

0 commit comments

Comments
 (0)