-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Avoid printing extra blocks and inline nodes #5510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -646,6 +646,17 @@ trait Printers | |
printTree(body) | ||
} | ||
|
||
case IsDefDef(ddef @ DefDef(name, targs, argss, _, rhsOpt)) if name.startsWith("$anonfun") => | ||
// Decompile lambda definition | ||
assert(targs.isEmpty) | ||
val args :: Nil = argss | ||
val Some(rhs) = rhsOpt | ||
inParens { | ||
printArgsDefs(args) | ||
this += " => " | ||
printTree(rhs) | ||
} | ||
|
||
case IsDefDef(ddef @ DefDef(name, targs, argss, tpt, rhs)) => | ||
printDefAnnotations(ddef) | ||
|
||
|
@@ -777,34 +788,13 @@ trait Printers | |
case IsValDef(tree) => !tree.symbol.flags.isObject | ||
case _ => true | ||
} | ||
printFlatBlock(stats, expr) | ||
|
||
expr match { | ||
case Term.Lambda(_, _) => | ||
// Decompile lambda from { def annon$(...) = ...; closure(annon$, ...)} | ||
assert(stats.size == 1) | ||
val DefDef(_, _, args :: Nil, _, Some(rhs)) :: Nil = stats | ||
inParens { | ||
printArgsDefs(args) | ||
this += " => " | ||
printTree(rhs) | ||
} | ||
case _ => | ||
this += "{" | ||
indented { | ||
printStats(stats, expr) | ||
} | ||
this += lineBreak() += "}" | ||
} | ||
|
||
case Term.Inlined(call, bindings, expansion) => // FIXME: Don't print Inlined with empty calls? | ||
this += "{ // inlined" | ||
indented { | ||
printStats(bindings, expansion) | ||
} | ||
this += lineBreak() += "}" | ||
case Term.Inlined(_, bindings, expansion) => | ||
printFlatBlock(bindings, expansion) | ||
|
||
case Term.Lambda(meth, tpt) => | ||
// Printed in Term.Block branch | ||
// Printed in by it's DefDef | ||
this | ||
|
||
case Term.If(cond, thenp, elsep) => | ||
|
@@ -847,15 +837,80 @@ trait Printers | |
|
||
} | ||
|
||
def flatBlock(stats: List[Statement], expr: Term): (List[Statement], Term) = { | ||
val flatStats = List.newBuilder[Statement] | ||
def extractFlatStats(stat: Statement): Unit = stat match { | ||
case Term.Block(stats1, expr1) => | ||
val it = stats1.iterator | ||
while (it.hasNext) | ||
extractFlatStats(it.next()) | ||
extractFlatStats(expr1) | ||
case Term.Inlined(_, bindings, expansion) => | ||
val it = bindings.iterator | ||
while (it.hasNext) | ||
extractFlatStats(it.next()) | ||
extractFlatStats(expansion) | ||
case Term.Literal(Constant.Unit()) => // ignore | ||
case stat => flatStats += stat | ||
} | ||
def extractFlatExpr(term: Term): Term = term match { | ||
case Term.Block(stats1, expr1) => | ||
val it = stats1.iterator | ||
while (it.hasNext) | ||
extractFlatStats(it.next()) | ||
extractFlatExpr(expr1) | ||
case Term.Inlined(_, bindings, expansion) => | ||
val it = bindings.iterator | ||
while (it.hasNext) | ||
extractFlatStats(it.next()) | ||
extractFlatExpr(expansion) | ||
case term => term | ||
} | ||
val it = stats.iterator | ||
while (it.hasNext) | ||
extractFlatStats(it.next()) | ||
val flatExpr = extractFlatExpr(expr) | ||
(flatStats.result(), flatExpr) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Code smell for |
||
|
||
def printFlatBlock(stats: List[Statement], expr: Term): Buffer = { | ||
val (stats1, expr1) = flatBlock(stats, expr) | ||
// Remove Term.Lambda nodes, lambdas are printed by their definition | ||
val stats2 = stats1.filter { case Term.Lambda(_, _) => false; case _ => true } | ||
val (stats3, expr3) = expr1 match { | ||
case Term.Lambda(_, _) => | ||
val init :+ last = stats2 | ||
(init, last) | ||
case _ => (stats2, expr1) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the decompiler, |
||
if (stats3.isEmpty) { | ||
printTree(expr3) | ||
} else { | ||
this += "{" | ||
indented { | ||
printStats(stats3, expr3) | ||
} | ||
this += lineBreak() += "}" | ||
} | ||
} | ||
|
||
def printStats(stats: List[Tree], expr: Tree): Unit = { | ||
def printSeparator(next: Tree): Unit = { | ||
// Avoid accidental application of opening `{` on next line with a double break | ||
def rec(next: Tree): Unit = next match { | ||
case Term.Block(stats, _) if stats.nonEmpty => this += doubleLineBreak() | ||
case Term.Inlined(_, bindings, _) if bindings.nonEmpty => this += doubleLineBreak() | ||
case Term.Select(qual, _) => rec(qual) | ||
case Term.Apply(fn, _) => rec(fn) | ||
case Term.TypeApply(fn, _) => rec(fn) | ||
case _ => this += lineBreak() | ||
} | ||
next match { | ||
case Term.Block(_, _) => this += doubleLineBreak() | ||
case Term.Inlined(_, _, _) => this += doubleLineBreak() | ||
case Term.Select(qual, _) => printSeparator(qual) | ||
case Term.Apply(fn, _) => printSeparator(fn) | ||
case Term.TypeApply(fn, _) => printSeparator(fn) | ||
case IsTerm(term) => | ||
flatBlock(Nil, term) match { | ||
case (next :: _, _) => rec(next) | ||
case (Nil, next) => rec(next) | ||
} | ||
case _ => this += lineBreak() | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,9 @@ | ||
/** Decompiled from out/posTestFromTasty/pos/i4526b/Foo.class */ | ||
class Foo() { | ||
def justdoit(f: scala.Either[scala.Int, scala.Predef.String]): scala.Predef.String = { | ||
f match { | ||
case scala.Left(i) => | ||
i.toString() | ||
case scala.Right(s) => | ||
(s: java.lang.String) | ||
} | ||
def justdoit(f: scala.Either[scala.Int, scala.Predef.String]): scala.Predef.String = f match { | ||
case scala.Left(i) => | ||
i.toString() | ||
case scala.Right(s) => | ||
(s: java.lang.String) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,7 @@ | ||
/** Decompiled from out/posTestFromTasty/pos/lambda/foo/Foo.class */ | ||
package foo { | ||
class Foo() { | ||
{ | ||
((x: scala.Int) => { | ||
2 | ||
}) | ||
} | ||
((x: scala.Int) => 2) | ||
val a: scala.Function1[scala.Int, scala.Int] = ((x: scala.Int) => x.*(x)) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,5 @@ | ||
/** Decompiled from out/posTestFromTasty/pos/simpleInline/Foo.class */ | ||
class Foo() { | ||
inline def foo: scala.Int = (9: scala.Int) | ||
def bar: scala.Int = { // inlined | ||
(9: scala.Int) | ||
} | ||
def bar: scala.Int = (9: scala.Int) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,8 @@ | ||
/** Decompiled from out/posTestFromTasty/pos/simpleMatchCase/Foo.class */ | ||
class Foo() { | ||
def foo: scala.Unit = { | ||
"c" match { | ||
case x => | ||
scala.Predef.println("a") | ||
scala.Predef.println("b") | ||
} | ||
def foo: scala.Unit = "c" match { | ||
case x => | ||
scala.Predef.println("a") | ||
scala.Predef.println("b") | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,6 @@ | |
class Foo() { | ||
def foo: scala.Unit = { | ||
var i: scala.Int = 1 | ||
while (i.!=(0)) { | ||
i = 0 | ||
} | ||
while (i.!=(0)) i = 0 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,5 @@ | ||
/** Decompiled from out/posTestFromTasty/pos/t3869/Test.class */ | ||
object Test { | ||
def f: scala.Unit = try return () finally while (true) () | ||
def main(args: scala.Array[scala.Predef.String]): scala.Unit = { | ||
Test.f | ||
} | ||
def main(args: scala.Array[scala.Predef.String]): scala.Unit = Test.f | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1 @@ | ||
1 + {{ // inlined | ||
Index.zero["bar", scala.Tuple2["baz", scala.Unit]] | ||
}} | ||
1 + {Index.zero["bar", scala.Tuple2["baz", scala.Unit]]} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,5 @@ | |
type T = scala.Predef.String | ||
val x: java.lang.String = "foo" | ||
val z: T = x | ||
() | ||
(x: java.lang.String) | ||
} |
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code seems to have forgotten the case
implicit object A
.