@@ -646,6 +646,17 @@ trait Printers
646646 printTree(body)
647647 }
648648
649+ case IsDefDef (ddef @ DefDef (name, targs, argss, _, rhsOpt)) if name.startsWith(" $anonfun" ) =>
650+ // Decompile lambda definition
651+ assert(targs.isEmpty)
652+ val args :: Nil = argss
653+ val Some (rhs) = rhsOpt
654+ inParens {
655+ printArgsDefs(args)
656+ this += " => "
657+ printTree(rhs)
658+ }
659+
649660 case IsDefDef (ddef @ DefDef (name, targs, argss, tpt, rhs)) =>
650661 printDefAnnotations(ddef)
651662
@@ -777,34 +788,13 @@ trait Printers
777788 case IsValDef (tree) => ! tree.symbol.flags.isObject
778789 case _ => true
779790 }
791+ printFlatBlock(stats, expr)
780792
781- expr match {
782- case Term .Lambda (_, _) =>
783- // Decompile lambda from { def annon$(...) = ...; closure(annon$, ...)}
784- assert(stats.size == 1 )
785- val DefDef (_, _, args :: Nil , _, Some (rhs)) :: Nil = stats
786- inParens {
787- printArgsDefs(args)
788- this += " => "
789- printTree(rhs)
790- }
791- case _ =>
792- this += " {"
793- indented {
794- printStats(stats, expr)
795- }
796- this += lineBreak() += " }"
797- }
798-
799- case Term .Inlined (call, bindings, expansion) => // FIXME: Don't print Inlined with empty calls?
800- this += " { // inlined"
801- indented {
802- printStats(bindings, expansion)
803- }
804- this += lineBreak() += " }"
793+ case Term .Inlined (_, bindings, expansion) =>
794+ printFlatBlock(bindings, expansion)
805795
806796 case Term .Lambda (meth, tpt) =>
807- // Printed in Term.Block branch
797+ // Printed in by it's DefDef
808798 this
809799
810800 case Term .If (cond, thenp, elsep) =>
@@ -847,15 +837,80 @@ trait Printers
847837
848838 }
849839
840+ def flatBlock (stats : List [Statement ], expr : Term ): (List [Statement ], Term ) = {
841+ val flatStats = List .newBuilder[Statement ]
842+ def extractFlatStats (stat : Statement ): Unit = stat match {
843+ case Term .Block (stats1, expr1) =>
844+ val it = stats1.iterator
845+ while (it.hasNext)
846+ extractFlatStats(it.next())
847+ extractFlatStats(expr1)
848+ case Term .Inlined (_, bindings, expansion) =>
849+ val it = bindings.iterator
850+ while (it.hasNext)
851+ extractFlatStats(it.next())
852+ extractFlatStats(expansion)
853+ case Term .Literal (Constant .Unit ()) => // ignore
854+ case stat => flatStats += stat
855+ }
856+ def extractFlatExpr (term : Term ): Term = term match {
857+ case Term .Block (stats1, expr1) =>
858+ val it = stats1.iterator
859+ while (it.hasNext)
860+ extractFlatStats(it.next())
861+ extractFlatExpr(expr1)
862+ case Term .Inlined (_, bindings, expansion) =>
863+ val it = bindings.iterator
864+ while (it.hasNext)
865+ extractFlatStats(it.next())
866+ extractFlatExpr(expansion)
867+ case term => term
868+ }
869+ val it = stats.iterator
870+ while (it.hasNext)
871+ extractFlatStats(it.next())
872+ val flatExpr = extractFlatExpr(expr)
873+ (flatStats.result(), flatExpr)
874+ }
875+
876+ def printFlatBlock (stats : List [Statement ], expr : Term ): Buffer = {
877+ val (stats1, expr1) = flatBlock(stats, expr)
878+ // Remove Term.Lambda nodes, lambdas are printed by their definition
879+ val stats2 = stats1.filter { case Term .Lambda (_, _) => false ; case _ => true }
880+ val (stats3, expr3) = expr1 match {
881+ case Term .Lambda (_, _) =>
882+ val init :+ last = stats2
883+ (init, last)
884+ case _ => (stats2, expr1)
885+ }
886+ if (stats3.isEmpty) {
887+ printTree(expr3)
888+ } else {
889+ this += " {"
890+ indented {
891+ printStats(stats3, expr3)
892+ }
893+ this += lineBreak() += " }"
894+ }
895+ }
896+
850897 def printStats (stats : List [Tree ], expr : Tree ): Unit = {
851898 def printSeparator (next : Tree ): Unit = {
852899 // Avoid accidental application of opening `{` on next line with a double break
900+ def rec (next : Tree ): Unit = next match {
901+ case Term .Block (stats, _) if stats.nonEmpty => this += doubleLineBreak()
902+ case Term .Inlined (_, bindings, _) if bindings.nonEmpty => this += doubleLineBreak()
903+ case Term .Select (qual, _, _) => rec(qual)
904+ case Term .Apply (fn, _) => rec(fn)
905+ case Term .TypeApply (fn, _) => rec(fn)
906+ case _ => this += lineBreak()
907+ }
853908 next match {
854- case Term . Block (_, _ ) => this += doubleLineBreak()
855- case Term . Inlined (_, _, _) => this += doubleLineBreak()
856- case Term . Select (qual, _, _) => printSeparator(qual )
857- case Term . Apply (fn, _ ) => printSeparator(fn )
858- case Term . TypeApply (fn, _) => printSeparator(fn)
909+ case IsTerm (term ) =>
910+ flatBlock( Nil , term) match {
911+ case (next :: _, _) => rec(next )
912+ case ( Nil , next ) => rec(next )
913+ }
859914 case _ => this += lineBreak()
860915 }
861916 }
0 commit comments