Skip to content

Commit be7859e

Browse files
committed
Add Tasty.SyntheticBounds
To represent dotty TypeTrees containing type bounds
1 parent 1c0c9e9 commit be7859e

File tree

7 files changed

+86
-10
lines changed

7 files changed

+86
-10
lines changed

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ object TastyImpl extends scala.tasty.Tasty {
523523

524524
object Synthetic extends SyntheticExtractor {
525525
def unapply(x: TypeTree)(implicit ctx: Context): Boolean = x match {
526-
case Trees.TypeTree() => true
526+
case x @ Trees.TypeTree() => !x.tpe.isInstanceOf[Types.TypeBounds]
527527
case _ => false
528528
}
529529
}
@@ -595,9 +595,11 @@ object TastyImpl extends scala.tasty.Tasty {
595595

596596
// ----- TypeBoundsTrees ------------------------------------------------
597597

598-
type TypeBoundsTree = tpd.TypeBoundsTree
598+
type TypeBoundsTree = tpd.Tree
599599

600-
def TypeBoundsTreeDeco(x: TypeBoundsTree): AbstractTypeBoundsTree = ???
600+
def TypeBoundsTreeDeco(x: TypeBoundsTree): AbstractTypeBoundsTree = new AbstractTypeBoundsTree {
601+
def tpe: TypeBounds = x.tpe.asInstanceOf[Types.TypeBounds]
602+
}
601603

602604
def typeBoundsTreeClassTag: ClassTag[TypeBoundsTree] = implicitly[ClassTag[TypeBoundsTree]]
603605

@@ -608,6 +610,13 @@ object TastyImpl extends scala.tasty.Tasty {
608610
}
609611
}
610612

613+
object SyntheticBounds extends SyntheticBoundsExtractor {
614+
def unapply(x: TypeBoundsTree)(implicit ctx: Context): Boolean = x match {
615+
case x @ Trees.TypeTree() => x.tpe.isInstanceOf[Types.TypeBounds]
616+
case _ => false
617+
}
618+
}
619+
611620
// ===== Types ====================================================
612621

613622
type TypeOrBounds = Types.Type

library/src/scala/tasty/Tasty.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,11 @@ abstract class Tasty { tasty =>
444444
def unapply(x: TypeBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)]
445445
}
446446

447+
val SyntheticBounds: SyntheticBoundsExtractor
448+
abstract class SyntheticBoundsExtractor {
449+
def unapply(x: TypeBoundsTree)(implicit ctx: Context): Boolean
450+
}
451+
447452
// ===== Types ====================================================
448453

449454
type TypeOrBounds

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
109109
this += "TypeTree.Annotated(" += arg += ", " += annot += ")"
110110
case TypeBoundsTree(lo, hi) =>
111111
this += "TypeBoundsTree(" += lo += ", " += hi += ")"
112+
case SyntheticBounds() =>
113+
this += s"SyntheticBounds()"
112114
}
113115

114116
def visitCaseDef(x: CaseDef): Buffer = {
@@ -185,7 +187,8 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
185187
case Type.PolyType(argNames, argBounds, resType) =>
186188
this += "Type.PolyType(" ++= argNames += ", " ++= argBounds += ", " += resType += ")"
187189
case Type.TypeLambda(argNames, argBounds, resType) =>
188-
this += "Type.TypeLambda(" ++= argNames += ", " ++= argBounds += ", " += resType += ")"
190+
// resType is not printed to avoid cycles
191+
this += "Type.TypeLambda(" ++= argNames += ", " ++= argBounds += ", _)"
189192
case TypeBounds(lo, hi) =>
190193
this += "TypeBounds(" += lo += ", " += hi += ")"
191194
case NoPrefix() =>

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,11 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
437437
this += " <: "
438438
printTypeTree(hi)
439439
}
440-
case tpt@TypeTree() =>
440+
case rhs @ SyntheticBounds() =>
441+
printTypeOrBound(rhs.tpe)
442+
case rhs @ TypeTree() =>
441443
this += " = "
442-
printTypeTree(tpt)
444+
printTypeTree(rhs)
443445
}
444446
}
445447

@@ -555,6 +557,8 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
555557
printTypeTree(lo)
556558
this += " <: "
557559
printTypeTree(hi)
560+
case tpt @ SyntheticBounds() =>
561+
printTypeOrBound(tpt.tpe)
558562
case tpt @ TypeTree() =>
559563
printTypeTree(tpt)
560564
}

tests/pos/i2104.decompiled

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/** Decompiled from out/posTestFromTasty/pos/i2104/Cons.class */
2+
class Cons[H, T]() extends java.lang.Object
3+
object Cons {
4+
def apply[H, T](h: H, t: T): Cons[H, T] = scala.Predef.???
5+
def unapply[H, T](t: Cons[H, T]): scala.Option[<empty>.Pair[H, T]] = scala.Predef.???
6+
}/** Decompiled from out/posTestFromTasty/pos/i2104/Pair.class */
7+
case class Pair[A, B](_1: A, _2: B) {
8+
def copy[A >: scala.Nothing <: scala.Any, B >: scala.Nothing <: scala.Any](_1: A, _2: B): Pair[A, B] = new Pair[A, B](_1, _2)
9+
def copy$default$1[A >: scala.Nothing <: scala.Any, B >: scala.Nothing <: scala.Any]: Pair.A = (Pair._1: Pair._1)
10+
def copy$default$2[A >: scala.Nothing <: scala.Any, B >: scala.Nothing <: scala.Any]: Pair.B = (Pair._2: Pair._2)
11+
override def hashCode(): scala.Int = {
12+
var acc: scala.Int = 2479866
13+
acc = scala.runtime.Statics.mix(acc, scala.runtime.Statics.anyHash(Pair._1))
14+
acc = scala.runtime.Statics.mix(acc, scala.runtime.Statics.anyHash(Pair._2))
15+
scala.runtime.Statics.finalizeHash(acc, 2)
16+
}
17+
override def equals(x$0: scala.Any): scala.Boolean = this.eq(x$0.asInstanceOf[java.lang.Object]).||(x$0 match {
18+
case x$0: Pair[Pair.A, Pair.B] =>
19+
this._1.==(x$0._1).&&(this._2.==(x$0._2))
20+
case _ =>
21+
false
22+
})
23+
override def toString(): java.lang.String = scala.runtime.ScalaRunTime._toString(this)
24+
override def canEqual(that: scala.Any): scala.Boolean = that.isInstanceOf[Pair[Pair.A, Pair.B]]
25+
override def productArity: scala.Int = 2
26+
override def productPrefix: java.lang.String = "Pair"
27+
override def productElement(n: scala.Int): scala.Any = n match {
28+
case 0 =>
29+
this._1
30+
case 1 =>
31+
this._2
32+
case _ =>
33+
throw new java.lang.IndexOutOfBoundsException(n.toString())
34+
}
35+
}
36+
object Pair extends scala.AnyRef {
37+
def apply[A >: scala.Nothing <: scala.Any, B >: scala.Nothing <: scala.Any](_1: A, _2: B): Pair[A, B] = new Pair[A, B](_1, _2)
38+
def unapply[A >: scala.Nothing <: scala.Any, B >: scala.Nothing <: scala.Any](x$1: Pair[A, B]): Pair[A, B] = x$1
39+
}/** Decompiled from out/posTestFromTasty/pos/i2104/Test.class */
40+
object Test {
41+
def main(args: scala.Array[scala.Predef.String]): scala.Unit = {
42+
<empty>.Cons.apply[scala.Option[scala.Int], scala.None](scala.Option.apply[scala.Int](1), scala.None) match {
43+
case <empty>.Cons.unapply[scala.Option[scala.Int], scala.None](, scala.None) =>
44+
{
45+
(i: scala.Int)
46+
dotty.DottyPredef.assert(i.==(1))
47+
}
48+
}
49+
}
50+
}

tests/pos/tasty/definitions.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,16 @@ object definitions {
8888
case ByName(tpt: TypeTree)
8989
}
9090

91-
/** Trees denoting type bounds*/
91+
/** Trees denoting type bounds */
9292
case class TypeBoundsTree(loBound: TypeTree, hiBound: TypeTree) extends Tree {
9393
def tpe: Type.TypeBounds = ???
9494
}
9595

96+
/** Trees denoting type infered bounds */
97+
case class SyntheticBounds() extends Tree {
98+
def tpe: Type.TypeBounds = ???
99+
}
100+
96101
/** Trees denoting patterns */
97102
enum Pattern extends Positioned {
98103
def tpe: Type = ???

tests/run/tasty-extractors-owners.check

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ baz2
1717
ValDef("foo2", TypeTree.Synthetic(), None)
1818

1919
<init>
20-
ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "<init>", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", TypeTree.Synthetic()), DefDef("b", Nil, Nil, TypeTree.Synthetic(), None), ValDef("b2", TypeTree.Synthetic(), None)))
20+
ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "<init>", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", SyntheticBounds()), DefDef("b", Nil, Nil, TypeTree.Synthetic(), None), ValDef("b2", TypeTree.Synthetic(), None)))
2121

2222
b
23-
ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "<init>", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", TypeTree.Synthetic()), DefDef("b", Nil, Nil, TypeTree.Synthetic(), None), ValDef("b2", TypeTree.Synthetic(), None)))
23+
ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "<init>", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", SyntheticBounds()), DefDef("b", Nil, Nil, TypeTree.Synthetic(), None), ValDef("b2", TypeTree.Synthetic(), None)))
2424

2525
b2
26-
ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "<init>", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", TypeTree.Synthetic()), DefDef("b", Nil, Nil, TypeTree.Synthetic(), None), ValDef("b2", TypeTree.Synthetic(), None)))
26+
ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "<init>", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", SyntheticBounds()), DefDef("b", Nil, Nil, TypeTree.Synthetic(), None), ValDef("b2", TypeTree.Synthetic(), None)))
2727

0 commit comments

Comments
 (0)