From 8391c9e308d57bd3be443a655a4f15588f6a44e4 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 5 Apr 2018 11:39:12 +0200 Subject: [PATCH 1/4] Decompile [do] while loops --- .../tools/dotc/printing/DecompilerPrinter.scala | 9 ++++++++- tests/pos/simpleDoWhile.decompiled | 17 +++++++++++++++++ tests/pos/simpleDoWhile.scala | 8 ++++++++ tests/pos/simpleWhile.decompiled | 16 ++++++++++++++++ tests/pos/simpleWhile.scala | 8 ++++++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 tests/pos/simpleDoWhile.decompiled create mode 100644 tests/pos/simpleDoWhile.scala create mode 100644 tests/pos/simpleWhile.decompiled create mode 100644 tests/pos/simpleWhile.scala diff --git a/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala b/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala index 392d719cfefd..458610599fba 100644 --- a/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala @@ -7,6 +7,7 @@ import dotty.tools.dotc.printing.Texts._ import dotty.tools.dotc.core.Contexts._ import dotty.tools.dotc.core.Flags._ import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.core.StdNames._ import scala.language.implicitConversions @@ -16,7 +17,13 @@ class DecompilerPrinter(_ctx: Context) extends RefinedPrinter(_ctx) { annots.filter(_.tpe != defn.SourceFileAnnotType) override protected def blockText[T >: Untyped](trees: List[Trees.Tree[T]]): Text = { - super.blockText(trees.filterNot(_.isInstanceOf[Closure[_]])) + trees match { + case DefDef(_, _, _, _, Trees.If(cond, Trees.Block(body :: Nil, _), _)) :: y :: Nil if y.symbol.name == nme.WHILE_PREFIX => + keywordText("while") ~ " (" ~ toText(cond) ~ ")" ~ toText(body) + case DefDef(_, _, _, _, Trees.Block(body :: Nil, Trees.If(cond, _, _))) :: y :: Nil if y.symbol.name == nme.DO_WHILE_PREFIX => + keywordText("do") ~ toText(body) ~ keywordText("while") ~ " (" ~ toText(cond) ~ ")" + case _ => super.blockText(trees.filterNot(_.isInstanceOf[Closure[_]])) + } } override protected def packageDefText(tree: PackageDef): Text = { diff --git a/tests/pos/simpleDoWhile.decompiled b/tests/pos/simpleDoWhile.decompiled new file mode 100644 index 000000000000..77417f1daa44 --- /dev/null +++ b/tests/pos/simpleDoWhile.decompiled @@ -0,0 +1,17 @@ +================================================================================ +out/posTestFromTasty/pos/simpleDoWhile/Foo.class +-------------------------------------------------------------------------------- +package { + class Foo() extends Object() { + def foo: Unit = + { + var i: Int = 1 + do + { + i = 0 + } + while (i.!=(0)) + } + } +} +-------------------------------------------------------------------------------- \ No newline at end of file diff --git a/tests/pos/simpleDoWhile.scala b/tests/pos/simpleDoWhile.scala new file mode 100644 index 000000000000..37419dc5d064 --- /dev/null +++ b/tests/pos/simpleDoWhile.scala @@ -0,0 +1,8 @@ +class Foo { + def foo = { + var i = 1 + do { + i = 0 + } while (i != 0) + } +} diff --git a/tests/pos/simpleWhile.decompiled b/tests/pos/simpleWhile.decompiled new file mode 100644 index 000000000000..55f532ec4e79 --- /dev/null +++ b/tests/pos/simpleWhile.decompiled @@ -0,0 +1,16 @@ +================================================================================ +out/posTestFromTasty/pos/simpleWhile/Foo.class +-------------------------------------------------------------------------------- +package { + class Foo() extends Object() { + def foo: Unit = + { + var i: Int = 1 + while (i.!=(0)) + { + i = 0 + } + } + } +} +-------------------------------------------------------------------------------- \ No newline at end of file diff --git a/tests/pos/simpleWhile.scala b/tests/pos/simpleWhile.scala new file mode 100644 index 000000000000..a70399f0aaa7 --- /dev/null +++ b/tests/pos/simpleWhile.scala @@ -0,0 +1,8 @@ +class Foo { + def foo = { + var i = 1 + while (i != 0) { + i = 0 + } + } +} From 2ea9d9e30c447a19e7f7330ba01d382e2e38b4f5 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 5 Apr 2018 11:51:54 +0200 Subject: [PATCH 2/4] Do not print empty package when decompiling --- .../dotc/printing/DecompilerPrinter.scala | 6 +++-- tests/pos/methodTypes.decompiled | 10 ++++----- tests/pos/simpleDoWhile.decompiled | 22 +++++++++---------- tests/pos/simpleWhile.decompiled | 20 ++++++++--------- tests/run/puzzle.decompiled | 22 +++++++++---------- 5 files changed, 37 insertions(+), 43 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala b/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala index 458610599fba..584afda3761f 100644 --- a/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala @@ -36,8 +36,10 @@ class DecompilerPrinter(_ctx: Context) extends RefinedPrinter(_ctx) { case _ => toTextGlobal(stats, "\n") } val bodyText = - if (currentPrecedence == TopLevelPrec) "\n" ~ statsText else " {" ~ statsText ~ "}" - keywordStr("package ") ~ toTextPackageId(tree.pid) ~ bodyText + if (tree.pid.symbol.isEmptyPackage) statsText + else if (currentPrecedence == TopLevelPrec) "\n" ~ statsText + else " {" ~ statsText ~ "}" + (keywordStr("package ") ~ toTextPackageId(tree.pid)).provided(!tree.pid.symbol.isEmptyPackage) ~ bodyText } override protected def templateText(tree: TypeDef, impl: Template): Text = { diff --git a/tests/pos/methodTypes.decompiled b/tests/pos/methodTypes.decompiled index 8b49ab2b402e..4789029de8d7 100644 --- a/tests/pos/methodTypes.decompiled +++ b/tests/pos/methodTypes.decompiled @@ -1,11 +1,9 @@ ================================================================================ out/posTestFromTasty/pos/methodTypes/Foo.class -------------------------------------------------------------------------------- -package { - class Foo() extends Object() { - val x: Int = 1 - def y: Int = 2 - def z(): Int = 3 - } +class Foo() extends Object() { + val x: Int = 1 + def y: Int = 2 + def z(): Int = 3 } -------------------------------------------------------------------------------- \ No newline at end of file diff --git a/tests/pos/simpleDoWhile.decompiled b/tests/pos/simpleDoWhile.decompiled index 77417f1daa44..d1629e0ccecd 100644 --- a/tests/pos/simpleDoWhile.decompiled +++ b/tests/pos/simpleDoWhile.decompiled @@ -1,17 +1,15 @@ ================================================================================ out/posTestFromTasty/pos/simpleDoWhile/Foo.class -------------------------------------------------------------------------------- -package { - class Foo() extends Object() { - def foo: Unit = - { - var i: Int = 1 - do - { - i = 0 - } - while (i.!=(0)) - } - } +class Foo() extends Object() { + def foo: Unit = + { + var i: Int = 1 + do + { + i = 0 + } + while (i.!=(0)) + } } -------------------------------------------------------------------------------- \ No newline at end of file diff --git a/tests/pos/simpleWhile.decompiled b/tests/pos/simpleWhile.decompiled index 55f532ec4e79..4cea6bebfaa8 100644 --- a/tests/pos/simpleWhile.decompiled +++ b/tests/pos/simpleWhile.decompiled @@ -1,16 +1,14 @@ ================================================================================ out/posTestFromTasty/pos/simpleWhile/Foo.class -------------------------------------------------------------------------------- -package { - class Foo() extends Object() { - def foo: Unit = - { - var i: Int = 1 - while (i.!=(0)) - { - i = 0 - } - } - } +class Foo() extends Object() { + def foo: Unit = + { + var i: Int = 1 + while (i.!=(0)) + { + i = 0 + } + } } -------------------------------------------------------------------------------- \ No newline at end of file diff --git a/tests/run/puzzle.decompiled b/tests/run/puzzle.decompiled index 4ce0c2cc3891..ff9220b317d0 100644 --- a/tests/run/puzzle.decompiled +++ b/tests/run/puzzle.decompiled @@ -1,17 +1,15 @@ ================================================================================ out/runTestFromTasty/run/puzzle/Test.class -------------------------------------------------------------------------------- -package { - object Test() extends Object() { this: Test.type => - def main(args: Array[String]): Unit = - { - println(if false then 5.0 else 53.0) - val x: Double = if false then 5.0 else 53.0 - println(x) - val z: Long = 1L - val y: Float = Long.long2float(z) - () - } - } +object Test() extends Object() { this: Test.type => + def main(args: Array[String]): Unit = + { + println(if false then 5.0 else 53.0) + val x: Double = if false then 5.0 else 53.0 + println(x) + val z: Long = 1L + val y: Float = Long.long2float(z) + () + } } -------------------------------------------------------------------------------- \ No newline at end of file From af822e16fa129cc7be669d0b80b681ee965fdeec Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 5 Apr 2018 13:08:33 +0200 Subject: [PATCH 3/4] Do not print extends Object whlie decompiling --- .../src/dotty/tools/dotc/printing/DecompilerPrinter.scala | 8 +++++++- .../src/dotty/tools/dotc/printing/RefinedPrinter.scala | 2 +- tests/pos/lambda.decompiled | 2 +- tests/pos/methodTypes.decompiled | 2 +- tests/pos/simpleCaseObject.decompiled | 4 +--- tests/pos/simpleClass-2.decompiled | 2 +- tests/pos/simpleClass.decompiled | 2 +- tests/pos/simpleDoWhile.decompiled | 2 +- tests/pos/simpleWhile.decompiled | 2 +- tests/run/puzzle.decompiled | 2 +- 10 files changed, 16 insertions(+), 12 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala b/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala index 584afda3761f..081075e6c434 100644 --- a/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala @@ -1,6 +1,6 @@ package dotty.tools.dotc.printing -import dotty.tools.dotc.ast.Trees.{Closure, DefDef, Untyped, ValDef} +import dotty.tools.dotc.ast.Trees._ import dotty.tools.dotc.ast.untpd.{PackageDef, Template, TypeDef} import dotty.tools.dotc.ast.{Trees, untpd} import dotty.tools.dotc.printing.Texts._ @@ -49,6 +49,12 @@ class DecompilerPrinter(_ctx: Context) extends RefinedPrinter(_ctx) { decl ~~ typeText(nameIdText(tree)) ~ withEnclosingDef(tree) { toTextTemplate(impl) } ~ "" } + override protected def toTextTemplate(impl: Template, ofNew: Boolean = false): Text = { + val Template(constr, parents, self, preBody) = impl + val impl1 = Template(constr, parents.filterNot(_.symbol.maybeOwner == defn.ObjectClass), self, preBody) + super.toTextTemplate(impl1, ofNew) + } + override protected def defDefToText[T >: Untyped](tree: DefDef[T]): Text = { import untpd.{modsDeco => _, _} dclTextOr(tree) { diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 48bc992f8a47..1c1e05e5404e 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -654,7 +654,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { val bodyText = "{" ~~ selfText ~~ toTextGlobal(primaryConstrs ::: body, "\n") ~ "}" - prefix ~ (keywordText(" extends") provided !ofNew) ~~ parentsText ~~ bodyText + prefix ~ (keywordText(" extends") provided (!ofNew && parents.nonEmpty)) ~~ parentsText ~~ bodyText } protected def templateText(tree: TypeDef, impl: Template): Text = { diff --git a/tests/pos/lambda.decompiled b/tests/pos/lambda.decompiled index e44e5770633a..b201feba55cc 100644 --- a/tests/pos/lambda.decompiled +++ b/tests/pos/lambda.decompiled @@ -2,7 +2,7 @@ out/posTestFromTasty/pos/lambda/foo/Foo.class -------------------------------------------------------------------------------- package foo { - class Foo() extends Object() { + class Foo() { val a: Int => Int = { (x: Int) => x.*(x) diff --git a/tests/pos/methodTypes.decompiled b/tests/pos/methodTypes.decompiled index 4789029de8d7..40cc677c5c03 100644 --- a/tests/pos/methodTypes.decompiled +++ b/tests/pos/methodTypes.decompiled @@ -1,7 +1,7 @@ ================================================================================ out/posTestFromTasty/pos/methodTypes/Foo.class -------------------------------------------------------------------------------- -class Foo() extends Object() { +class Foo() { val x: Int = 1 def y: Int = 2 def z(): Int = 3 diff --git a/tests/pos/simpleCaseObject.decompiled b/tests/pos/simpleCaseObject.decompiled index 1ecd3759cb65..0692b8d5ac8b 100644 --- a/tests/pos/simpleCaseObject.decompiled +++ b/tests/pos/simpleCaseObject.decompiled @@ -2,9 +2,7 @@ out/posTestFromTasty/pos/simpleCaseObject/foo/Foo.class -------------------------------------------------------------------------------- package foo { - case object Foo() extends Object() with _root_.scala.Product { - this: foo.Foo.type => - + case object Foo() extends _root_.scala.Product { this: foo.Foo.type => override def hashCode(): Int = 1045991777 override def toString(): String = "Foo" override def canEqual(that: Any): Boolean = that.isInstanceOf[foo.Foo] diff --git a/tests/pos/simpleClass-2.decompiled b/tests/pos/simpleClass-2.decompiled index 78291f123ca2..23e04b8e8701 100644 --- a/tests/pos/simpleClass-2.decompiled +++ b/tests/pos/simpleClass-2.decompiled @@ -9,6 +9,6 @@ package foo { out/posTestFromTasty/pos/simpleClass-2/foo/B.class -------------------------------------------------------------------------------- package foo { - class B() extends Object() {} + class B() {} } -------------------------------------------------------------------------------- \ No newline at end of file diff --git a/tests/pos/simpleClass.decompiled b/tests/pos/simpleClass.decompiled index f671605a89c7..814df8bceddc 100644 --- a/tests/pos/simpleClass.decompiled +++ b/tests/pos/simpleClass.decompiled @@ -2,7 +2,7 @@ out/posTestFromTasty/pos/simpleClass/foo/A.class -------------------------------------------------------------------------------- package foo { - class A() extends Object() {} + class A() {} } -------------------------------------------------------------------------------- ================================================================================ diff --git a/tests/pos/simpleDoWhile.decompiled b/tests/pos/simpleDoWhile.decompiled index d1629e0ccecd..811801631451 100644 --- a/tests/pos/simpleDoWhile.decompiled +++ b/tests/pos/simpleDoWhile.decompiled @@ -1,7 +1,7 @@ ================================================================================ out/posTestFromTasty/pos/simpleDoWhile/Foo.class -------------------------------------------------------------------------------- -class Foo() extends Object() { +class Foo() { def foo: Unit = { var i: Int = 1 diff --git a/tests/pos/simpleWhile.decompiled b/tests/pos/simpleWhile.decompiled index 4cea6bebfaa8..8ae185525386 100644 --- a/tests/pos/simpleWhile.decompiled +++ b/tests/pos/simpleWhile.decompiled @@ -1,7 +1,7 @@ ================================================================================ out/posTestFromTasty/pos/simpleWhile/Foo.class -------------------------------------------------------------------------------- -class Foo() extends Object() { +class Foo() { def foo: Unit = { var i: Int = 1 diff --git a/tests/run/puzzle.decompiled b/tests/run/puzzle.decompiled index ff9220b317d0..870c215b4a1d 100644 --- a/tests/run/puzzle.decompiled +++ b/tests/run/puzzle.decompiled @@ -1,7 +1,7 @@ ================================================================================ out/runTestFromTasty/run/puzzle/Test.class -------------------------------------------------------------------------------- -object Test() extends Object() { this: Test.type => +object Test() { this: Test.type => def main(args: Array[String]): Unit = { println(if false then 5.0 else 53.0) From b78ca99ca62e62ff4628ee0fb5b01a7079649cdf Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 5 Apr 2018 17:02:09 +0200 Subject: [PATCH 4/4] Simpify code --- .../src/dotty/tools/dotc/printing/DecompilerPrinter.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala b/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala index 081075e6c434..9e3c520985de 100644 --- a/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala @@ -39,7 +39,7 @@ class DecompilerPrinter(_ctx: Context) extends RefinedPrinter(_ctx) { if (tree.pid.symbol.isEmptyPackage) statsText else if (currentPrecedence == TopLevelPrec) "\n" ~ statsText else " {" ~ statsText ~ "}" - (keywordStr("package ") ~ toTextPackageId(tree.pid)).provided(!tree.pid.symbol.isEmptyPackage) ~ bodyText + (keywordStr("package ") ~ toTextPackageId(tree.pid)).provided(!tree.symbol.isEmptyPackage) ~ bodyText } override protected def templateText(tree: TypeDef, impl: Template): Text = { @@ -50,8 +50,7 @@ class DecompilerPrinter(_ctx: Context) extends RefinedPrinter(_ctx) { } override protected def toTextTemplate(impl: Template, ofNew: Boolean = false): Text = { - val Template(constr, parents, self, preBody) = impl - val impl1 = Template(constr, parents.filterNot(_.symbol.maybeOwner == defn.ObjectClass), self, preBody) + val impl1 = impl.copy(parents = impl.parents.filterNot(_.symbol.maybeOwner == defn.ObjectClass)) super.toTextTemplate(impl1, ofNew) }