diff --git a/compiler/src/dotty/tools/dotc/decompiler/DecompilationPrinter.scala b/compiler/src/dotty/tools/dotc/decompiler/DecompilationPrinter.scala index ad95bcd57429..707f319dce51 100644 --- a/compiler/src/dotty/tools/dotc/decompiler/DecompilationPrinter.scala +++ b/compiler/src/dotty/tools/dotc/decompiler/DecompilationPrinter.scala @@ -41,7 +41,7 @@ class DecompilationPrinter extends Phase { new TastyPrinter(unit.pickled.head._2).printContents() } else { out.println(s"/** Decompiled from $unit */") - out.print(TastyImpl.showSourceCode.showTree(unit.tpdTree)(ctx)) + out.println(TastyImpl.showSourceCode.showTree(unit.tpdTree)(ctx)) } } } diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala index e5c824f06fc6..84420409b822 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala @@ -454,9 +454,10 @@ object TastyImpl extends scala.tasty.Tasty { type Pattern = tpd.Tree - def PatternDeco(x: Pattern): AbstractPattern = new AbstractPattern { - def pos(implicit ctx: Context): Position = x.pos - def tpe(implicit ctx: Context): Types.Type = x.tpe.stripTypeVar + def PatternDeco(pattern: Pattern): AbstractPattern = new AbstractPattern { + def show(implicit ctx: Context, s: Show[TastyImpl.this.type]): String = s.showPattern(pattern) + def pos(implicit ctx: Context): Position = pattern.pos + def tpe(implicit ctx: Context): Types.Type = pattern.tpe.stripTypeVar } def patternClassTag: ClassTag[Pattern] = implicitly[ClassTag[Pattern]] diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala index 03b260bf3aaa..7ae49e9467d8 100644 --- a/library/src/scala/tasty/Tasty.scala +++ b/library/src/scala/tasty/Tasty.scala @@ -324,7 +324,9 @@ abstract class Tasty { tasty => type Pattern - trait AbstractPattern extends Typed with Positioned + trait AbstractPattern extends Typed with Positioned { + def show(implicit ctx: Context, s: Show[tasty.type]): String + } implicit def PatternDeco(x: Pattern): AbstractPattern implicit def patternClassTag: ClassTag[Pattern] diff --git a/library/src/scala/tasty/util/Show.scala b/library/src/scala/tasty/util/Show.scala index 7d6f1cccf28b..e1beb41e59da 100644 --- a/library/src/scala/tasty/util/Show.scala +++ b/library/src/scala/tasty/util/Show.scala @@ -8,6 +8,8 @@ abstract class Show[T <: Tasty with Singleton](val tasty: T) { def showCaseDef(caseDef: tasty.CaseDef)(implicit ctx: tasty.Context): String + def showPattern(pattern: tasty.Pattern)(implicit ctx: tasty.Context): String + def showTypeOrBoundsTree(tpt: tasty.TypeOrBoundsTree)(implicit ctx: tasty.Context): String def showTypeOrBounds(tpe: tasty.TypeOrBounds)(implicit ctx: tasty.Context): String diff --git a/library/src/scala/tasty/util/ShowExtractors.scala b/library/src/scala/tasty/util/ShowExtractors.scala index 46dc8966478e..2edbdafb5f11 100644 --- a/library/src/scala/tasty/util/ShowExtractors.scala +++ b/library/src/scala/tasty/util/ShowExtractors.scala @@ -11,6 +11,9 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty def showCaseDef(caseDef: CaseDef)(implicit ctx: Context): String = new Buffer().visitCaseDef(caseDef).result() + def showPattern(pattern: tasty.Pattern)(implicit ctx: tasty.Context): String = + new Buffer().visitPattern(pattern).result() + def showTypeOrBoundsTree(tpt: TypeOrBoundsTree)(implicit ctx: Context): String = new Buffer().visitTypeTree(tpt).result() diff --git a/library/src/scala/tasty/util/ShowSourceCode.scala b/library/src/scala/tasty/util/ShowSourceCode.scala index 584880e5b8b2..7e3987a5a6a1 100644 --- a/library/src/scala/tasty/util/ShowSourceCode.scala +++ b/library/src/scala/tasty/util/ShowSourceCode.scala @@ -10,6 +10,9 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty def showCaseDef(caseDef: CaseDef)(implicit ctx: Context): String = (new Buffer).printCaseDef(caseDef).result() + def showPattern(pattern: Pattern)(implicit ctx: Context): String = + (new Buffer).printPattern(pattern).result() + def showTypeOrBoundsTree(tpt: TypeOrBoundsTree)(implicit ctx: Context): String = (new Buffer).printTypeOrBoundsTree(tpt).result() @@ -49,7 +52,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty this += lineBreak() printTrees(stats1, lineBreak()) } - this += lineBreak() += "}" += lineBreak() + this += lineBreak() += "}" } case Import(expr, selectors) => @@ -484,7 +487,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty this += " =>" indented { this += lineBreak() - printTree(body) + body match { + case Term.Block(stats, expr) => + printTrees(stats, lineBreak()) + printTree(expr) + case body => + printTree(body) + } } this } @@ -508,7 +517,11 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty printPattern(pattern) case Pattern.Unapply(fun, implicits, patterns) => - printTree(fun) + fun match { + case Term.Select(extractor, "unapply" | "unapplySeq", _) => printTree(extractor) + case Term.TypeApply(Term.Select(extractor, "unapply" | "unapplySeq", _), _) => printTree(extractor) + case _ => throw new MatchError(fun.show) + } this += "(" printPatterns(patterns, ", ") this += ")" @@ -517,7 +530,11 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty printPatterns(trees, " | ") case Pattern.TypeTest(tpt) => - this + this += "_: " + printTypeOrBoundsTree(tpt) + + case _ => + throw new MatchError(pattern.show) } @@ -541,8 +558,8 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty printTypeTree(lo) this += " <: " printTypeTree(hi) - case tpt@Type() => - printType(tpt) + case tpt @ TypeTree() => + printTypeTree(tpt) } def printTypeTree(tree: TypeTree): Buffer = tree match { @@ -628,7 +645,9 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case Type.TermRef(name, prefix) => prefix match { - case prefix@Type() => + case Type.ThisType(Types.EmptyPackage()) => + this += name + case prefix @ Type() => printType(prefix) if (name != "package") this += "." += name @@ -639,7 +658,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case Type.TypeRef(name, prefix) => prefix match { - case NoPrefix() => + case NoPrefix() | Type.ThisType(Types.EmptyPackage()) => case prefix@Type() => printType(prefix) this += "." diff --git a/tests/pos/simpleExractors.decompiled b/tests/pos/simpleExractors.decompiled new file mode 100644 index 000000000000..e432e5a99d65 --- /dev/null +++ b/tests/pos/simpleExractors.decompiled @@ -0,0 +1,35 @@ +/** Decompiled from out/posTestFromTasty/pos/simpleExractors/Bar.class */ +object Bar { + def unapply(arg: scala.Any): scala.Option[scala.Any] = scala.Some.apply[scala.Any](arg) +} +/** Decompiled from out/posTestFromTasty/pos/simpleExractors/BarSeq.class */ +object BarSeq { + def unapplySeq(arg: scala.Any): scala.Option[scala.Seq[scala.Any]] = scala.Some.apply[collection.immutable.List[scala.Any]](scala.List.apply[scala.Any](arg)) +} +/** Decompiled from out/posTestFromTasty/pos/simpleExractors/Baz.class */ +object Baz { + def unapply[T](arg: T): scala.Option[T] = scala.Some.apply[T](arg) +} +/** Decompiled from out/posTestFromTasty/pos/simpleExractors/BazSeq.class */ +object BazSeq { + def unapplySeq[T](arg: T): scala.Option[scala.Seq[T]] = scala.Some.apply[collection.immutable.List[T]](scala.List.apply[T](arg)) +} +/** Decompiled from out/posTestFromTasty/pos/simpleExractors/Foo.class */ +class Foo() { + def bar(x: scala.Any): scala.Unit = x match { + case Bar(a) => + scala.Predef.println(a) + case BarSeq(a) => + scala.Predef.println(a) + case BarSeq(a, b) => + scala.Predef.println(a) + } + def baz(x: scala.Any): scala.Unit = x match { + case Baz(a) => + scala.Predef.println(a) + case BazSeq(a) => + scala.Predef.println(a) + case BazSeq(a, b) => + scala.Predef.println(a) + } +} diff --git a/tests/pos/simpleExractors.scala b/tests/pos/simpleExractors.scala new file mode 100644 index 000000000000..05bde494079d --- /dev/null +++ b/tests/pos/simpleExractors.scala @@ -0,0 +1,28 @@ +class Foo { + def bar(x: Any): Unit = x match { + case Bar(a) => println(a) + case BarSeq(a) => println(a) + case BarSeq(a, b) => println(a) + } + def baz(x: Any): Unit = x match { + case Baz(a) => println(a) + case BazSeq(a) => println(a) + case BazSeq(a, b) => println(a) + } +} + +object Bar { + def unapply(arg: Any): Option[Any] = Some(arg) +} + +object BarSeq { + def unapplySeq(arg: Any): Option[Seq[Any]] = Some(List(arg)) +} + +object Baz { + def unapply[T](arg: T): Option[T] = Some(arg) +} + +object BazSeq { + def unapplySeq[T](arg: T): Option[Seq[T]] = Some(List(arg)) +} diff --git a/tests/run/tasty-custom-show/quoted_1.scala b/tests/run/tasty-custom-show/quoted_1.scala index ba50cfbb3f27..e7897f81ab7a 100644 --- a/tests/run/tasty-custom-show/quoted_1.scala +++ b/tests/run/tasty-custom-show/quoted_1.scala @@ -49,6 +49,7 @@ class DummyShow[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty0) { import tasty._ def showTree(tree: Tree)(implicit ctx: Context): String = "Tree" def showCaseDef(caseDef: CaseDef)(implicit ctx: Context): String = "CaseDef" + def showPattern(pattern: Pattern)(implicit ctx: Context): String = "Pattern" def showTypeOrBoundsTree(tpt: TypeOrBoundsTree)(implicit ctx: Context): String = "TypeOrBoundsTree" def showTypeOrBounds(tpe: TypeOrBounds)(implicit ctx: Context): String = "TypeOrBounds" def showConstant(const: Constant)(implicit ctx: Context): String = "Constant"