Skip to content

Commit 127b07b

Browse files
committed
Print type refinements
1 parent 93f0307 commit 127b07b

File tree

4 files changed

+177
-40
lines changed

4 files changed

+177
-40
lines changed

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

Lines changed: 99 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
7474

7575
if (flags.isObject) this += "object " += name.stripSuffix("$")
7676
else if (flags.isTrait) this += "trait " += name
77+
else if (flags.isAbstract) this += "abstract class " += name
7778
else this += "class " += name
7879

7980
if (!flags.isObject) {
@@ -504,29 +505,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
504505

505506
def printTargDef(arg: TypeDef, isMember: Boolean = false): Buffer = {
506507
val TypeDef(name, rhs) = arg
507-
def printBounds(bounds: TypeBoundsTree): Buffer = {
508-
val TypeBoundsTree(lo, hi) = bounds
509-
lo match {
510-
case TypeTree.Synthetic() =>
511-
case _ =>
512-
this += " >: "
513-
printTypeTree(lo)
514-
}
515-
hi match {
516-
case TypeTree.Synthetic() => this
517-
case _ =>
518-
this += " <: "
519-
printTypeTree(hi)
520-
}
521-
}
522508
this += name
523509
rhs match {
524-
case rhs @ TypeBoundsTree(lo, hi) => printBounds(rhs)
510+
case rhs @ TypeBoundsTree(lo, hi) => printBoundsTree(rhs)
525511
case rhs @ SyntheticBounds() =>
526512
printTypeOrBound(rhs.tpe)
527513
case rhs @ TypeTree.TypeLambdaTree(tparams, body) =>
528514
def printParam(t: TypeOrBoundsTree): Unit = t match {
529-
case t @ TypeBoundsTree(_, _) => printBounds(t)
515+
case t @ TypeBoundsTree(_, _) => printBoundsTree(t)
530516
case t @ TypeTree() => printTypeTree(t)
531517
}
532518
def printSeparated(list: List[TypeDef]): Unit = list match {
@@ -824,9 +810,50 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
824810
}
825811
this += name.stripSuffix("$")
826812

827-
case Type.Refinement(parent, name, info) =>
828-
printType(parent)
829-
// TODO add refinements
813+
case tpe @ Type.Refinement(_, _, _) =>
814+
def rec(tp: Type): Unit = tp match {
815+
case Type.Refinement(parent, name, info) =>
816+
rec(parent)
817+
indented {
818+
this += lineBreak()
819+
info match {
820+
case info @ TypeBounds(_, _) =>
821+
this += "type " += name
822+
printBounds(info)
823+
case info @ Type() =>
824+
info match {
825+
case Type.ByNameType(_) | Type.MethodType(_, _, _) | Type.TypeLambda(_, _, _) =>
826+
this += "def " += name
827+
case _ =>
828+
this += "val " += name
829+
}
830+
def printMethodicType(tp: Type): Unit = tp match {
831+
case tp @ Type.MethodType(paramNames, params, res) =>
832+
this += "("
833+
printMethodicTypeParams(paramNames, params)
834+
this += ")"
835+
printMethodicType(res)
836+
case tp @ Type.TypeLambda(paramNames, params, res) =>
837+
this += "["
838+
printMethodicTypeParams(paramNames, params)
839+
this += "]"
840+
printMethodicType(res)
841+
case Type.ByNameType(t) =>
842+
this += ": "
843+
printType(t)
844+
case tp @ Type() =>
845+
this += ": "
846+
printType(tp)
847+
}
848+
printMethodicType(info)
849+
}
850+
}
851+
case tp =>
852+
printType(tp)
853+
this += " {"
854+
}
855+
rec(tpe)
856+
this += lineBreak() += "}"
830857

831858
case Type.AppliedType(tp, args) =>
832859
printType(tp)
@@ -861,27 +888,15 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
861888
case _ => this
862889
}
863890

891+
case Type.MethodType(paramNames, params, body) =>
892+
this += "("
893+
printMethodicTypeParams(paramNames, params)
894+
this += ") => "
895+
printTypeOrBound(body)
896+
864897
case Type.TypeLambda(paramNames, tparams, body) =>
865898
this += "["
866-
def printBounds(bounds: TypeBounds): Buffer = {
867-
val TypeBounds(lo, hi) = bounds
868-
this += " >: "
869-
printType(lo)
870-
this += " <: "
871-
printType(hi)
872-
}
873-
def printSeparated(list: List[(String, TypeBounds)]): Unit = list match {
874-
case Nil =>
875-
case (name, bounds) :: Nil =>
876-
this += name
877-
printBounds(bounds)
878-
case (name, bounds) :: xs =>
879-
this += name
880-
printBounds(bounds)
881-
this += ", "
882-
printSeparated(xs)
883-
}
884-
printSeparated(paramNames.zip(tparams))
899+
printMethodicTypeParams(paramNames, tparams)
885900
this += "] => "
886901
printTypeOrBound(body)
887902

@@ -934,6 +949,51 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
934949
else this
935950
}
936951

952+
def printMethodicTypeParams(paramNames: List[String], params: List[TypeOrBounds]): Unit = {
953+
def printInfo(info: TypeOrBounds) = info match {
954+
case info @ TypeBounds(_, _) => printBounds(info)
955+
case info @ Type() =>
956+
this += ": "
957+
printType(info)
958+
}
959+
def printSeparated(list: List[(String, TypeOrBounds)]): Unit = list match {
960+
case Nil =>
961+
case (name, info) :: Nil =>
962+
this += name
963+
printInfo(info)
964+
case (name, info) :: xs =>
965+
this += name
966+
printInfo(info)
967+
this += ", "
968+
printSeparated(xs)
969+
}
970+
printSeparated(paramNames.zip(params))
971+
}
972+
973+
def printBoundsTree(bounds: TypeBoundsTree): Buffer = {
974+
val TypeBoundsTree(lo, hi) = bounds
975+
lo match {
976+
case TypeTree.Synthetic() =>
977+
case _ =>
978+
this += " >: "
979+
printTypeTree(lo)
980+
}
981+
hi match {
982+
case TypeTree.Synthetic() => this
983+
case _ =>
984+
this += " <: "
985+
printTypeTree(hi)
986+
}
987+
}
988+
989+
def printBounds(bounds: TypeBounds): Buffer = {
990+
val TypeBounds(lo, hi) = bounds
991+
this += " >: "
992+
printType(lo)
993+
this += " <: "
994+
printType(hi)
995+
}
996+
937997
def +=(x: Boolean): this.type = { sb.append(x); this }
938998
def +=(x: Byte): this.type = { sb.append(x); this }
939999
def +=(x: Short): this.type = { sb.append(x); this }

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)