Skip to content

Commit fc6db4b

Browse files
Merge pull request #4698 from dotty-staging/print-refinements
Print decompiled refinements
2 parents 9d73a09 + 1a21558 commit fc6db4b

File tree

6 files changed

+184
-48
lines changed

6 files changed

+184
-48
lines changed

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

Lines changed: 102 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
7070

7171
val flags = cdef.flags
7272
if (flags.isImplicit) this += "implicit "
73+
if (flags.isSealed) this += "sealed "
7374
if (flags.isFinal && !flags.isObject) this += "final "
7475
if (flags.isCase) this += "case "
7576

7677
if (flags.isObject) this += "object " += name.stripSuffix("$")
7778
else if (flags.isTrait) this += "trait " += name
79+
else if (flags.isAbstract) this += "abstract class " += name
7880
else this += "class " += name
7981

8082
if (!flags.isObject) {
@@ -549,29 +551,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
549551

550552
def printTargDef(arg: TypeDef, isMember: Boolean = false): Buffer = {
551553
val TypeDef(name, rhs) = arg
552-
def printBounds(bounds: TypeBoundsTree): Buffer = {
553-
val TypeBoundsTree(lo, hi) = bounds
554-
lo match {
555-
case TypeTree.Synthetic() =>
556-
case _ =>
557-
this += " >: "
558-
printTypeTree(lo)
559-
}
560-
hi match {
561-
case TypeTree.Synthetic() => this
562-
case _ =>
563-
this += " <: "
564-
printTypeTree(hi)
565-
}
566-
}
567554
this += name
568555
rhs match {
569-
case rhs @ TypeBoundsTree(lo, hi) => printBounds(rhs)
556+
case rhs @ TypeBoundsTree(lo, hi) => printBoundsTree(rhs)
570557
case rhs @ SyntheticBounds() =>
571558
printTypeOrBound(rhs.tpe)
572559
case rhs @ TypeTree.TypeLambdaTree(tparams, body) =>
573560
def printParam(t: TypeOrBoundsTree): Unit = t match {
574-
case t @ TypeBoundsTree(_, _) => printBounds(t)
561+
case t @ TypeBoundsTree(_, _) => printBoundsTree(t)
575562
case t @ TypeTree() => printTypeTree(t)
576563
}
577564
def printSeparated(list: List[TypeDef]): Unit = list match {
@@ -835,12 +822,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
835822
case Type.SymRef(sym, prefix) =>
836823
prefix match {
837824
case Types.EmptyPrefix() =>
838-
case prefix@Type.SymRef(ClassDef(_, _, _, _, _), _) =>
825+
case prefix @ Type.SymRef(ClassDef(_, _, _, _, _), _) =>
839826
printType(prefix)
840827
this += "#"
841-
case prefix@Type() =>
842-
printType(prefix)
843-
this += "."
828+
case prefix @ Type() =>
829+
if (!sym.flags.isLocal) {
830+
printType(prefix)
831+
this += "."
832+
}
844833
}
845834
printDefinitionName(sym)
846835

@@ -864,9 +853,8 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
864853
}
865854
this += name.stripSuffix("$")
866855

867-
case Type.Refinement(parent, name, info) =>
868-
printType(parent)
869-
// TODO add refinements
856+
case tpe @ Type.Refinement(_, _, _) =>
857+
printRefinement(tpe)
870858

871859
case Type.AppliedType(tp, args) =>
872860
printType(tp)
@@ -911,25 +899,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
911899

912900
case Type.TypeLambda(paramNames, tparams, body) =>
913901
this += "["
914-
def printBounds(bounds: TypeBounds): Buffer = {
915-
val TypeBounds(lo, hi) = bounds
916-
this += " >: "
917-
printType(lo)
918-
this += " <: "
919-
printType(hi)
920-
}
921-
def printSeparated(list: List[(String, TypeBounds)]): Unit = list match {
922-
case Nil =>
923-
case (name, bounds) :: Nil =>
924-
this += name
925-
printBounds(bounds)
926-
case (name, bounds) :: xs =>
927-
this += name
928-
printBounds(bounds)
929-
this += ", "
930-
printSeparated(xs)
931-
}
932-
printSeparated(paramNames.zip(tparams))
902+
printMethodicTypeParams(paramNames, tparams)
933903
this += "] => "
934904
printTypeOrBound(body)
935905

@@ -982,6 +952,95 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
982952
else this
983953
}
984954

955+
def printRefinement(tpe: Type): Buffer = {
956+
def printMethodicType(tp: TypeOrBounds): Unit = tp match {
957+
case tp @ Type.MethodType(paramNames, params, res) =>
958+
this += "("
959+
printMethodicTypeParams(paramNames, params)
960+
this += ")"
961+
printMethodicType(res)
962+
case tp @ Type.TypeLambda(paramNames, params, res) =>
963+
this += "["
964+
printMethodicTypeParams(paramNames, params)
965+
this += "]"
966+
printMethodicType(res)
967+
case Type.ByNameType(t) =>
968+
this += ": "
969+
printType(t)
970+
case tp @ Type() =>
971+
this += ": "
972+
printType(tp)
973+
}
974+
def rec(tp: Type): Unit = tp match {
975+
case Type.Refinement(parent, name, info) =>
976+
rec(parent)
977+
indented {
978+
this += lineBreak()
979+
info match {
980+
case info @ TypeBounds(_, _) =>
981+
this += "type " += name
982+
printBounds(info)
983+
case Type.ByNameType(_) | Type.MethodType(_, _, _) | Type.TypeLambda(_, _, _) =>
984+
this += "def " += name
985+
printMethodicType(info)
986+
case info @ Type() =>
987+
this += "val " += name
988+
printMethodicType(info)
989+
}
990+
}
991+
case tp =>
992+
printType(tp)
993+
this += " {"
994+
}
995+
rec(tpe)
996+
this += lineBreak() += "}"
997+
}
998+
999+
def printMethodicTypeParams(paramNames: List[String], params: List[TypeOrBounds]): Unit = {
1000+
def printInfo(info: TypeOrBounds) = info match {
1001+
case info @ TypeBounds(_, _) => printBounds(info)
1002+
case info @ Type() =>
1003+
this += ": "
1004+
printType(info)
1005+
}
1006+
def printSeparated(list: List[(String, TypeOrBounds)]): Unit = list match {
1007+
case Nil =>
1008+
case (name, info) :: Nil =>
1009+
this += name
1010+
printInfo(info)
1011+
case (name, info) :: xs =>
1012+
this += name
1013+
printInfo(info)
1014+
this += ", "
1015+
printSeparated(xs)
1016+
}
1017+
printSeparated(paramNames.zip(params))
1018+
}
1019+
1020+
def printBoundsTree(bounds: TypeBoundsTree): Buffer = {
1021+
val TypeBoundsTree(lo, hi) = bounds
1022+
lo match {
1023+
case TypeTree.Synthetic() =>
1024+
case _ =>
1025+
this += " >: "
1026+
printTypeTree(lo)
1027+
}
1028+
hi match {
1029+
case TypeTree.Synthetic() => this
1030+
case _ =>
1031+
this += " <: "
1032+
printTypeTree(hi)
1033+
}
1034+
}
1035+
1036+
def printBounds(bounds: TypeBounds): Buffer = {
1037+
val TypeBounds(lo, hi) = bounds
1038+
this += " >: "
1039+
printType(lo)
1040+
this += " <: "
1041+
printType(hi)
1042+
}
1043+
9851044
def +=(x: Boolean): this.type = { sb.append(x); this }
9861045
def +=(x: Byte): this.type = { sb.append(x); this }
9871046
def +=(x: Short): this.type = { sb.append(x); this }

tests/pos/i2104b.decompiled

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ case class Pair[A, B](_1: A, _2: B) {
1313
scala.runtime.Statics.finalizeHash(acc, 2)
1414
}
1515
override def equals(x$0: scala.Any): scala.Boolean = this.eq(x$0.asInstanceOf[java.lang.Object]).||(x$0 match {
16-
case x$0: Pair[Pair.this.A, Pair.this.B] @scala.unchecked() =>
16+
case x$0: Pair[A, B] @scala.unchecked() =>
1717
this._1.==(x$0._1).&&(this._2.==(x$0._2))
1818
case _ =>
1919
false
2020
})
2121
override def toString(): java.lang.String = scala.runtime.ScalaRunTime._toString(this)
22-
override def canEqual(that: scala.Any): scala.Boolean = that.isInstanceOf[Pair[Pair.this.A, Pair.this.B] @scala.unchecked()]
22+
override def canEqual(that: scala.Any): scala.Boolean = that.isInstanceOf[Pair[A, B] @scala.unchecked()]
2323
override def productArity: scala.Int = 2
2424
override def productPrefix: java.lang.String = "Pair"
2525
override def productElement(n: scala.Int): scala.Any = n match {

tests/pos/simpleCaseClass-3.decompiled

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ case class A[T](x: T) {
66
scala.runtime.Statics.finalizeHash(acc, 1)
77
}
88
override def equals(x$0: scala.Any): scala.Boolean = this.eq(x$0.asInstanceOf[java.lang.Object]).||(x$0 match {
9-
case x$0: A[A.this.T] @scala.unchecked() =>
9+
case x$0: A[T] @scala.unchecked() =>
1010
this.x.==(x$0.x)
1111
case _ =>
1212
false
1313
})
1414
override def toString(): java.lang.String = scala.runtime.ScalaRunTime._toString(this)
15-
override def canEqual(that: scala.Any): scala.Boolean = that.isInstanceOf[A[A.this.T] @scala.unchecked()]
15+
override def canEqual(that: scala.Any): scala.Boolean = that.isInstanceOf[A[T] @scala.unchecked()]
1616
override def productArity: scala.Int = 1
1717
override def productPrefix: java.lang.String = "A"
1818
override def productElement(n: scala.Int): scala.Any = n match {

tests/pos/simpleRefinement.decompiled

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/** Decompiled from out/posTestFromTasty/pos/simpleRefinement/Bar.class */
2+
trait Bar() extends java.lang.Object {
3+
type S
4+
type T
5+
type U <: [X] => scala.Any
6+
val x: scala.Any
7+
def y: scala.Any
8+
def z(): scala.Any
9+
def z2()(): scala.Any
10+
def w[T]: scala.Any
11+
def w2[T](a: scala.Null)(b: scala.Null): scala.Any
12+
}
13+
/** Decompiled from out/posTestFromTasty/pos/simpleRefinement/Foo.class */
14+
class Foo() {
15+
val bar: Bar {
16+
type S >: scala.Int <: scala.Int
17+
type T >: scala.Function1[scala.Int, scala.Int] <: scala.Function1[scala.Int, scala.Int]
18+
type U >: [X >: scala.Nothing <: scala.Any] => scala.Int <: [X >: scala.Nothing <: scala.Any] => scala.Int
19+
val x: scala.Long
20+
def y: scala.Boolean
21+
def z(): scala.Char
22+
def z2()(): scala.Char
23+
def w[T >: scala.Nothing <: scala.Any]: scala.Predef.String
24+
def w2[T >: scala.Nothing <: scala.Any](a: scala.Null)(b: scala.Null): scala.Null
25+
} = {
26+
final class $anon() extends Bar {
27+
type S = scala.Int
28+
type T = scala.Function1[scala.Int, scala.Int]
29+
type U[X] = scala.Int
30+
val x: scala.Long = 2L
31+
def y: scala.Boolean = true
32+
def z(): scala.Char = 'f'
33+
def z2()(): scala.Char = 'g'
34+
def w[T]: scala.Predef.String = "a"
35+
def w2[T](a: scala.Null)(b: scala.Null): scala.Null = null
36+
}
37+
(new $anon(): Bar {
38+
type S >: scala.Int <: scala.Int
39+
type T >: scala.Function1[scala.Int, scala.Int] <: scala.Function1[scala.Int, scala.Int]
40+
type U >: [X >: scala.Nothing <: scala.Any] => scala.Int <: [X >: scala.Nothing <: scala.Any] => scala.Int
41+
val x: scala.Long
42+
def y: scala.Boolean
43+
def z(): scala.Char
44+
def z2()(): scala.Char
45+
def w[T >: scala.Nothing <: scala.Any]: scala.Predef.String
46+
def w2[T >: scala.Nothing <: scala.Any](a: scala.Null)(b: scala.Null): scala.Null
47+
})
48+
}
49+
}

tests/pos/simpleRefinement.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
class Foo {
3+
val bar = new Bar {
4+
type S = Int
5+
type T = Int => Int
6+
type U = [X] => Int
7+
val x: Long = 2L
8+
def y: Boolean = true
9+
def z(): Char = 'f'
10+
def z2()(): Char = 'g'
11+
def w[T]: String = "a"
12+
def w2[T](a: Null)(b: Null): Null = null
13+
}
14+
}
15+
16+
trait Bar {
17+
type S
18+
type T
19+
type U <: [X] => Any
20+
val x: Any
21+
def y: Any
22+
def z(): Any
23+
def z2()(): Any
24+
def w[T]: Any
25+
def w2[T](a: Null)(b: Null): Any
26+
}

tests/run-with-compiler/i3876-c.check

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@
44
val f: scala.Function1[scala.Int, scala.Int] {
55
def apply(x: scala.Int): scala.Int
66
} = ((x: scala.Int) => x.+(x))
7-
(f: scala.Function1[scala.Int, scala.Int]).apply(x$1)
7+
(f: scala.Function1[scala.Int, scala.Int] {
8+
def apply(x: scala.Int): scala.Int
9+
}).apply(x$1)
810
}

0 commit comments

Comments
 (0)