Skip to content

Commit a043541

Browse files
Merge pull request #5416 from dotty-staging/fix-#5404-2
Fix #5404: Add MatchType to TASTy reflect
2 parents b0a20fc + 571cd88 commit a043541

11 files changed

+115
-5
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 CoreImpl with H
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/CoreImpl.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ trait CoreImpl extends scala.tasty.reflect.Core {
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 CoreI
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 Core {
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/Core.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 Core {
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/Printers.scala

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,20 @@ trait Printers
192192
this += "TypeBoundsTree(" += lo += ", " += hi += ")"
193193
case SyntheticBounds() =>
194194
this += s"SyntheticBounds()"
195+
case TypeTree.MatchType(bound, selector, cases) =>
196+
this += "TypeTree.MatchType(" += bound += ", " += selector += ", " ++= cases += ")"
195197
}
196198

197199
def visitCaseDef(x: CaseDef): Buffer = {
198200
val CaseDef(pat, guard, body) = x
199201
this += "CaseDef(" += pat += ", " += guard += ", " += body += ")"
200202
}
201203

204+
def visitTypeCaseDef(x: TypeCaseDef): Buffer = {
205+
val TypeCaseDef(pat, body) = x
206+
this += "TypeCaseDef(" += pat += ", " += body += ")"
207+
}
208+
202209
def visitPattern(x: Pattern): Buffer = x match {
203210
case Pattern.Value(v) =>
204211
this += "Pattern.Value(" += v += ")"
@@ -252,6 +259,8 @@ trait Printers
252259
this += "Type.AndType(" += left += ", " += right += ")"
253260
case Type.OrType(left, right) =>
254261
this += "Type.OrType(" += left += ", " += right += ")"
262+
case Type.MatchType(bound, scrutinee, cases) =>
263+
this += "Type.MatchType(" += bound += ", " += scrutinee += ", " ++= cases += ")"
255264
case Type.ByNameType(underlying) =>
256265
this += "Type.ByNameType(" += underlying += ")"
257266
case Type.ParamRef(binder, idx) =>
@@ -326,6 +335,11 @@ trait Printers
326335
def ++=(x: List[CaseDef]): Buffer = { visitList(x, visitCaseDef); buff }
327336
}
328337

338+
private implicit class TypeCaseDefOps(buff: Buffer) {
339+
def +=(x: TypeCaseDef): Buffer = { visitTypeCaseDef(x); buff }
340+
def ++=(x: List[TypeCaseDef]): Buffer = { visitList(x, visitTypeCaseDef); buff }
341+
}
342+
329343
private implicit class PatternOps(buff: Buffer) {
330344
def +=(x: Pattern): Buffer = { visitPattern(x); buff }
331345
def ++=(x: List[Pattern]): Buffer = { visitList(x, visitPattern); buff }
@@ -871,6 +885,19 @@ trait Printers
871885
this
872886
}
873887

888+
def printTypes(trees: List[Type], sep: String): Buffer = {
889+
def printSeparated(list: List[Type]): Unit = list match {
890+
case Nil =>
891+
case x :: Nil => printType(x)
892+
case x :: xs =>
893+
printType(x)
894+
this += sep
895+
printSeparated(xs)
896+
}
897+
printSeparated(trees)
898+
this
899+
}
900+
874901
def printImportSelectors(selectors: List[ImportSelector]): Buffer = {
875902
def printSeparated(list: List[ImportSelector]): Unit = list match {
876903
case Nil =>
@@ -898,6 +925,19 @@ trait Printers
898925
this
899926
}
900927

928+
def printTypeCases(cases: List[TypeCaseDef], sep: String): Buffer = {
929+
def printSeparated(list: List[TypeCaseDef]): Unit = list match {
930+
case Nil =>
931+
case x :: Nil => printTypeCaseDef(x)
932+
case x :: xs =>
933+
printTypeCaseDef(x)
934+
this += sep
935+
printSeparated(xs)
936+
}
937+
printSeparated(cases)
938+
this
939+
}
940+
901941
def printPatterns(cases: List[Pattern], sep: String): Buffer = {
902942
def printSeparated(list: List[Pattern]): Unit = list match {
903943
case Nil =>
@@ -976,6 +1016,12 @@ trait Printers
9761016
}
9771017
inSquare(printSeparated(tparams))
9781018
if (isMember) {
1019+
body match {
1020+
case TypeTree.MatchType(Some(bound), _, _) =>
1021+
this += " <: "
1022+
printTypeTree(bound)
1023+
case _ =>
1024+
}
9791025
this += " = "
9801026
printTypeOrBoundsTree(body)
9811027
}
@@ -1067,6 +1113,14 @@ trait Printers
10671113
this
10681114
}
10691115

1116+
def printTypeCaseDef(caseDef: TypeCaseDef): Buffer = {
1117+
this += highlightValDef("case ", color)
1118+
printTypeTree(caseDef.pattern)
1119+
this += highlightValDef(" => ", color)
1120+
printTypeTree(caseDef.rhs)
1121+
this
1122+
}
1123+
10701124
def printPattern(pattern: Pattern): Buffer = pattern match {
10711125
case Pattern.Value(v) =>
10721126
v match {
@@ -1201,6 +1255,11 @@ trait Printers
12011255
this += highlightTypeDef(" | ", color)
12021256
printTypeTree(right)
12031257

1258+
case TypeTree.MatchType(bound, selector, cases) =>
1259+
printTypeTree(selector)
1260+
this += highlightKeyword(" match ", color)
1261+
inBlock(printTypeCases(cases, lineBreak()))
1262+
12041263
case TypeTree.ByName(result) =>
12051264
this += highlightTypeDef("=> ", color)
12061265
printTypeTree(result)
@@ -1300,6 +1359,11 @@ trait Printers
13001359
this += highlightTypeDef(" | ", color)
13011360
printType(right)
13021361

1362+
case Type.MatchType(bound, scrutinee, cases) =>
1363+
printType(scrutinee)
1364+
this += highlightKeyword(" match ", color)
1365+
inBlock(printTypes(cases, lineBreak()))
1366+
13031367
case Type.ByNameType(tp) =>
13041368
this += highlightTypeDef(" => ", color)
13051369
printType(tp)
@@ -1553,7 +1617,7 @@ trait Printers
15531617
}
15541618
}
15551619

1556-
// TODO Provide some of these in scala.tasty.Reflect.scala and implement them using checks on symbols for performance
1620+
// TODO Provide some of these in scala.tasty.Reflection.scala and implement them using checks on symbols for performance
15571621
private object Types {
15581622

15591623
object JavaLangObject {

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 Core {
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 Core {
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]

0 commit comments

Comments
 (0)