Skip to content

Commit 491fbe9

Browse files
committed
Do Text construction via extension methods
Do Text construction via extension methods in class Printer. This refactoring is a necssary first step to be able to implement output throttling to avoid error messages that become too large.
1 parent 3cbc53e commit 491fbe9

File tree

10 files changed

+78
-62
lines changed

10 files changed

+78
-62
lines changed

compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
631631
// ---------- toText -----------------------------------------------------
632632

633633
override def toText(printer: Printer): Text = {
634+
import printer.{~, concat, lines}
634635
def entryText(tp: Type) = tp match {
635636
case tp: TypeBounds =>
636637
tp.toText(printer)
@@ -640,15 +641,15 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
640641
val indent = 3
641642
val header: Text = "Constraint("
642643
val uninstVarsText = " uninstVars = " ~
643-
Text(uninstVars map (_.toText(printer)), ", ") ~ ";"
644+
concat(uninstVars map (_.toText(printer)), ", ") ~ ";"
644645
val constrainedText =
645-
" constrained types = " ~ Text(domainLambdas map (_.toText(printer)), ", ")
646+
" constrained types = " ~ concat(domainLambdas map (_.toText(printer)), ", ")
646647
val boundsText =
647648
" bounds = " ~ {
648649
val assocs =
649650
for (param <- domainParams)
650651
yield (" " * indent) ~ param.toText(printer) ~ entryText(entry(param))
651-
Text(assocs, "\n")
652+
concat(assocs, "\n")
652653
}
653654
val orderingText =
654655
" ordering = " ~ {
@@ -660,10 +661,10 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
660661
}
661662
yield
662663
(" " * indent) ~ param.toText(printer) ~ " <: " ~
663-
Text(ups.map(_.toText(printer)), ", ")
664-
Text(deps, "\n")
664+
concat(ups.map(_.toText(printer)), ", ")
665+
concat(deps, "\n")
665666
}
666-
Text.lines(List(header, uninstVarsText, constrainedText, boundsText, orderingText, ")"))
667+
lines(List(header, uninstVarsText, constrainedText, boundsText, orderingText, ")"))
667668
}
668669

669670
override def toString: String = {

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5233,6 +5233,7 @@ object Types {
52335233
assert(!hi.isInstanceOf[Range])
52345234

52355235
override def toText(printer: Printer): Text =
5236+
import printer.~
52365237
lo.toText(printer) ~ ".." ~ hi.toText(printer)
52375238
}
52385239

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ object TreePickler {
2626
override def isTerm: Boolean = isTermHole
2727
override def isType: Boolean = !isTermHole
2828
override def fallbackToText(printer: Printer): Text =
29+
import printer.~~
2930
s"[[$idx|" ~~ printer.toTextGlobal(args, ", ") ~~ "]]"
3031
}
3132
}

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ object Scala2Unpickler {
3737

3838
case class TempPolyType(tparams: List[TypeSymbol], tpe: Type) extends UncachedGroundType {
3939
override def fallbackToText(printer: Printer): Text =
40+
import printer.~
4041
"[" ~ printer.dclsText(tparams, ", ") ~ "]" ~ printer.toText(tpe)
4142
}
4243

compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class DecompilerPrinter(_ctx: Context) extends RefinedPrinter(_ctx) {
6666
// We don't print self type and constructor for objects
6767
val isObject = impl.constr.symbol.owner.is(Module)
6868
if (isObject) {
69-
val parentsText = keywordText(" extends") ~~ Text(parents.map(constrText), keywordStr(" with "))
69+
val parentsText = keywordText(" extends") ~~ concat(parents.map(constrText), keywordStr(" with "))
7070
val bodyText = " {" ~~ toTextGlobal(impl.body, "\n") ~ "}"
7171
parentsText.provided(parents.nonEmpty) ~ bodyText
7272
}

compiler/src/dotty/tools/dotc/printing/Formatting.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ object Formatting {
3131
case NonFatal(ex)
3232
if !ctx.mode.is(Mode.PrintShowExceptions) &&
3333
!ctx.settings.YshowPrintErrors.value =>
34-
val msg = ex match { case te: TypeError => te.toMessage case _ => ex.getMessage }
34+
val msg = ex match
35+
case te: TypeError => te.toMessage
36+
case _ => ex.getMessage
3537
s"[cannot display due to $msg, raw string = ${arg.toString}]"
3638
}
3739
case _ => arg.toString

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,27 @@ class PlainPrinter(_ctx: Context) extends Printer {
2323

2424
protected def maxToTextRecursions: Int = 100
2525

26+
def (x: Text) ~ (y: Text): Text =
27+
if (x.isEmpty) y
28+
else if (y.isEmpty) x
29+
else Fluid(y :: x :: Nil)
30+
31+
def (x: Text) ~~ (y: Text): Text =
32+
if (x.isEmpty) y
33+
else if (y.isEmpty) x
34+
else Fluid(y :: Str(" ") :: x :: Nil)
35+
36+
def concat(xs: Traversable[Text], sep: String = " "): Text =
37+
if (sep == "\n") lines(xs)
38+
else {
39+
val ys = xs filterNot (_.isEmpty)
40+
if (ys.isEmpty) Str("")
41+
else ys reduce (_ ~ sep ~ _)
42+
}
43+
44+
/** The given texts `xs`, each on a separate line */
45+
def lines(xs: Traversable[Text]): Vertical = Vertical(xs.toList.reverse)
46+
2647
protected final def controlled(op: => Text): Text =
2748
if (ctx.base.toTextRecursions < maxToTextRecursions && ctx.base.toTextRecursions < maxSummarized)
2849
try {
@@ -112,7 +133,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
112133
/** Pretty-print comma-separated type arguments for a constructor to be inserted among parentheses or brackets
113134
* (hence with `GlobalPrec` precedence).
114135
*/
115-
protected def argsText(args: List[Type]): Text = atPrec(GlobalPrec) { Text(args.map(arg => argText(arg) ), ", ") }
136+
protected def argsText(args: List[Type]): Text =
137+
atPrec(GlobalPrec) { concat(args.map(arg => argText(arg) ), ", ") }
116138

117139
/** The longest sequence of refinement types, starting at given type
118140
* and following parents.
@@ -156,7 +178,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
156178
case tp: RefinedType =>
157179
val parent :: (refined: List[RefinedType @unchecked]) =
158180
refinementChain(tp).reverse
159-
toTextLocal(parent) ~ "{" ~ Text(refined map toTextRefinement, "; ").close ~ "}"
181+
toTextLocal(parent) ~ "{" ~ concat(refined map toTextRefinement, "; ").close ~ "}"
160182
case tp: RecType =>
161183
try {
162184
openRecs = tp :: openRecs
@@ -173,7 +195,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
173195
case defn.MatchCase(pat, body) => "case " ~ toText(pat) ~ " => " ~ toText(body)
174196
case _ => "case " ~ toText(tp)
175197
}
176-
def casesText = Text(cases.map(caseText), "\n")
198+
def casesText = concat(cases.map(caseText), "\n")
177199
atPrec(InfixPrec) { toText(scrutinee) } ~
178200
keywordStr(" match ") ~ "{" ~ casesText ~ "}" ~
179201
(" <: " ~ toText(bound) provided !bound.isAny)
@@ -240,7 +262,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
240262
protected def paramsText(lam: LambdaType): Text = {
241263
def paramText(name: Name, tp: Type) =
242264
toText(name) ~ lambdaHash(lam) ~ toTextRHS(tp)
243-
Text(lam.paramNames.lazyZip(lam.paramInfos).map(paramText), ", ")
265+
concat(lam.paramNames.lazyZip(lam.paramInfos).map(paramText), ", ")
244266
}
245267

246268
protected def ParamRefNameString(name: Name): String = name.toString
@@ -363,22 +385,22 @@ class PlainPrinter(_ctx: Context) extends Printer {
363385
case tp: AliasingBounds =>
364386
" = " ~ toText(tp.alias)
365387
case TypeBounds(lo, hi) =>
366-
(if (lo isRef defn.NothingClass) Text() else " >: " ~ toText(lo))
367-
~ (if hi.isAny then Text() else " <: " ~ toText(hi))
388+
(if (lo isRef defn.NothingClass) Text.empty else " >: " ~ toText(lo))
389+
~ (if hi.isAny then Text.empty else " <: " ~ toText(hi))
368390
tparamStr ~ binder
369391
case tp @ ClassInfo(pre, cls, cparents, decls, selfInfo) =>
370392
val preText = toTextLocal(pre)
371393
val (tparams, otherDecls) = decls.toList partition treatAsTypeParam
372394
val tparamsText =
373-
if (tparams.isEmpty) Text() else ("[" ~ dclsText(tparams) ~ "]").close
395+
if (tparams.isEmpty) Text.empty else ("[" ~ dclsText(tparams) ~ "]").close
374396
val selfText: Text = selfInfo match {
375-
case NoType => Text()
397+
case NoType => Text.empty
376398
case sym: Symbol if !sym.isCompleted => "this: ? =>"
377399
case _ => "this: " ~ atPrec(InfixPrec) { toText(tp.selfType) } ~ " =>"
378400
}
379401
val trueDecls = otherDecls.filterNot(treatAsTypeArg)
380402
val declsText =
381-
if (trueDecls.isEmpty || !ctx.settings.Ydebug.value) Text()
403+
if (trueDecls.isEmpty || !ctx.settings.Ydebug.value) Text.empty
382404
else dclsText(trueDecls)
383405
tparamsText ~ " extends " ~ toTextParents(tp.parents) ~~ "{" ~ selfText ~ declsText ~
384406
"} at " ~ preText
@@ -391,7 +413,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
391413
}
392414
}
393415

394-
protected def toTextParents(parents: List[Type]): Text = Text(parents.map(toTextLocal), " with ")
416+
protected def toTextParents(parents: List[Type]): Text = concat(parents.map(toTextLocal), " with ")
395417

396418
protected def treatAsTypeParam(sym: Symbol): Boolean = false
397419
protected def treatAsTypeArg(sym: Symbol): Boolean = false
@@ -445,9 +467,9 @@ class PlainPrinter(_ctx: Context) extends Printer {
445467
protected def toTextFlags(sym: Symbol): Text = toTextFlags(sym, sym.flagsUNSAFE)
446468

447469
protected def toTextFlags(sym: Symbol, flags: FlagSet): Text =
448-
Text(flags.flagStrings(privateWithinString(sym)).map(flag => stringToText(keywordStr(flag))), " ")
470+
concat(flags.flagStrings(privateWithinString(sym)).map(flag => stringToText(keywordStr(flag))), " ")
449471

450-
def annotsText(sym: Symbol): Text = Text(sym.annotations.map(toText))
472+
def annotsText(sym: Symbol): Text = concat(sym.annotations.map(toText))
451473

452474
def dclText(sym: Symbol): Text = dclTextWithInfo(sym, sym.unforcedInfo)
453475

@@ -469,7 +491,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
469491
if (!sym.exists) ""
470492
else {
471493
val ownr = sym.effectiveOwner
472-
if (ownr.isClass && !isEmptyPrefix(ownr)) " in " ~ toText(ownr) else Text()
494+
if (ownr.isClass && !isEmptyPrefix(ownr)) " in " ~ toText(ownr) else Text.empty
473495
}
474496

475497
def locatedText(sym: Symbol): Text =
@@ -522,25 +544,25 @@ class PlainPrinter(_ctx: Context) extends Printer {
522544

523545
protected def escapedString(str: String): String = str flatMap escapedChar
524546

525-
def dclsText(syms: List[Symbol], sep: String): Text = Text(syms map dclText, sep)
547+
def dclsText(syms: List[Symbol], sep: String): Text = concat(syms map dclText, sep)
526548

527549
def toText(sc: Scope): Text =
528550
("Scope{" ~ dclsText(sc.toList) ~ "}").close
529551

530552
def toText[T >: Untyped](tree: Tree[T]): Text = {
531553
def toTextElem(elem: Any): Text = elem match {
532554
case elem: Showable => elem.toText(this)
533-
case elem: List[?] => "List(" ~ Text(elem map toTextElem, ",") ~ ")"
555+
case elem: List[?] => "List(" ~ concat(elem map toTextElem, ",") ~ ")"
534556
case elem => elem.toString
535557
}
536558
val nodeName = tree.productPrefix
537559
val elems =
538-
Text(tree.productIterator.map(toTextElem).toList, ", ")
560+
concat(tree.productIterator.map(toTextElem).toList, ", ")
539561
val tpSuffix =
540562
if (ctx.settings.XprintTypes.value && tree.hasType)
541563
" | " ~ toText(tree.typeOpt)
542564
else
543-
Text()
565+
Text.empty
544566

545567
nodeName ~ "(" ~ elems ~ tpSuffix ~ ")" ~ (Str(tree.sourcePos.toString) provided printDebug)
546568
}.close // todo: override in refined printer

compiler/src/dotty/tools/dotc/printing/Printer.scala

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ abstract class Printer {
157157

158158
/** Render elements alternating with `sep` string */
159159
def toText(elems: Traversable[Showable], sep: String): Text =
160-
Text(elems map (_ toText this), sep)
160+
concat(elems map (_ toText this), sep)
161161

162162
/** Render elements within highest precedence */
163163
def toTextLocal(elems: Traversable[Showable], sep: String): Text =
@@ -172,6 +172,18 @@ abstract class Printer {
172172
*/
173173
def summarized[T](depth: Int)(op: => T): T
174174

175+
/** A text that concatenates `x` and `y` */
176+
def (x: Text) ~ (y: Text): Text
177+
178+
/** A text that concatenates `x` and `y` with ` ` between them if both are nonempty */
179+
def (x: Text) ~~ (y: Text): Text
180+
181+
/** A text that concatenates all elements of `xs` with `sep` between them */
182+
def concat(xs: Traversable[Text], sep: String = " "): Text
183+
184+
/** A text that concatenates all elements of `xs` as individual lines */
185+
def lines(xs: Traversable[Text]): Text
186+
175187
/** A plain printer without any embellishments */
176188
def plain: Printer
177189
}

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
120120
}
121121

122122
override protected def toTextParents(parents: List[Type]): Text =
123-
Text(parents.map(toTextLocal).map(typeText), keywordStr(" with "))
123+
concat(parents.map(toTextLocal).map(typeText), keywordStr(" with "))
124124

125125
override protected def refinementNameString(tp: RefinedType): String =
126126
if (tp.parent.isInstanceOf[WildcardType] || tp.refinedName == nme.WILDCARD)
@@ -303,7 +303,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
303303
}
304304

305305
def forText(enums: List[untpd.Tree], expr: untpd.Tree, sep: String): Text = // DD
306-
changePrec(GlobalPrec) { keywordStr("for ") ~ Text(enums map enumText, "; ") ~ sep ~ toText(expr) }
306+
changePrec(GlobalPrec) { keywordStr("for ") ~ concat(enums map enumText, "; ") ~ sep ~ toText(expr) }
307307

308308
def cxBoundToText(bound: untpd.Tree): Text = bound match { // DD
309309
case AppliedTypeTree(tpt, _) => " : " ~ toText(tpt)
@@ -347,7 +347,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
347347
case (sel @ untpd.ImportSelector(name, EmptyTree, EmptyTree)) :: Nil =>
348348
selectorText(sel)
349349
case _ =>
350-
"{" ~ Text(selectors.map(selectorText), ", ") ~ "}"
350+
"{" ~ concat(selectors.map(selectorText), ", ") ~ "}"
351351

352352
toTextLocal(expr) ~ "." ~ selectorsText
353353

@@ -480,7 +480,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
480480
else if (tpt.symbol == defn.andType && args.length == 2)
481481
changePrec(AndTypePrec) { toText(args(0)) ~ " & " ~ atPrec(AndTypePrec + 1) { toText(args(1)) } }
482482
else
483-
toTextLocal(tpt) ~ "[" ~ Text(args map argText, ", ") ~ "]"
483+
toTextLocal(tpt) ~ "[" ~ concat(args map argText, ", ") ~ "]"
484484
case LambdaTypeTree(tparams, body) =>
485485
changePrec(GlobalPrec) {
486486
tparamsText(tparams) ~ " =>> " ~ toText(body)
@@ -560,7 +560,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
560560
case Thicket(List(str: Literal, expr)) => strText(str) ~ "{" ~ toTextGlobal(expr) ~ "}"
561561
case str: Literal => strText(str)
562562
}
563-
toText(id) ~ "\"" ~ Text(segments map segmentText, "") ~ "\""
563+
toText(id) ~ "\"" ~ concat(segments map segmentText, "") ~ "\""
564564
case Function(args, body) =>
565565
var implicitSeen: Boolean = false
566566
var isGiven: Boolean = false
@@ -581,12 +581,12 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
581581
case _ =>
582582
"("
583583
~ keywordText("erased ").provided(isErased)
584-
~ Text(args.map(argToText), ", ")
584+
~ concat(args.map(argToText), ", ")
585585
~ ")"
586586
}
587587
argsText ~ " " ~ arrow(isGiven) ~ " " ~ toText(body)
588588
case PolyFunction(targs, body) =>
589-
val targsText = "[" ~ Text(targs.map((arg: Tree) => toText(arg)), ", ") ~ "]"
589+
val targsText = "[" ~ concat(targs.map((arg: Tree) => toText(arg)), ", ") ~ "]"
590590
changePrec(GlobalPrec) {
591591
targsText ~ " => " ~ toText(body)
592592
}
@@ -805,8 +805,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
805805
if (constr.mods.hasAnnotations && !constr.mods.hasFlags) modsText = modsText ~~ " this"
806806
withEnclosingDef(constr) { addVparamssText(tparamsTxt ~~ modsText, vparamss) }
807807
}
808-
val parentsText = Text(impl.parents.map(constrText), if (ofNew) keywordStr(" with ") else ", ")
809-
val derivedText = Text(impl.derived.map(toText(_)), ", ")
808+
val parentsText = concat(impl.parents.map(constrText), if (ofNew) keywordStr(" with ") else ", ")
809+
val derivedText = concat(impl.derived.map(toText(_)), ", ")
810810
val selfText = {
811811
val selfName = if (self.name == nme.WILDCARD) keywordStr("this") else self.name.toString
812812
(selfName ~ optText(self.tpt)(": " ~ _) ~ " =>").close
@@ -870,7 +870,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
870870
val annotations =
871871
if (sym.exists) sym.annotations.filterNot(ann => dropAnnotForModText(ann.symbol)).map(_.tree)
872872
else mods.annotations.filterNot(tree => dropAnnotForModText(tree.symbol))
873-
Text(annotations.map(annotText), " ") ~~ flagsText ~~ (Str(kw) provided !suppressKw)
873+
concat(annotations.map(annotText), " ") ~~ flagsText ~~ (Str(kw) provided !suppressKw)
874874
}
875875

876876
def optText(name: Name)(encl: Text => Text): Text =
@@ -949,7 +949,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
949949
}
950950

951951
override def toText(denot: Denotation): Text = denot match {
952-
case denot: MultiDenotation => Text(denot.alternatives.map(dclText), " <and> ")
952+
case denot: MultiDenotation => concat(denot.alternatives.map(dclText), " <and> ")
953953
case NoDenotation => "NoDenotation"
954954
case _ =>
955955
if (denot.symbol.exists) toText(denot.symbol)

compiler/src/dotty/tools/dotc/printing/Texts.scala

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,6 @@ object Texts {
134134
sb.toString
135135
}
136136

137-
def ~ (that: Text): Text =
138-
if (this.isEmpty) that
139-
else if (that.isEmpty) this
140-
else Fluid(that :: this :: Nil)
141-
142-
def ~~ (that: Text): Text =
143-
if (this.isEmpty) that
144-
else if (that.isEmpty) this
145-
else Fluid(that :: Str(" ") :: this :: Nil)
146-
147137
def over (that: Text): Vertical =
148138
if (this.isVertical) Vertical(that :: this.relems)
149139
else Vertical(that :: this :: Nil)
@@ -152,21 +142,7 @@ object Texts {
152142
object Text {
153143

154144
/** The empty text */
155-
def apply(): Text = Str("")
156-
157-
/** A concatenation of elements in `xs` and interspersed with
158-
* separator strings `sep`.
159-
*/
160-
def apply(xs: Traversable[Text], sep: String = " "): Text =
161-
if (sep == "\n") lines(xs)
162-
else {
163-
val ys = xs filterNot (_.isEmpty)
164-
if (ys.isEmpty) Str("")
165-
else ys reduce (_ ~ sep ~ _)
166-
}
167-
168-
/** The given texts `xs`, each on a separate line */
169-
def lines(xs: Traversable[Text]): Vertical = Vertical(xs.toList.reverse)
145+
def empty: Text = Str("")
170146

171147
implicit class textDeco(text: => Text) {
172148
def provided(cond: Boolean): Text = if (cond) text else Str("")

0 commit comments

Comments
 (0)