Skip to content

Commit c225b1a

Browse files
Merge pull request #4705 from dotty-staging/decompiled-print-constructor-vals
Print `val` for class parameters
2 parents 497efb9 + a62585c commit c225b1a

File tree

4 files changed

+135
-24
lines changed

4 files changed

+135
-24
lines changed

library/src/scala/tasty/util/ShowSourceCode.scala

Lines changed: 81 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
4141
this += ")"
4242
}
4343

44-
def inSquareParens(body: => Unit): Buffer = {
44+
def inSquare(body: => Unit): Buffer = {
4545
this += "["
4646
body
4747
this += "]"
@@ -126,7 +126,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
126126
def printParent(parent: Parent): Unit = parent match {
127127
case parent @ Term.TypeApply(fun, targs) =>
128128
printParent(fun)
129-
inSquareParens(printTypeOrBoundsTrees(targs, ", "))
129+
inSquare(printTypeOrBoundsTrees(targs, ", "))
130130

131131
case parent @ Term.Apply(fun, args) =>
132132
printParent(fun)
@@ -215,6 +215,8 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
215215
if (flags.isImplicit) this += "implicit "
216216
if (flags.isOverride) this += "override "
217217

218+
printProtectedOrPrivate(vdef)
219+
218220
if (flags.isLazy) this += "lazy "
219221
if (vdef.flags.isMutable) this += "var "
220222
else this += "val "
@@ -242,12 +244,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
242244
case ddef @ DefDef(name, targs, argss, tpt, rhs) =>
243245
printDefAnnotations(ddef)
244246

247+
val isConstructor = name == "<init>"
248+
245249
val flags = ddef.flags
246250
if (flags.isImplicit) this += "implicit "
247251
if (flags.isInline) this += "inline "
248252
if (flags.isOverride) this += "override "
249253

250-
val isConstructor = name == "<init>"
254+
printProtectedOrPrivate(ddef)
251255

252256
this += "def " += (if (isConstructor) "this" else name)
253257
printTargsDefs(targs)
@@ -318,7 +322,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
318322
// type bounds already printed in `fn`
319323
this
320324
case _ =>
321-
inSquareParens(printTypeOrBoundsTrees(args, ", "))
325+
inSquare(printTypeOrBoundsTrees(args, ", "))
322326
}
323327

324328
case Term.Super(qual, idOpt) =>
@@ -329,7 +333,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
329333
this += "super"
330334
for (id <- idOpt) {
331335
val Id(name) = id
332-
inSquareParens(this += name)
336+
inSquare(this += name)
333337
}
334338
this
335339

@@ -549,7 +553,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
549553
printSeparated(xs)
550554
}
551555

552-
inSquareParens(printSeparated(targs))
556+
inSquare(printSeparated(targs))
553557
}
554558
}
555559

@@ -578,7 +582,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
578582
this += ", "
579583
printSeparated(xs)
580584
}
581-
inSquareParens(printSeparated(tparams))
585+
inSquare(printSeparated(tparams))
582586
if (isMember) {
583587
this += " = "
584588
printTypeOrBoundsTree(body)
@@ -600,9 +604,9 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
600604

601605
def printSeparated(list: List[ValDef]): Unit = list match {
602606
case Nil =>
603-
case x :: Nil => printArgDef(x)
607+
case x :: Nil => printParamDef(x)
604608
case x :: xs =>
605-
printArgDef(x)
609+
printParamDef(x)
606610
this += ", "
607611
printSeparated(xs)
608612
}
@@ -623,8 +627,28 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
623627
this
624628
}
625629

626-
def printArgDef(arg: ValDef): Unit = {
630+
def printParamDef(arg: ValDef): Unit = {
627631
val ValDef(name, tpt, rhs) = arg
632+
arg.owner match {
633+
case DefDef("<init>", _, _, _, _) =>
634+
val ClassDef(_, _, _, _, body) = arg.owner.owner
635+
body.collectFirst {
636+
case vdef @ ValDef(`name`, _, _) if vdef.flags.isParamAccessor =>
637+
if (!vdef.flags.isLocal) {
638+
var printedPrefix = false
639+
if (vdef.flags.isOverride) {
640+
this += "override "
641+
printedPrefix = true
642+
}
643+
printedPrefix |= printProtectedOrPrivate(vdef)
644+
if (vdef.flags.isMutable) this += "var "
645+
else if (printedPrefix || !vdef.flags.isCaseAcessor) this += "val "
646+
else this // val not explicitly needed
647+
}
648+
}
649+
case _ =>
650+
}
651+
628652
this += name += ": "
629653
printTypeTree(tpt)
630654
}
@@ -704,7 +728,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
704728
case Constant.String(v) => this += '"' += escapedString(v) += '"'
705729
case Constant.ClassTag(v) =>
706730
this += "classOf"
707-
inSquareParens(printType(v))
731+
inSquare(printType(v))
708732
}
709733

710734
def printTypeOrBoundsTree(tpt: TypeOrBoundsTree): Buffer = tpt match {
@@ -761,7 +785,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
761785

762786
case TypeTree.Applied(tpt, args) =>
763787
printTypeTree(tpt)
764-
inSquareParens(printTypeOrBoundsTrees(args, ", "))
788+
inSquare(printTypeOrBoundsTrees(args, ", "))
765789

766790
case TypeTree.Annotated(tpt, annot) =>
767791
val Annotation(ref, args) = annot
@@ -852,7 +876,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
852876
this += "_*"
853877
case _ =>
854878
printType(tp)
855-
inSquareParens(printTypesOrBounds(args, ", "))
879+
inSquare(printTypesOrBounds(args, ", "))
856880
}
857881

858882
case Type.AnnotatedType(tp, annot) =>
@@ -877,21 +901,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
877901

878902
case Type.ThisType(tp) =>
879903
tp match {
880-
case Type.SymRef(cdef @ ClassDef(name, _, _, _, _), prefix) if !cdef.flags.isObject =>
881-
def printPrefix(prefix: TypeOrBounds): Unit = prefix match {
882-
case Type.SymRef(ClassDef(name, _, _, _, _), prefix2) =>
883-
printPrefix(prefix2)
884-
this += name += "."
885-
case _ =>
886-
}
887-
printPrefix(prefix)
888-
this += name
904+
case Type.SymRef(cdef @ ClassDef(_, _, _, _, _), _) if !cdef.flags.isObject =>
905+
printFullClassName(tp)
889906
this += ".this"
890907
case _ => printType(tp)
891908
}
892909

893910
case Type.TypeLambda(paramNames, tparams, body) =>
894-
inSquareParens(printMethodicTypeParams(paramNames, tparams))
911+
inSquare(printMethodicTypeParams(paramNames, tparams))
895912
this += " => "
896913
printTypeOrBound(body)
897914

@@ -948,7 +965,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
948965
inParens(printMethodicTypeParams(paramNames, params))
949966
printMethodicType(res)
950967
case tp @ Type.TypeLambda(paramNames, params, res) =>
951-
inSquareParens(printMethodicTypeParams(paramNames, params))
968+
inSquare(printMethodicTypeParams(paramNames, params))
952969
printMethodicType(res)
953970
case Type.ByNameType(t) =>
954971
this += ": "
@@ -1027,6 +1044,46 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
10271044
printType(hi)
10281045
}
10291046

1047+
def printProtectedOrPrivate(definition: Definition): Boolean = {
1048+
var prefixWasPrinted = false
1049+
def printWithin(within: Type) = within match {
1050+
case Type.SymRef(PackageDef(name, _), _) => this += name
1051+
case _ => printFullClassName(within)
1052+
}
1053+
if (definition.flags.isProtected) {
1054+
this += "protected"
1055+
definition.protectedWithin match {
1056+
case Some(within) =>
1057+
inSquare(printWithin(within))
1058+
case _ =>
1059+
}
1060+
prefixWasPrinted = true
1061+
} else {
1062+
definition.privateWithin match {
1063+
case Some(within) =>
1064+
this += "private"
1065+
inSquare(printWithin(within))
1066+
prefixWasPrinted = true
1067+
case _ =>
1068+
}
1069+
}
1070+
if (prefixWasPrinted)
1071+
this += " "
1072+
prefixWasPrinted
1073+
}
1074+
1075+
def printFullClassName(tp: TypeOrBounds): Unit = {
1076+
def printClassPrefix(prefix: TypeOrBounds): Unit = prefix match {
1077+
case Type.SymRef(ClassDef(name, _, _, _, _), prefix2) =>
1078+
printClassPrefix(prefix2)
1079+
this += name += "."
1080+
case _ =>
1081+
}
1082+
val Type.SymRef(ClassDef(name, _, _, _, _), prefix) = tp
1083+
printClassPrefix(prefix)
1084+
this += name
1085+
}
1086+
10301087
def +=(x: Boolean): this.type = { sb.append(x); this }
10311088
def +=(x: Byte): this.type = { sb.append(x); this }
10321089
def +=(x: Short): this.type = { sb.append(x); this }
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/** Decompiled from out/posTestFromTasty/pos/simpleConstructor/A.class */
2+
class A(a: scala.Int, val b: scala.Int, var c: scala.Int)
3+
/** Decompiled from out/posTestFromTasty/pos/simpleConstructor/B.class */
4+
class B(protected val x: scala.Int, protected[B] val y: scala.Int, private[B] val z: scala.Int)

tests/pos/simpleConstructor.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
class A(a: Int, val b: Int, var c: Int)
3+
4+
class B(protected val x: Int, protected[B] val y: Int, private[B] val z: Int)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/** Decompiled from out/runTestFromTasty/run/valueclasses-pavlov/Box1.class */
2+
final class Box1(val value: scala.Predef.String) extends scala.AnyVal() {
3+
override def hashCode(): scala.Int = Box1.this.value.hashCode()
4+
override def equals(x$0: scala.Any): scala.Boolean = x$0 match {
5+
case x$0: Box1 @scala.unchecked() =>
6+
Box1.this.value.==(x$0.value)
7+
case _ =>
8+
false
9+
}
10+
}
11+
object Box1 extends scala.AnyRef()
12+
/** Decompiled from out/runTestFromTasty/run/valueclasses-pavlov/Box2.class */
13+
final class Box2(val value: scala.Predef.String) extends scala.AnyVal() with Foo {
14+
def box1(x: Box1): scala.Predef.String = "box1: ok"
15+
def box2(x: Box2): scala.Predef.String = "box2: ok"
16+
override def hashCode(): scala.Int = Box2.this.value.hashCode()
17+
override def equals(x$0: scala.Any): scala.Boolean = x$0 match {
18+
case x$0: Box2 @scala.unchecked() =>
19+
Box2.this.value.==(x$0.value)
20+
case _ =>
21+
false
22+
}
23+
}
24+
object Box2 extends scala.AnyRef()
25+
/** Decompiled from out/runTestFromTasty/run/valueclasses-pavlov/C.class */
26+
class C(x: scala.Predef.String) {
27+
def this() = {
28+
this("")
29+
()
30+
}
31+
}
32+
/** Decompiled from out/runTestFromTasty/run/valueclasses-pavlov/Foo.class */
33+
trait Foo() extends scala.Any {
34+
def box1(x: Box1): scala.Predef.String
35+
def box2(x: Box2): scala.Predef.String
36+
}
37+
/** Decompiled from out/runTestFromTasty/run/valueclasses-pavlov/Test.class */
38+
object Test {
39+
def main(args: scala.Array[scala.Predef.String]): scala.Unit = {
40+
val b1: Box1 = new Box1("")
41+
val b2: Box2 = new Box2("")
42+
val f: Foo = b2
43+
scala.Predef.println(f.box1(b1))
44+
scala.Predef.println(f.box2(b2))
45+
}
46+
}

0 commit comments

Comments
 (0)