From 93f03072e4e07ec60e2cae204b4e5054afc15d6a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 20 Jun 2018 08:57:26 +0200 Subject: [PATCH 1/5] Print local type parameters without prefix --- library/src/scala/tasty/util/ShowSourceCode.scala | 10 ++++++---- tests/pos/i2104b.decompiled | 4 ++-- tests/pos/simpleCaseClass-3.decompiled | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/library/src/scala/tasty/util/ShowSourceCode.scala b/library/src/scala/tasty/util/ShowSourceCode.scala index d57cb8233f2c..1754cada4410 100644 --- a/library/src/scala/tasty/util/ShowSourceCode.scala +++ b/library/src/scala/tasty/util/ShowSourceCode.scala @@ -793,12 +793,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case Type.SymRef(sym, prefix) => prefix match { case Types.EmptyPrefix() => - case prefix@Type.SymRef(ClassDef(_, _, _, _, _), _) => + case prefix @ Type.SymRef(ClassDef(_, _, _, _, _), _) => printType(prefix) this += "#" - case prefix@Type() => - printType(prefix) - this += "." + case prefix @ Type() => + if (!sym.flags.isLocal) { + printType(prefix) + this += "." + } } printDefinitionName(sym) diff --git a/tests/pos/i2104b.decompiled b/tests/pos/i2104b.decompiled index 782d80666748..ead2eb68cd7c 100644 --- a/tests/pos/i2104b.decompiled +++ b/tests/pos/i2104b.decompiled @@ -13,13 +13,13 @@ case class Pair[A, B](_1: A, _2: B) { scala.runtime.Statics.finalizeHash(acc, 2) } override def equals(x$0: scala.Any): scala.Boolean = this.eq(x$0.asInstanceOf[java.lang.Object]).||(x$0 match { - case x$0: Pair[Pair.this.A, Pair.this.B] @scala.unchecked() => + case x$0: Pair[A, B] @scala.unchecked() => this._1.==(x$0._1).&&(this._2.==(x$0._2)) case _ => false }) override def toString(): java.lang.String = scala.runtime.ScalaRunTime._toString(this) - override def canEqual(that: scala.Any): scala.Boolean = that.isInstanceOf[Pair[Pair.this.A, Pair.this.B] @scala.unchecked()] + override def canEqual(that: scala.Any): scala.Boolean = that.isInstanceOf[Pair[A, B] @scala.unchecked()] override def productArity: scala.Int = 2 override def productPrefix: java.lang.String = "Pair" override def productElement(n: scala.Int): scala.Any = n match { diff --git a/tests/pos/simpleCaseClass-3.decompiled b/tests/pos/simpleCaseClass-3.decompiled index f41807b184c5..cf6fe29cf6c5 100644 --- a/tests/pos/simpleCaseClass-3.decompiled +++ b/tests/pos/simpleCaseClass-3.decompiled @@ -6,13 +6,13 @@ case class A[T](x: T) { scala.runtime.Statics.finalizeHash(acc, 1) } override def equals(x$0: scala.Any): scala.Boolean = this.eq(x$0.asInstanceOf[java.lang.Object]).||(x$0 match { - case x$0: A[A.this.T] @scala.unchecked() => + case x$0: A[T] @scala.unchecked() => this.x.==(x$0.x) case _ => false }) override def toString(): java.lang.String = scala.runtime.ScalaRunTime._toString(this) - override def canEqual(that: scala.Any): scala.Boolean = that.isInstanceOf[A[A.this.T] @scala.unchecked()] + override def canEqual(that: scala.Any): scala.Boolean = that.isInstanceOf[A[T] @scala.unchecked()] override def productArity: scala.Int = 1 override def productPrefix: java.lang.String = "A" override def productElement(n: scala.Int): scala.Any = n match { From 127b07b46a1b02cd0f9a775aadaa6a708233728b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 20 Jun 2018 09:48:34 +0200 Subject: [PATCH 2/5] Print type refinements --- .../src/scala/tasty/util/ShowSourceCode.scala | 138 +++++++++++++----- tests/pos/simpleRefinement.decompiled | 49 +++++++ tests/pos/simpleRefinement.scala | 26 ++++ tests/run-with-compiler/i3876-c.check | 4 +- 4 files changed, 177 insertions(+), 40 deletions(-) create mode 100644 tests/pos/simpleRefinement.decompiled create mode 100644 tests/pos/simpleRefinement.scala diff --git a/library/src/scala/tasty/util/ShowSourceCode.scala b/library/src/scala/tasty/util/ShowSourceCode.scala index 1754cada4410..9911ba08597d 100644 --- a/library/src/scala/tasty/util/ShowSourceCode.scala +++ b/library/src/scala/tasty/util/ShowSourceCode.scala @@ -74,6 +74,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty if (flags.isObject) this += "object " += name.stripSuffix("$") else if (flags.isTrait) this += "trait " += name + else if (flags.isAbstract) this += "abstract class " += name else this += "class " += name if (!flags.isObject) { @@ -504,29 +505,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty def printTargDef(arg: TypeDef, isMember: Boolean = false): Buffer = { val TypeDef(name, rhs) = arg - def printBounds(bounds: TypeBoundsTree): Buffer = { - val TypeBoundsTree(lo, hi) = bounds - lo match { - case TypeTree.Synthetic() => - case _ => - this += " >: " - printTypeTree(lo) - } - hi match { - case TypeTree.Synthetic() => this - case _ => - this += " <: " - printTypeTree(hi) - } - } this += name rhs match { - case rhs @ TypeBoundsTree(lo, hi) => printBounds(rhs) + case rhs @ TypeBoundsTree(lo, hi) => printBoundsTree(rhs) case rhs @ SyntheticBounds() => printTypeOrBound(rhs.tpe) case rhs @ TypeTree.TypeLambdaTree(tparams, body) => def printParam(t: TypeOrBoundsTree): Unit = t match { - case t @ TypeBoundsTree(_, _) => printBounds(t) + case t @ TypeBoundsTree(_, _) => printBoundsTree(t) case t @ TypeTree() => printTypeTree(t) } def printSeparated(list: List[TypeDef]): Unit = list match { @@ -824,9 +810,50 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty } this += name.stripSuffix("$") - case Type.Refinement(parent, name, info) => - printType(parent) - // TODO add refinements + case tpe @ Type.Refinement(_, _, _) => + def rec(tp: Type): Unit = tp match { + case Type.Refinement(parent, name, info) => + rec(parent) + indented { + this += lineBreak() + info match { + case info @ TypeBounds(_, _) => + this += "type " += name + printBounds(info) + case info @ Type() => + info match { + case Type.ByNameType(_) | Type.MethodType(_, _, _) | Type.TypeLambda(_, _, _) => + this += "def " += name + case _ => + this += "val " += name + } + def printMethodicType(tp: Type): Unit = tp match { + case tp @ Type.MethodType(paramNames, params, res) => + this += "(" + printMethodicTypeParams(paramNames, params) + this += ")" + printMethodicType(res) + case tp @ Type.TypeLambda(paramNames, params, res) => + this += "[" + printMethodicTypeParams(paramNames, params) + this += "]" + printMethodicType(res) + case Type.ByNameType(t) => + this += ": " + printType(t) + case tp @ Type() => + this += ": " + printType(tp) + } + printMethodicType(info) + } + } + case tp => + printType(tp) + this += " {" + } + rec(tpe) + this += lineBreak() += "}" case Type.AppliedType(tp, args) => printType(tp) @@ -861,27 +888,15 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case _ => this } + case Type.MethodType(paramNames, params, body) => + this += "(" + printMethodicTypeParams(paramNames, params) + this += ") => " + printTypeOrBound(body) + case Type.TypeLambda(paramNames, tparams, body) => this += "[" - def printBounds(bounds: TypeBounds): Buffer = { - val TypeBounds(lo, hi) = bounds - this += " >: " - printType(lo) - this += " <: " - printType(hi) - } - def printSeparated(list: List[(String, TypeBounds)]): Unit = list match { - case Nil => - case (name, bounds) :: Nil => - this += name - printBounds(bounds) - case (name, bounds) :: xs => - this += name - printBounds(bounds) - this += ", " - printSeparated(xs) - } - printSeparated(paramNames.zip(tparams)) + printMethodicTypeParams(paramNames, tparams) this += "] => " printTypeOrBound(body) @@ -934,6 +949,51 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty else this } + def printMethodicTypeParams(paramNames: List[String], params: List[TypeOrBounds]): Unit = { + def printInfo(info: TypeOrBounds) = info match { + case info @ TypeBounds(_, _) => printBounds(info) + case info @ Type() => + this += ": " + printType(info) + } + def printSeparated(list: List[(String, TypeOrBounds)]): Unit = list match { + case Nil => + case (name, info) :: Nil => + this += name + printInfo(info) + case (name, info) :: xs => + this += name + printInfo(info) + this += ", " + printSeparated(xs) + } + printSeparated(paramNames.zip(params)) + } + + def printBoundsTree(bounds: TypeBoundsTree): Buffer = { + val TypeBoundsTree(lo, hi) = bounds + lo match { + case TypeTree.Synthetic() => + case _ => + this += " >: " + printTypeTree(lo) + } + hi match { + case TypeTree.Synthetic() => this + case _ => + this += " <: " + printTypeTree(hi) + } + } + + def printBounds(bounds: TypeBounds): Buffer = { + val TypeBounds(lo, hi) = bounds + this += " >: " + printType(lo) + this += " <: " + printType(hi) + } + def +=(x: Boolean): this.type = { sb.append(x); this } def +=(x: Byte): this.type = { sb.append(x); this } def +=(x: Short): this.type = { sb.append(x); this } diff --git a/tests/pos/simpleRefinement.decompiled b/tests/pos/simpleRefinement.decompiled new file mode 100644 index 000000000000..72cb06c43840 --- /dev/null +++ b/tests/pos/simpleRefinement.decompiled @@ -0,0 +1,49 @@ +/** Decompiled from out/posTestFromTasty/pos/simpleRefinement/Bar.class */ +trait Bar() extends java.lang.Object { + type S + type T + type U <: [X] => scala.Any + val x: scala.Any + def y: scala.Any + def z(): scala.Any + def z2()(): scala.Any + def w[T]: scala.Any + def w2[T](a: scala.Null)(b: scala.Null): scala.Any +} +/** Decompiled from out/posTestFromTasty/pos/simpleRefinement/Foo.class */ +class Foo() { + val bar: Bar { + type S >: scala.Int <: scala.Int + type T >: scala.Function1[scala.Int, scala.Int] <: scala.Function1[scala.Int, scala.Int] + type U >: [X >: scala.Nothing <: scala.Any] => scala.Int <: [X >: scala.Nothing <: scala.Any] => scala.Int + val x: scala.Long + def y: scala.Boolean + def z(): scala.Char + def z2()(): scala.Char + def w[T >: scala.Nothing <: scala.Any]: scala.Predef.String + def w2[T >: scala.Nothing <: scala.Any](a: scala.Null)(b: scala.Null): scala.Null + } = { + final class $anon() extends Bar { + type S = scala.Int + type T = scala.Function1[scala.Int, scala.Int] + type U[X] = scala.Int + val x: scala.Long = 2L + def y: scala.Boolean = true + def z(): scala.Char = 'f' + def z2()(): scala.Char = 'g' + def w[T]: scala.Predef.String = "a" + def w2[T](a: scala.Null)(b: scala.Null): scala.Null = null + } + (new $anon(): Bar { + type S >: scala.Int <: scala.Int + type T >: scala.Function1[scala.Int, scala.Int] <: scala.Function1[scala.Int, scala.Int] + type U >: [X >: scala.Nothing <: scala.Any] => scala.Int <: [X >: scala.Nothing <: scala.Any] => scala.Int + val x: scala.Long + def y: scala.Boolean + def z(): scala.Char + def z2()(): scala.Char + def w[T >: scala.Nothing <: scala.Any]: scala.Predef.String + def w2[T >: scala.Nothing <: scala.Any](a: scala.Null)(b: scala.Null): scala.Null + }) + } +} diff --git a/tests/pos/simpleRefinement.scala b/tests/pos/simpleRefinement.scala new file mode 100644 index 000000000000..3b6500feddd3 --- /dev/null +++ b/tests/pos/simpleRefinement.scala @@ -0,0 +1,26 @@ + +class Foo { + val bar = new Bar { + type S = Int + type T = Int => Int + type U = [X] => Int + val x: Long = 2L + def y: Boolean = true + def z(): Char = 'f' + def z2()(): Char = 'g' + def w[T]: String = "a" + def w2[T](a: Null)(b: Null): Null = null + } +} + +trait Bar { + type S + type T + type U <: [X] => Any + val x: Any + def y: Any + def z(): Any + def z2()(): Any + def w[T]: Any + def w2[T](a: Null)(b: Null): Any +} diff --git a/tests/run-with-compiler/i3876-c.check b/tests/run-with-compiler/i3876-c.check index e298ecc3f648..54c77aeb94e6 100644 --- a/tests/run-with-compiler/i3876-c.check +++ b/tests/run-with-compiler/i3876-c.check @@ -4,5 +4,7 @@ val f: scala.Function1[scala.Int, scala.Int] { def apply(x: scala.Int): scala.Int } = ((x: scala.Int) => x.+(x)) - (f: scala.Function1[scala.Int, scala.Int]).apply(x$1) + (f: scala.Function1[scala.Int, scala.Int] { + def apply(x: scala.Int): scala.Int + }).apply(x$1) } From fd4317a6d154911f5c3ae369dacbf4fdbba7f361 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 21 Jun 2018 14:57:51 +0200 Subject: [PATCH 3/5] Add `sealed` --- library/src/scala/tasty/util/ShowSourceCode.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/library/src/scala/tasty/util/ShowSourceCode.scala b/library/src/scala/tasty/util/ShowSourceCode.scala index 9911ba08597d..7bb7aacad9b6 100644 --- a/library/src/scala/tasty/util/ShowSourceCode.scala +++ b/library/src/scala/tasty/util/ShowSourceCode.scala @@ -69,6 +69,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty val flags = cdef.flags if (flags.isImplicit) this += "implicit " + if (flags.isSealed) this += "sealed " if (flags.isFinal && !flags.isObject) this += "final " if (flags.isCase) this += "case " From 14a5ec5c3bc7d5dbdebdebd3087aa6c1d6c3749b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 21 Jun 2018 14:58:10 +0200 Subject: [PATCH 4/5] Refactor print refinements --- .../src/scala/tasty/util/ShowSourceCode.scala | 88 ++++++++++--------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/library/src/scala/tasty/util/ShowSourceCode.scala b/library/src/scala/tasty/util/ShowSourceCode.scala index 7bb7aacad9b6..954758752285 100644 --- a/library/src/scala/tasty/util/ShowSourceCode.scala +++ b/library/src/scala/tasty/util/ShowSourceCode.scala @@ -812,49 +812,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty this += name.stripSuffix("$") case tpe @ Type.Refinement(_, _, _) => - def rec(tp: Type): Unit = tp match { - case Type.Refinement(parent, name, info) => - rec(parent) - indented { - this += lineBreak() - info match { - case info @ TypeBounds(_, _) => - this += "type " += name - printBounds(info) - case info @ Type() => - info match { - case Type.ByNameType(_) | Type.MethodType(_, _, _) | Type.TypeLambda(_, _, _) => - this += "def " += name - case _ => - this += "val " += name - } - def printMethodicType(tp: Type): Unit = tp match { - case tp @ Type.MethodType(paramNames, params, res) => - this += "(" - printMethodicTypeParams(paramNames, params) - this += ")" - printMethodicType(res) - case tp @ Type.TypeLambda(paramNames, params, res) => - this += "[" - printMethodicTypeParams(paramNames, params) - this += "]" - printMethodicType(res) - case Type.ByNameType(t) => - this += ": " - printType(t) - case tp @ Type() => - this += ": " - printType(tp) - } - printMethodicType(info) - } - } - case tp => - printType(tp) - this += " {" - } - rec(tpe) - this += lineBreak() += "}" + printRefinement(tpe) case Type.AppliedType(tp, args) => printType(tp) @@ -950,6 +908,50 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty else this } + def printRefinement(tpe: Type): Buffer = { + def printMethodicType(tp: TypeOrBounds): Unit = tp match { + case tp @ Type.MethodType(paramNames, params, res) => + this += "(" + printMethodicTypeParams(paramNames, params) + this += ")" + printMethodicType(res) + case tp @ Type.TypeLambda(paramNames, params, res) => + this += "[" + printMethodicTypeParams(paramNames, params) + this += "]" + printMethodicType(res) + case Type.ByNameType(t) => + this += ": " + printType(t) + case tp @ Type() => + this += ": " + printType(tp) + } + def rec(tp: Type): Unit = tp match { + case Type.Refinement(parent, name, info) => + rec(parent) + indented { + this += lineBreak() + info match { + case info @ TypeBounds(_, _) => + this += "type " += name + printBounds(info) + case Type.ByNameType(_) | Type.MethodType(_, _, _) | Type.TypeLambda(_, _, _) => + this += "def " += name + printMethodicType(info) + case info @ Type() => + this += "val " += name + printMethodicType(info) + } + } + case tp => + printType(tp) + this += " {" + } + rec(tpe) + this += lineBreak() += "}" + } + def printMethodicTypeParams(paramNames: List[String], params: List[TypeOrBounds]): Unit = { def printInfo(info: TypeOrBounds) = info match { case info @ TypeBounds(_, _) => printBounds(info) From 1a2155805207149c6395bafc56f33a66bf99361f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 21 Jun 2018 14:59:37 +0200 Subject: [PATCH 5/5] Remove printing of MethodType outside refinements --- library/src/scala/tasty/util/ShowSourceCode.scala | 6 ------ 1 file changed, 6 deletions(-) diff --git a/library/src/scala/tasty/util/ShowSourceCode.scala b/library/src/scala/tasty/util/ShowSourceCode.scala index 954758752285..3ad84cbf880d 100644 --- a/library/src/scala/tasty/util/ShowSourceCode.scala +++ b/library/src/scala/tasty/util/ShowSourceCode.scala @@ -847,12 +847,6 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case _ => this } - case Type.MethodType(paramNames, params, body) => - this += "(" - printMethodicTypeParams(paramNames, params) - this += ") => " - printTypeOrBound(body) - case Type.TypeLambda(paramNames, tparams, body) => this += "[" printMethodicTypeParams(paramNames, tparams)