Skip to content

Commit 1fd69f1

Browse files
som-snytttgodzik
authored andcommitted
Inline extra object to StringInterpOpt
[Cherry-picked ed63fe8]
1 parent d22a5f1 commit 1fd69f1

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

0 commit comments

Comments
 (0)