Skip to content

Commit cd2b4c1

Browse files
committed
Fix #5404: Add MatchType to TASTy reflect
1 parent 45eb6aa commit cd2b4c1

12 files changed

+114
-4
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,12 @@ trait CaseDefOpsImpl extends scala.tasty.reflect.CaseDefOps with TastyCoreImpl w
1313
def unapply(x: CaseDef): Some[(Pattern, Option[Term], Term)] = Some(x.pat, optional(x.guard), x.body)
1414
}
1515

16+
def TypeCaseDefDeco(caseDef: TypeCaseDef): TypeCaseDefAPI = new TypeCaseDefAPI {
17+
def pattern(implicit ctx: Context): Pattern = caseDef.pat
18+
def rhs(implicit ctx: Context): Term = caseDef.body
19+
}
20+
21+
object TypeCaseDef extends TypeCaseDefExtractor {
22+
def unapply(x: TypeCaseDef): Some[(TypeTree, TypeTree)] = Some((x.pat, x.body))
23+
}
1624
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ trait TastyCoreImpl extends scala.tasty.reflect.TastyCore {
2626
type Term = tpd.Tree
2727

2828
type CaseDef = tpd.CaseDef
29+
type TypeCaseDef = tpd.CaseDef
2930

3031
type Pattern = tpd.Tree
3132
type Value = tpd.Tree

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@ trait TypeOrBoundsOpsImpl extends scala.tasty.reflect.TypeOrBoundsOps with Tasty
123123
}
124124
}
125125

126+
object MatchType extends MatchTypeExtractor {
127+
def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(Type, Type, List[Type])] = x match {
128+
case Types.MatchType(bound, scrutinee, cases) => Some((bound, scrutinee, cases))
129+
case _ => None
130+
}
131+
}
132+
126133
object ByNameType extends ByNameTypeExtractor {
127134
def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[Type] = x match {
128135
case Types.ExprType(resType) => Some(resType.stripTypeVar)

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ trait TypeOrBoundsTreesOpsImpl extends scala.tasty.reflect.TypeOrBoundsTreeOps w
100100
}
101101
}
102102

103+
object MatchType extends MatchTypeExtractor {
104+
def unapply(x: TypeOrBoundsTree)(implicit ctx: Context): Option[(Option[TypeTree], TypeTree, List[CaseDef])] = x match {
105+
case x: tpd.MatchTypeTree => Some((if (x.bound == tpd.EmptyTree) None else Some(x.bound), x.selector, x.cases))
106+
case _ => None
107+
}
108+
}
109+
103110
object ByName extends ByNameExtractor {
104111
def unapply(x: TypeTree)(implicit ctx: Context): Option[TypeTree] = x match {
105112
case x: tpd.ByNameTypeTree => Some(x.result)

compiler/test/dotc/pos-from-tasty.blacklist

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ repeatedArgs213.scala
1616
# Error printing parent constructors that are blocks
1717
default-super.scala
1818

19-
# Need to implement printing of match types
20-
matchtype.scala
21-
2219
# Did not survive addition of type ascriptions in decompiled tests
2320
i3050.scala
2421
i4006b.scala

compiler/test/dotc/pos-recompilation.whitelist

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,6 @@ lookupswitch
376376
macro-deprecate-dont-touch-backquotedidents
377377
Map
378378
match
379-
matchtype
380379
matthias3
381380
matthias4
382381
matthias5

library/src/scala/tasty/reflect/CaseDefOps.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,15 @@ trait CaseDefOps extends TastyCore {
1616
def unapply(x: CaseDef): Option[(Pattern, Option[Term], Term)]
1717
}
1818

19+
20+
trait TypeCaseDefAPI {
21+
def pattern(implicit ctx: Context): TypeTree
22+
def rhs(implicit ctx: Context): TypeTree
23+
}
24+
implicit def TypeCaseDefDeco(caseDef: TypeCaseDef): TypeCaseDefAPI
25+
26+
val TypeCaseDef: TypeCaseDefExtractor
27+
abstract class TypeCaseDefExtractor {
28+
def unapply(x: TypeCaseDef): Option[(TypeTree, TypeTree)]
29+
}
1930
}

library/src/scala/tasty/reflect/TastyCore.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ package scala.tasty.reflect
4646
* | +- Annotated
4747
* | +- And
4848
* | +- Or
49+
* | +- MatchType
4950
* | +- ByName
5051
* | +- TypeLambdaTree
5152
* | +- Bind
@@ -54,6 +55,7 @@ package scala.tasty.reflect
5455
* +- SyntheticBounds
5556
*
5657
* +- CaseDef
58+
* +- TypeCaseDef
5759
*
5860
* +- Pattern --+- Value
5961
* +- Bind
@@ -75,6 +77,7 @@ package scala.tasty.reflect
7577
* +- AnnotatedType
7678
* +- AndType
7779
* +- OrType
80+
* +- MatchType
7881
* +- ByNameType
7982
* +- ParamRef
8083
* +- ThisType
@@ -137,6 +140,9 @@ trait TastyCore {
137140
/** Branch of a pattern match or catch clause */
138141
type CaseDef
139142

143+
/** Branch of a type pattern match */
144+
type TypeCaseDef
145+
140146
/** Pattern tree of the pattern part of a CaseDef */
141147
type Pattern
142148
type Value <: Pattern

library/src/scala/tasty/reflect/TypeOrBoundsOps.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ trait TypeOrBoundsOps extends TastyCore {
9292
def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(Type, Type)]
9393
}
9494

95+
val MatchType: MatchTypeExtractor
96+
abstract class MatchTypeExtractor {
97+
def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(Type, Type, List[Type])]
98+
}
99+
95100
val ByNameType: ByNameTypeExtractor
96101
abstract class ByNameTypeExtractor {
97102
def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[Type]

library/src/scala/tasty/reflect/TypeOrBoundsTreeOps.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ trait TypeOrBoundsTreeOps extends TastyCore {
7777
def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)]
7878
}
7979

80+
val MatchType: MatchTypeExtractor
81+
abstract class MatchTypeExtractor {
82+
def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(Option[TypeTree], TypeTree, List[TypeCaseDef])]
83+
}
84+
8085
val ByName: ByNameExtractor
8186
abstract class ByNameExtractor {
8287
def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[TypeTree]

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,20 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
125125
this += "TypeBoundsTree(" += lo += ", " += hi += ")"
126126
case SyntheticBounds() =>
127127
this += s"SyntheticBounds()"
128+
case TypeTree.MatchType(bound, selector, cases) =>
129+
this += "TypeTree.MatchType(" += bound += ", " += selector += ", " ++= cases += ")"
128130
}
129131

130132
def visitCaseDef(x: CaseDef): Buffer = {
131133
val CaseDef(pat, guard, body) = x
132134
this += "CaseDef(" += pat += ", " += guard += ", " += body += ")"
133135
}
134136

137+
def visitTypeCaseDef(x: TypeCaseDef): Buffer = {
138+
val TypeCaseDef(pat, body) = x
139+
this += "TypeCaseDef(" += pat += ", " += body += ")"
140+
}
141+
135142
def visitPattern(x: Pattern): Buffer = x match {
136143
case Pattern.Value(v) =>
137144
this += "Pattern.Value(" += v += ")"
@@ -185,6 +192,8 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
185192
this += "Type.AndType(" += left += ", " += right += ")"
186193
case Type.OrType(left, right) =>
187194
this += "Type.OrType(" += left += ", " += right += ")"
195+
case Type.MatchType(bound, scrutinee, cases) =>
196+
this += "Type.MatchType(" += bound += ", " += scrutinee += ", " ++= cases += ")"
188197
case Type.ByNameType(underlying) =>
189198
this += "Type.ByNameType(" += underlying += ")"
190199
case Type.ParamRef(binder, idx) =>
@@ -259,6 +268,11 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
259268
def ++=(x: List[CaseDef]): Buffer = { visitList(x, visitCaseDef); buff }
260269
}
261270

271+
private implicit class TypeCaseDefOps(buff: Buffer) {
272+
def +=(x: TypeCaseDef): Buffer = { visitTypeCaseDef(x); buff }
273+
def ++=(x: List[TypeCaseDef]): Buffer = { visitList(x, visitTypeCaseDef); buff }
274+
}
275+
262276
private implicit class PatternOps(buff: Buffer) {
263277
def +=(x: Pattern): Buffer = { visitPattern(x); buff }
264278
def ++=(x: List[Pattern]): Buffer = { visitList(x, visitPattern); buff }

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,19 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
487487
this
488488
}
489489

490+
def printTypes(trees: List[Type], sep: String): Buffer = {
491+
def printSeparated(list: List[Type]): Unit = list match {
492+
case Nil =>
493+
case x :: Nil => printType(x)
494+
case x :: xs =>
495+
printType(x)
496+
this += sep
497+
printSeparated(xs)
498+
}
499+
printSeparated(trees)
500+
this
501+
}
502+
490503
def printImportSelectors(selectors: List[ImportSelector]): Buffer = {
491504
def printSeparated(list: List[ImportSelector]): Unit = list match {
492505
case Nil =>
@@ -514,6 +527,19 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
514527
this
515528
}
516529

530+
def printTypeCases(cases: List[TypeCaseDef], sep: String): Buffer = {
531+
def printSeparated(list: List[TypeCaseDef]): Unit = list match {
532+
case Nil =>
533+
case x :: Nil => printTypeCaseDef(x)
534+
case x :: xs =>
535+
printTypeCaseDef(x)
536+
this += sep
537+
printSeparated(xs)
538+
}
539+
printSeparated(cases)
540+
this
541+
}
542+
517543
def printPatterns(cases: List[Pattern], sep: String): Buffer = {
518544
def printSeparated(list: List[Pattern]): Unit = list match {
519545
case Nil =>
@@ -592,6 +618,12 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
592618
}
593619
inSquare(printSeparated(tparams))
594620
if (isMember) {
621+
body match {
622+
case TypeTree.MatchType(Some(bound), _, _) =>
623+
this += " <: "
624+
printTypeTree(bound)
625+
case _ =>
626+
}
595627
this += " = "
596628
printTypeOrBoundsTree(body)
597629
}
@@ -683,6 +715,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
683715
this
684716
}
685717

718+
def printTypeCaseDef(caseDef: TypeCaseDef): Buffer = {
719+
this += highlightValDef("case ", color)
720+
printTypeTree(caseDef.pattern)
721+
this += highlightValDef(" => ", color)
722+
printTypeTree(caseDef.rhs)
723+
this
724+
}
725+
686726
def printPattern(pattern: Pattern): Buffer = pattern match {
687727
case Pattern.Value(v) =>
688728
v match {
@@ -817,6 +857,11 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
817857
this += highlightTypeDef(" | ", color)
818858
printTypeTree(right)
819859

860+
case TypeTree.MatchType(bound, selector, cases) =>
861+
printTypeTree(selector)
862+
this += highlightKeyword(" match ", color)
863+
inBlock(printTypeCases(cases, lineBreak()))
864+
820865
case TypeTree.ByName(result) =>
821866
this += highlightTypeDef("=> ", color)
822867
printTypeTree(result)
@@ -916,6 +961,11 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
916961
this += highlightTypeDef(" | ", color)
917962
printType(right)
918963

964+
case Type.MatchType(bound, scrutinee, cases) =>
965+
printType(scrutinee)
966+
this += highlightKeyword(" match ", color)
967+
inBlock(printTypes(cases, lineBreak()))
968+
919969
case Type.ByNameType(tp) =>
920970
this += highlightTypeDef(" => ", color)
921971
printType(tp)

0 commit comments

Comments
 (0)