@@ -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
0 commit comments