From 8c770816babe0b7c506e2e20ff4deb05479d8cde Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 22 Jun 2018 11:13:27 +0200 Subject: [PATCH 1/2] Print `val` for class parameters --- .../src/scala/tasty/util/ShowSourceCode.scala | 11 +++++ tests/run/valueclasses-pavlov.decompiled | 46 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 tests/run/valueclasses-pavlov.decompiled diff --git a/library/src/scala/tasty/util/ShowSourceCode.scala b/library/src/scala/tasty/util/ShowSourceCode.scala index a5de429c1a46..9ff631163bd0 100644 --- a/library/src/scala/tasty/util/ShowSourceCode.scala +++ b/library/src/scala/tasty/util/ShowSourceCode.scala @@ -625,6 +625,17 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty def printArgDef(arg: ValDef): Unit = { val ValDef(name, tpt, rhs) = arg + arg.owner match { + case DefDef("", _, _, _, _) => + val ClassDef(_, _, _, _, body) = arg.owner.owner + body.collectFirst { + case vdef @ ValDef(`name`, _, _) if vdef.flags.isParamAccessor => + if (!vdef.flags.isLocal && !vdef.flags.isCaseAcessor) + this += "val " // TODO `var`s + } + case _ => + } + this += name += ": " printTypeTree(tpt) } diff --git a/tests/run/valueclasses-pavlov.decompiled b/tests/run/valueclasses-pavlov.decompiled new file mode 100644 index 000000000000..fbf972b03c32 --- /dev/null +++ b/tests/run/valueclasses-pavlov.decompiled @@ -0,0 +1,46 @@ +/** Decompiled from out/runTestFromTasty/run/valueclasses-pavlov/Box1.class */ +final class Box1(val value: scala.Predef.String) extends scala.AnyVal() { + override def hashCode(): scala.Int = Box1.this.value.hashCode() + override def equals(x$0: scala.Any): scala.Boolean = x$0 match { + case x$0: Box1 @scala.unchecked() => + Box1.this.value.==(x$0.value) + case _ => + false + } +} +object Box1 extends scala.AnyRef() +/** Decompiled from out/runTestFromTasty/run/valueclasses-pavlov/Box2.class */ +final class Box2(val value: scala.Predef.String) extends scala.AnyVal() with Foo { + def box1(x: Box1): scala.Predef.String = "box1: ok" + def box2(x: Box2): scala.Predef.String = "box2: ok" + override def hashCode(): scala.Int = Box2.this.value.hashCode() + override def equals(x$0: scala.Any): scala.Boolean = x$0 match { + case x$0: Box2 @scala.unchecked() => + Box2.this.value.==(x$0.value) + case _ => + false + } +} +object Box2 extends scala.AnyRef() +/** Decompiled from out/runTestFromTasty/run/valueclasses-pavlov/C.class */ +class C(x: scala.Predef.String) { + def this() = { + this("") + () + } +} +/** Decompiled from out/runTestFromTasty/run/valueclasses-pavlov/Foo.class */ +trait Foo() extends scala.Any { + def box1(x: Box1): scala.Predef.String + def box2(x: Box2): scala.Predef.String +} +/** Decompiled from out/runTestFromTasty/run/valueclasses-pavlov/Test.class */ +object Test { + def main(args: scala.Array[scala.Predef.String]): scala.Unit = { + val b1: Box1 = new Box1("") + val b2: Box2 = new Box2("") + val f: Foo = b2 + scala.Predef.println(f.box1(b1)) + scala.Predef.println(f.box2(b2)) + } +} From a62585cac00e770b1f9028e2a7c1c7b54d3372ca Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 22 Jun 2018 14:56:14 +0200 Subject: [PATCH 2/2] Print vars, protected and private --- .../src/scala/tasty/util/ShowSourceCode.scala | 98 ++++++++++++++----- tests/pos/simpleConstructor.decompiled | 4 + tests/pos/simpleConstructor.scala | 4 + 3 files changed, 80 insertions(+), 26 deletions(-) create mode 100644 tests/pos/simpleConstructor.decompiled create mode 100644 tests/pos/simpleConstructor.scala diff --git a/library/src/scala/tasty/util/ShowSourceCode.scala b/library/src/scala/tasty/util/ShowSourceCode.scala index 9ff631163bd0..06d0287a19bd 100644 --- a/library/src/scala/tasty/util/ShowSourceCode.scala +++ b/library/src/scala/tasty/util/ShowSourceCode.scala @@ -41,7 +41,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty this += ")" } - def inSquareParens(body: => Unit): Buffer = { + def inSquare(body: => Unit): Buffer = { this += "[" body this += "]" @@ -126,7 +126,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty def printParent(parent: Parent): Unit = parent match { case parent @ Term.TypeApply(fun, targs) => printParent(fun) - inSquareParens(printTypeOrBoundsTrees(targs, ", ")) + inSquare(printTypeOrBoundsTrees(targs, ", ")) case parent @ Term.Apply(fun, args) => printParent(fun) @@ -215,6 +215,8 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty if (flags.isImplicit) this += "implicit " if (flags.isOverride) this += "override " + printProtectedOrPrivate(vdef) + if (flags.isLazy) this += "lazy " if (vdef.flags.isMutable) this += "var " else this += "val " @@ -242,12 +244,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case ddef @ DefDef(name, targs, argss, tpt, rhs) => printDefAnnotations(ddef) + val isConstructor = name == "" + val flags = ddef.flags if (flags.isImplicit) this += "implicit " if (flags.isInline) this += "inline " if (flags.isOverride) this += "override " - val isConstructor = name == "" + printProtectedOrPrivate(ddef) this += "def " += (if (isConstructor) "this" else name) printTargsDefs(targs) @@ -318,7 +322,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty // type bounds already printed in `fn` this case _ => - inSquareParens(printTypeOrBoundsTrees(args, ", ")) + inSquare(printTypeOrBoundsTrees(args, ", ")) } case Term.Super(qual, idOpt) => @@ -329,7 +333,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty this += "super" for (id <- idOpt) { val Id(name) = id - inSquareParens(this += name) + inSquare(this += name) } this @@ -549,7 +553,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty printSeparated(xs) } - inSquareParens(printSeparated(targs)) + inSquare(printSeparated(targs)) } } @@ -578,7 +582,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty this += ", " printSeparated(xs) } - inSquareParens(printSeparated(tparams)) + inSquare(printSeparated(tparams)) if (isMember) { this += " = " printTypeOrBoundsTree(body) @@ -600,9 +604,9 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty def printSeparated(list: List[ValDef]): Unit = list match { case Nil => - case x :: Nil => printArgDef(x) + case x :: Nil => printParamDef(x) case x :: xs => - printArgDef(x) + printParamDef(x) this += ", " printSeparated(xs) } @@ -623,15 +627,24 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty this } - def printArgDef(arg: ValDef): Unit = { + def printParamDef(arg: ValDef): Unit = { val ValDef(name, tpt, rhs) = arg arg.owner match { case DefDef("", _, _, _, _) => val ClassDef(_, _, _, _, body) = arg.owner.owner body.collectFirst { case vdef @ ValDef(`name`, _, _) if vdef.flags.isParamAccessor => - if (!vdef.flags.isLocal && !vdef.flags.isCaseAcessor) - this += "val " // TODO `var`s + if (!vdef.flags.isLocal) { + var printedPrefix = false + if (vdef.flags.isOverride) { + this += "override " + printedPrefix = true + } + printedPrefix |= printProtectedOrPrivate(vdef) + if (vdef.flags.isMutable) this += "var " + else if (printedPrefix || !vdef.flags.isCaseAcessor) this += "val " + else this // val not explicitly needed + } } case _ => } @@ -715,7 +728,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case Constant.String(v) => this += '"' += escapedString(v) += '"' case Constant.ClassTag(v) => this += "classOf" - inSquareParens(printType(v)) + inSquare(printType(v)) } def printTypeOrBoundsTree(tpt: TypeOrBoundsTree): Buffer = tpt match { @@ -772,7 +785,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case TypeTree.Applied(tpt, args) => printTypeTree(tpt) - inSquareParens(printTypeOrBoundsTrees(args, ", ")) + inSquare(printTypeOrBoundsTrees(args, ", ")) case TypeTree.Annotated(tpt, annot) => val Annotation(ref, args) = annot @@ -863,7 +876,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty this += "_*" case _ => printType(tp) - inSquareParens(printTypesOrBounds(args, ", ")) + inSquare(printTypesOrBounds(args, ", ")) } case Type.AnnotatedType(tp, annot) => @@ -888,21 +901,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case Type.ThisType(tp) => tp match { - case Type.SymRef(cdef @ ClassDef(name, _, _, _, _), prefix) if !cdef.flags.isObject => - def printPrefix(prefix: TypeOrBounds): Unit = prefix match { - case Type.SymRef(ClassDef(name, _, _, _, _), prefix2) => - printPrefix(prefix2) - this += name += "." - case _ => - } - printPrefix(prefix) - this += name + case Type.SymRef(cdef @ ClassDef(_, _, _, _, _), _) if !cdef.flags.isObject => + printFullClassName(tp) this += ".this" case _ => printType(tp) } case Type.TypeLambda(paramNames, tparams, body) => - inSquareParens(printMethodicTypeParams(paramNames, tparams)) + inSquare(printMethodicTypeParams(paramNames, tparams)) this += " => " printTypeOrBound(body) @@ -959,7 +965,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty inParens(printMethodicTypeParams(paramNames, params)) printMethodicType(res) case tp @ Type.TypeLambda(paramNames, params, res) => - inSquareParens(printMethodicTypeParams(paramNames, params)) + inSquare(printMethodicTypeParams(paramNames, params)) printMethodicType(res) case Type.ByNameType(t) => this += ": " @@ -1038,6 +1044,46 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty printType(hi) } + def printProtectedOrPrivate(definition: Definition): Boolean = { + var prefixWasPrinted = false + def printWithin(within: Type) = within match { + case Type.SymRef(PackageDef(name, _), _) => this += name + case _ => printFullClassName(within) + } + if (definition.flags.isProtected) { + this += "protected" + definition.protectedWithin match { + case Some(within) => + inSquare(printWithin(within)) + case _ => + } + prefixWasPrinted = true + } else { + definition.privateWithin match { + case Some(within) => + this += "private" + inSquare(printWithin(within)) + prefixWasPrinted = true + case _ => + } + } + if (prefixWasPrinted) + this += " " + prefixWasPrinted + } + + def printFullClassName(tp: TypeOrBounds): Unit = { + def printClassPrefix(prefix: TypeOrBounds): Unit = prefix match { + case Type.SymRef(ClassDef(name, _, _, _, _), prefix2) => + printClassPrefix(prefix2) + this += name += "." + case _ => + } + val Type.SymRef(ClassDef(name, _, _, _, _), prefix) = tp + printClassPrefix(prefix) + this += name + } + 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/simpleConstructor.decompiled b/tests/pos/simpleConstructor.decompiled new file mode 100644 index 000000000000..26bded3333b0 --- /dev/null +++ b/tests/pos/simpleConstructor.decompiled @@ -0,0 +1,4 @@ +/** Decompiled from out/posTestFromTasty/pos/simpleConstructor/A.class */ +class A(a: scala.Int, val b: scala.Int, var c: scala.Int) +/** Decompiled from out/posTestFromTasty/pos/simpleConstructor/B.class */ +class B(protected val x: scala.Int, protected[B] val y: scala.Int, private[B] val z: scala.Int) diff --git a/tests/pos/simpleConstructor.scala b/tests/pos/simpleConstructor.scala new file mode 100644 index 000000000000..3aee4b01124d --- /dev/null +++ b/tests/pos/simpleConstructor.scala @@ -0,0 +1,4 @@ + +class A(a: Int, val b: Int, var c: Int) + +class B(protected val x: Int, protected[B] val y: Int, private[B] val z: Int)