Skip to content

Add TypeTree.TypeLambda to Tasty reflect #4677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,12 @@ object TastyImpl extends scala.tasty.Tasty {
}
}

object TypeLambdaTree extends TypeLambdaTreeExtractor {
def unapply(x: TypeTree)(implicit ctx: Context): Option[(List[TypeDef], TypeOrBoundsTree)] = x match {
case Trees.LambdaTypeTree(tparams, body) => Some((tparams, body))
case _ => None
}
}
}

// ----- TypeBoundsTrees ------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions library/src/scala/tasty/Tasty.scala
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,10 @@ abstract class Tasty { tasty =>
def unapply(x: TypeTree)(implicit ctx: Context): Option[TypeTree]
}

val TypeLambdaTree: TypeLambdaTreeExtractor
abstract class TypeLambdaTreeExtractor {
def unapply(x: TypeTree)(implicit ctx: Context): Option[(List[TypeDef], TypeOrBoundsTree)]
}
}

// ----- TypeBoundsTrees ------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions library/src/scala/tasty/util/ShowExtractors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
this += "TypeTree.ByName(" += result += ")"
case TypeTree.Annotated(arg, annot) =>
this += "TypeTree.Annotated(" += arg += ", " += annot += ")"
case TypeTree.TypeLambdaTree(tparams, body) =>
this += "LambdaTypeTree(" ++= tparams += ", " += body += ")"
case TypeBoundsTree(lo, hi) =>
this += "TypeBoundsTree(" += lo += ", " += hi += ")"
case SyntheticBounds() =>
Expand Down Expand Up @@ -185,6 +187,8 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
this += "Type.ThisType(" += tp += ")"
case Type.RecursiveThis(binder) =>
this += "Type.RecursiveThis(" += binder += ")"
case Type.RecursiveType(underlying) =>
this += "Type.RecursiveType(" += underlying += ")"
case Type.MethodType(argNames, argTypes, resType) =>
this += "Type.MethodType(" ++= argNames += ", " ++= argTypes += ", " += resType += ")"
case Type.PolyType(argNames, argBounds, resType) =>
Expand Down
55 changes: 53 additions & 2 deletions library/src/scala/tasty/util/ShowSourceCode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty

case tdef@TypeDef(name, rhs) =>
this += "type "
printTargDef(tdef)
printTargDef(tdef, isMember = true)

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

def printTargDef(arg: TypeDef): Buffer = {
def printTargDef(arg: TypeDef, isMember: Boolean = false): Buffer = {
val TypeDef(name, rhs) = arg
this += name
rhs match {
Expand All @@ -488,6 +488,28 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
}
case rhs @ SyntheticBounds() =>
printTypeOrBound(rhs.tpe)
case rhs @ TypeTree.TypeLambdaTree(tparams, body) =>
def printSeparated(list: List[TypeDef]): Unit = list match {
case Nil =>
case x :: Nil =>
val TypeDef(name, trhs) = x
this += name
printTypeOrBoundsTree(trhs)
case x :: xs =>
val TypeDef(name, trhs) = x
this += name
printTypeOrBoundsTree(trhs)
this += ", "
printSeparated(xs)
}
this += "["
printSeparated(tparams)
this += "]"
if (isMember) {
this += " = "
printTypeOrBoundsTree(body)
}
else this
case rhs @ TypeTree() =>
this += " = "
printTypeTree(rhs)
Expand Down Expand Up @@ -672,6 +694,11 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
this += "=> "
printTypeTree(result)

case TypeTree.TypeLambdaTree(tparams, body) =>
printTargsDefs(tparams)
this += " => "
printTypeOrBoundsTree(body)

case _ =>
throw new MatchError(tree.show)

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

case Type.TypeLambda(paramNames, tparams, body) =>
this += "["
def printSeparated(list: List[(String, TypeBounds)]): Unit = list match {
case Nil =>
case (name, bounds) :: Nil =>
this += name
printTypeOrBound(bounds)
case (name, bounds) :: xs =>
this += name
printTypeOrBound(bounds)
this += ", "
printSeparated(xs)
}
printSeparated(paramNames.zip(tparams))
this += "] => "
printTypeOrBound(body)

case Type.ParamRef(lambda, idx) =>
lambda match {
case Type.MethodType(params, _, _) => this += params(idx)
case Type.PolyType(params, _, _) => this += params(idx)
case Type.TypeLambda(params, _, _) => this += params(idx)
}

case _ =>
throw new MatchError(tpe.show)
}
Expand Down
8 changes: 8 additions & 0 deletions tests/pos/i1181.decompiled
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** Decompiled from out/posTestFromTasty/pos/i1181/Test.class */
object Test {
def foo[M[_$1 >: scala.Nothing <: scala.Any]](x: M[scala.Int]): M[scala.Int] = x
type Alias[A >: scala.Nothing <: scala.Any] = scala.Tuple2[A, A]
val x: Test.Alias[scala.Int] = scala.Tuple2.apply[scala.Int, scala.Int](1, 2)
Test.foo[Test.Alias](Test.x)
Test.foo[[A >: scala.Nothing <: scala.Any] => scala.Tuple2[A, A]](Test.x)
}
1 change: 1 addition & 0 deletions tests/pos/tasty/definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ object definitions {
case And(left: TypeTree, right: TypeTree)
case Or(left: TypeTree, right: TypeTree)
case ByName(tpt: TypeTree)
case TypeLambda(tparams: List[TypeDef], body: Type | TypeBoundsTree)
}

/** Trees denoting type bounds */
Expand Down