Skip to content

Commit 188d4f2

Browse files
Merge pull request #4677 from dotty-staging/add-Tasty-relect-LambdaTypeTree
Add TypeTree.TypeLambda to Tasty reflect
2 parents 39c69c2 + 14a3f30 commit 188d4f2

File tree

6 files changed

+76
-2
lines changed

6 files changed

+76
-2
lines changed

compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,12 @@ object TastyImpl extends scala.tasty.Tasty {
606606
}
607607
}
608608

609+
object TypeLambdaTree extends TypeLambdaTreeExtractor {
610+
def unapply(x: TypeTree)(implicit ctx: Context): Option[(List[TypeDef], TypeOrBoundsTree)] = x match {
611+
case Trees.LambdaTypeTree(tparams, body) => Some((tparams, body))
612+
case _ => None
613+
}
614+
}
609615
}
610616

611617
// ----- TypeBoundsTrees ------------------------------------------------

library/src/scala/tasty/Tasty.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,10 @@ abstract class Tasty { tasty =>
440440
def unapply(x: TypeTree)(implicit ctx: Context): Option[TypeTree]
441441
}
442442

443+
val TypeLambdaTree: TypeLambdaTreeExtractor
444+
abstract class TypeLambdaTreeExtractor {
445+
def unapply(x: TypeTree)(implicit ctx: Context): Option[(List[TypeDef], TypeOrBoundsTree)]
446+
}
443447
}
444448

445449
// ----- TypeBoundsTrees ------------------------------------------------

library/src/scala/tasty/util/ShowExtractors.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
110110
this += "TypeTree.ByName(" += result += ")"
111111
case TypeTree.Annotated(arg, annot) =>
112112
this += "TypeTree.Annotated(" += arg += ", " += annot += ")"
113+
case TypeTree.TypeLambdaTree(tparams, body) =>
114+
this += "LambdaTypeTree(" ++= tparams += ", " += body += ")"
113115
case TypeBoundsTree(lo, hi) =>
114116
this += "TypeBoundsTree(" += lo += ", " += hi += ")"
115117
case SyntheticBounds() =>
@@ -185,6 +187,8 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
185187
this += "Type.ThisType(" += tp += ")"
186188
case Type.RecursiveThis(binder) =>
187189
this += "Type.RecursiveThis(" += binder += ")"
190+
case Type.RecursiveType(underlying) =>
191+
this += "Type.RecursiveType(" += underlying += ")"
188192
case Type.MethodType(argNames, argTypes, resType) =>
189193
this += "Type.MethodType(" ++= argNames += ", " ++= argTypes += ", " += resType += ")"
190194
case Type.PolyType(argNames, argBounds, resType) =>

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

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
148148

149149
case tdef@TypeDef(name, rhs) =>
150150
this += "type "
151-
printTargDef(tdef)
151+
printTargDef(tdef, isMember = true)
152152

153153
case vdef@ValDef(name, tpt, rhs) =>
154154
val flags = vdef.flags
@@ -469,7 +469,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
469469
}
470470
}
471471

472-
def printTargDef(arg: TypeDef): Buffer = {
472+
def printTargDef(arg: TypeDef, isMember: Boolean = false): Buffer = {
473473
val TypeDef(name, rhs) = arg
474474
this += name
475475
rhs match {
@@ -488,6 +488,28 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
488488
}
489489
case rhs @ SyntheticBounds() =>
490490
printTypeOrBound(rhs.tpe)
491+
case rhs @ TypeTree.TypeLambdaTree(tparams, body) =>
492+
def printSeparated(list: List[TypeDef]): Unit = list match {
493+
case Nil =>
494+
case x :: Nil =>
495+
val TypeDef(name, trhs) = x
496+
this += name
497+
printTypeOrBoundsTree(trhs)
498+
case x :: xs =>
499+
val TypeDef(name, trhs) = x
500+
this += name
501+
printTypeOrBoundsTree(trhs)
502+
this += ", "
503+
printSeparated(xs)
504+
}
505+
this += "["
506+
printSeparated(tparams)
507+
this += "]"
508+
if (isMember) {
509+
this += " = "
510+
printTypeOrBoundsTree(body)
511+
}
512+
else this
491513
case rhs @ TypeTree() =>
492514
this += " = "
493515
printTypeTree(rhs)
@@ -672,6 +694,11 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
672694
this += "=> "
673695
printTypeTree(result)
674696

697+
case TypeTree.TypeLambdaTree(tparams, body) =>
698+
printTargsDefs(tparams)
699+
this += " => "
700+
printTypeOrBoundsTree(body)
701+
675702
case _ =>
676703
throw new MatchError(tree.show)
677704

@@ -757,6 +784,30 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
757784
case _ => this
758785
}
759786

787+
case Type.TypeLambda(paramNames, tparams, body) =>
788+
this += "["
789+
def printSeparated(list: List[(String, TypeBounds)]): Unit = list match {
790+
case Nil =>
791+
case (name, bounds) :: Nil =>
792+
this += name
793+
printTypeOrBound(bounds)
794+
case (name, bounds) :: xs =>
795+
this += name
796+
printTypeOrBound(bounds)
797+
this += ", "
798+
printSeparated(xs)
799+
}
800+
printSeparated(paramNames.zip(tparams))
801+
this += "] => "
802+
printTypeOrBound(body)
803+
804+
case Type.ParamRef(lambda, idx) =>
805+
lambda match {
806+
case Type.MethodType(params, _, _) => this += params(idx)
807+
case Type.PolyType(params, _, _) => this += params(idx)
808+
case Type.TypeLambda(params, _, _) => this += params(idx)
809+
}
810+
760811
case _ =>
761812
throw new MatchError(tpe.show)
762813
}

tests/pos/i1181.decompiled

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/** Decompiled from out/posTestFromTasty/pos/i1181/Test.class */
2+
object Test {
3+
def foo[M[_$1 >: scala.Nothing <: scala.Any]](x: M[scala.Int]): M[scala.Int] = x
4+
type Alias[A >: scala.Nothing <: scala.Any] = scala.Tuple2[A, A]
5+
val x: Test.Alias[scala.Int] = scala.Tuple2.apply[scala.Int, scala.Int](1, 2)
6+
Test.foo[Test.Alias](Test.x)
7+
Test.foo[[A >: scala.Nothing <: scala.Any] => scala.Tuple2[A, A]](Test.x)
8+
}

tests/pos/tasty/definitions.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ object definitions {
100100
case And(left: TypeTree, right: TypeTree)
101101
case Or(left: TypeTree, right: TypeTree)
102102
case ByName(tpt: TypeTree)
103+
case TypeLambda(tparams: List[TypeDef], body: Type | TypeBoundsTree)
103104
}
104105

105106
/** Trees denoting type bounds */

0 commit comments

Comments
 (0)