Skip to content

Commit ca35eee

Browse files
committed
Handle empty blocks in the printer
Avoid printing extra blocks and inline nodes
1 parent 9a9aa31 commit ca35eee

20 files changed

+99
-167
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
404404
case SeqLiteral(elems, elemtpt) =>
405405
"[" ~ toTextGlobal(elems, ",") ~ " : " ~ toText(elemtpt) ~ "]"
406406
case tree @ Inlined(call, bindings, body) =>
407-
(("/* inlined from " ~ toText(call) ~ " */ ") `provided`
408-
!call.isEmpty && !homogenizedView && !ctx.settings.YshowNoInline.value) ~
407+
(("/* inlined from " ~ (if (call.isEmpty) "outside" else toText(call)) ~ " */ ") `provided`
408+
!homogenizedView && !ctx.settings.YshowNoInline.value) ~
409409
blockText(bindings :+ body)
410410
case tpt: untpd.DerivedTypeTree =>
411411
"<derived typetree watching " ~ summarized(toText(tpt.watched)) ~ ">"

compiler/src/dotty/tools/dotc/quoted/TreeCleaner.scala

-11
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,6 @@ class TreeCleaner extends tpd.TreeMap {
3030
}
3131

3232
super.transform(tree0) match {
33-
case Block(Nil, expr1) => expr1
34-
case Block(stats1, expr1) =>
35-
val flatStats = stats1.flatMap {
36-
case Block(stats2, expr2) => stats2 ::: expr2 :: Nil
37-
case Literal(Constant(())) => Nil
38-
case stat => stat :: Nil
39-
}
40-
expr1 match {
41-
case Block(stats3, expr3) => seq(flatStats ::: stats3, expr3)
42-
case expr3 => seq(flatStats, expr3)
43-
}
4433
case tree1: TypeTree => TypeTree(tree1.tpe.subst(aliasesSyms, aliasesTypes))
4534
case tree1: Ident => aliases.get(tree1.symbol).getOrElse(tree1)
4635
case tree1 => tree1

compiler/test/dotc/pos-recompilation.whitelist

-4
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ CoderTrait
3838
collectGenericCC
3939
collections_1
4040
comp-rec-test
41-
companions
4241
compile1
4342
conforms
4443
conformsWild
@@ -317,7 +316,6 @@ i831
317316
i864
318317
i877
319318
i878
320-
i880
321319
i903
322320
i938
323321
i939
@@ -438,7 +436,6 @@ propagate
438436
quote-1
439437
quote-lift-inline-params-b
440438
quote-non-static-macro
441-
quote-this
442439
range
443440
rangepos
444441
rangepos-anonapply
@@ -883,7 +880,6 @@ t613
883880
t6145
884881
t6146
885882
t615
886-
t6157
887883
t616
888884
t6184
889885
t6201

library/src/scala/tasty/reflect/Printers.scala

+74-30
Original file line numberDiff line numberDiff line change
@@ -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,69 @@ 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+
stats1.foreach(extractFlatStats)
845+
extractFlatStats(expr1)
846+
case Term.Inlined(_, bindings, expansion) =>
847+
bindings.foreach(extractFlatStats)
848+
extractFlatStats(expansion)
849+
case Term.Literal(Constant.Unit()) => // ignore
850+
case stat => flatStats += stat
851+
}
852+
def extractFlatExpr(term: Term): Term = term match {
853+
case Term.Block(stats1, expr1) =>
854+
stats1.foreach(extractFlatStats)
855+
extractFlatExpr(expr1)
856+
case Term.Inlined(_, bindings, expansion) =>
857+
bindings.foreach(extractFlatStats)
858+
extractFlatExpr(expansion)
859+
case term => term
860+
}
861+
stats.foreach(extractFlatStats)
862+
val flatExpr = extractFlatExpr(expr)
863+
(flatStats.result(), flatExpr)
864+
}
865+
def printFlatBlock(stats: List[Statement], expr: Term): Buffer = {
866+
val (stats1, expr1) = flatBlock(stats, expr)
867+
// Remove Term.Lambda nodes, lambdas are printed by their definition
868+
val stats2 = stats1.filter { case Term.Lambda(_, _) => false; case _ => true }
869+
val (stats3, expr3) = expr1 match {
870+
case Term.Lambda(_, _) =>
871+
val init :+ last = stats2
872+
(init, last)
873+
case _ => (stats2, expr1)
874+
}
875+
if (stats3.isEmpty) {
876+
printTree(expr3)
877+
} else {
878+
this += "{"
879+
indented {
880+
printStats(stats3, expr3)
881+
}
882+
this += lineBreak() += "}"
883+
}
884+
}
885+
850886
def printStats(stats: List[Tree], expr: Tree): Unit = {
851887
def printSeparator(next: Tree): Unit = {
852888
// Avoid accidental application of opening `{` on next line with a double break
889+
def rec(next: Tree): Unit = next match {
890+
case Term.Block(stats, _) if stats.nonEmpty => this += doubleLineBreak()
891+
case Term.Inlined(_, bindings, _) if bindings.nonEmpty => this += doubleLineBreak()
892+
case Term.Select(qual, _, _) => rec(qual)
893+
case Term.Apply(fn, _) => rec(fn)
894+
case Term.TypeApply(fn, _) => rec(fn)
895+
case _ => this += lineBreak()
896+
}
853897
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)
898+
case IsTerm(term) =>
899+
flatBlock(Nil, term) match {
900+
case (next :: _, _) => rec(next)
901+
case (Nil, next) => rec(next)
902+
}
859903
case _ => this += lineBreak()
860904
}
861905
}

tests/pos/i2104b.decompiled

+4-6
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,8 @@ case class Pair[A, B](_1: A, _2: B) {
3434
object Pair extends scala.AnyRef()
3535
/** Decompiled from out/posTestFromTasty/pos/i2104b/Test.class */
3636
object Test {
37-
def main(args: scala.Array[scala.Predef.String]): scala.Unit = {
38-
Cons.apply[scala.Option[scala.Int], scala.None.type](scala.Option.apply[scala.Int](1), scala.None) match {
39-
case Cons(scala.Some(i), scala.None) =>
40-
()
41-
}
37+
def main(args: scala.Array[scala.Predef.String]): scala.Unit = Cons.apply[scala.Option[scala.Int], scala.None.type](scala.Option.apply[scala.Int](1), scala.None) match {
38+
case Cons(scala.Some(i), scala.None) =>
39+
()
4240
}
43-
}
41+
}

tests/pos/i4526b.decompiled

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
/** Decompiled from out/posTestFromTasty/pos/i4526b/Foo.class */
22
class Foo() {
3-
def justdoit(f: scala.Either[scala.Int, scala.Predef.String]): scala.Predef.String = {
4-
f match {
5-
case scala.Left(i) =>
6-
i.toString()
7-
case scala.Right(s) =>
8-
(s: java.lang.String)
9-
}
3+
def justdoit(f: scala.Either[scala.Int, scala.Predef.String]): scala.Predef.String = f match {
4+
case scala.Left(i) =>
5+
i.toString()
6+
case scala.Right(s) =>
7+
(s: java.lang.String)
108
}
119
}

tests/pos/lambda.decompiled

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
/** Decompiled from out/posTestFromTasty/pos/lambda/foo/Foo.class */
22
package foo {
33
class Foo() {
4-
{
5-
((x: scala.Int) => {
6-
2
7-
})
8-
}
4+
((x: scala.Int) => 2)
95
val a: scala.Function1[scala.Int, scala.Int] = ((x: scala.Int) => x.*(x))
106
}
117
}

tests/pos/simpleDoWhile.decompiled

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
class Foo() {
33
def foo: scala.Unit = {
44
var i: scala.Int = 1
5-
do {
6-
i = 0
7-
} while (i.!=(0))
5+
do i = 0 while (i.!=(0))
86
}
97
}

tests/pos/simpleInline.decompiled

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
/** Decompiled from out/posTestFromTasty/pos/simpleInline/Foo.class */
22
class Foo() {
33
inline def foo: scala.Int = (9: scala.Int)
4-
def bar: scala.Int = { // inlined
5-
(9: scala.Int)
6-
}
4+
def bar: scala.Int = (9: scala.Int)
75
}

tests/pos/simpleMatchCase.decompiled

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
/** Decompiled from out/posTestFromTasty/pos/simpleMatchCase/Foo.class */
22
class Foo() {
3-
def foo: scala.Unit = {
4-
"c" match {
5-
case x =>
6-
scala.Predef.println("a")
7-
scala.Predef.println("b")
8-
}
3+
def foo: scala.Unit = "c" match {
4+
case x =>
5+
scala.Predef.println("a")
6+
scala.Predef.println("b")
97
}
108
}

tests/pos/simpleWhile.decompiled

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
class Foo() {
33
def foo: scala.Unit = {
44
var i: scala.Int = 1
5-
while (i.!=(0)) {
6-
i = 0
7-
}
5+
while (i.!=(0)) i = 0
86
}
97
}

tests/pos/t3869.decompiled

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
/** Decompiled from out/posTestFromTasty/pos/t3869/Test.class */
22
object Test {
33
def f: scala.Unit = try return () finally while (true) ()
4-
def main(args: scala.Array[scala.Predef.String]): scala.Unit = {
5-
Test.f
6-
}
4+
def main(args: scala.Array[scala.Predef.String]): scala.Unit = Test.f
75
}

tests/pos/t704.decompiled

+2-5
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,8 @@ trait E() extends java.lang.Object with D {
1616
val x1: scala.AnyRef = E.this.get_xxxx
1717
scala.Console.println(y)
1818
}
19-
20-
{
21-
yyyy
22-
()
23-
}
19+
yyyy
20+
()
2421
}
2522
}
2623
/** Decompiled from out/posTestFromTasty/pos/t704/Go.class */
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
1 + {{ // inlined
2-
Index.zero["bar", scala.Tuple2["baz", scala.Unit]]
3-
}}
1+
1 + {Index.zero["bar", scala.Tuple2["baz", scala.Unit]]}

tests/run-with-compiler/quote-nested-3.check

-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@
22
type T = scala.Predef.String
33
val x: java.lang.String = "foo"
44
val z: T = x
5-
()
65
(x: java.lang.String)
76
}

tests/run-with-compiler/quote-show-blocks-raw.check

-36
This file was deleted.

tests/run-with-compiler/quote-show-blocks-raw.scala

-25
This file was deleted.

tests/run-with-compiler/quote-unrolled-foreach.check

-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
var i: scala.Int = 0
3434
while (i.<(size)) {
3535
val element: scala.Int = arr.apply(i)
36-
3736
((i: scala.Int) => java.lang.System.out.println(i)).apply(element)
3837
i = i.+(1)
3938
}
@@ -86,7 +85,6 @@
8685
var i: scala.Int = 0
8786
while (i.<(size)) {
8887
val element: scala.Int = arr1.apply(i)
89-
9088
((x: scala.Int) => scala.Predef.println(x)).apply(element)
9189
i = i.+(1)
9290
}

0 commit comments

Comments
 (0)