@@ -646,6 +646,17 @@ trait Printers
646
646
printTree(body)
647
647
}
648
648
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
+
649
660
case IsDefDef (ddef @ DefDef (name, targs, argss, tpt, rhs)) =>
650
661
printDefAnnotations(ddef)
651
662
@@ -777,34 +788,13 @@ trait Printers
777
788
case IsValDef (tree) => ! tree.symbol.flags.isObject
778
789
case _ => true
779
790
}
791
+ printFlatBlock(stats, expr)
780
792
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)
805
795
806
796
case Term .Lambda (meth, tpt) =>
807
- // Printed in Term.Block branch
797
+ // Printed in by it's DefDef
808
798
this
809
799
810
800
case Term .If (cond, thenp, elsep) =>
@@ -847,15 +837,80 @@ trait Printers
847
837
848
838
}
849
839
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
+
850
897
def printStats (stats : List [Tree ], expr : Tree ): Unit = {
851
898
def printSeparator (next : Tree ): Unit = {
852
899
// 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
+ }
853
908
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
+ }
859
914
case _ => this += lineBreak()
860
915
}
861
916
}
0 commit comments