Skip to content

Commit 255da96

Browse files
Merge pull request #6275 from dotty-staging/add-tasty-reflect-pattern-wildcard
Add TASTy Reflect Pattern.Wildcard
2 parents 5821362 + 59e378a commit 255da96

File tree

13 files changed

+61
-18
lines changed

13 files changed

+61
-18
lines changed

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

+13-1
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ class KernelImpl(val rootContext: core.Contexts.Context, val rootPosition: util.
922922

923923
def matchPattern_Value(pattern: Pattern): Option[Value] = pattern match {
924924
case lit: tpd.Literal => Some(lit)
925-
case ref: tpd.RefTree if ref.isTerm => Some(ref)
925+
case ref: tpd.RefTree if ref.isTerm && !tpd.isWildcardArg(ref) => Some(ref)
926926
case ths: tpd.This => Some(ths)
927927
case _ => None
928928
}
@@ -1005,6 +1005,18 @@ class KernelImpl(val rootContext: core.Contexts.Context, val rootPosition: util.
10051005
def Pattern_TypeTest_module_copy(original: TypeTest)(tpt: TypeTree)(implicit ctx: Context): TypeTest =
10061006
tpd.cpy.Typed(original)(untpd.Ident(nme.WILDCARD).withSpan(original.span).withType(tpt.tpe), tpt)
10071007

1008+
type WildcardPattern = tpd.Ident
1009+
1010+
def matchPattern_WildcardPattern(pattern: Pattern)(implicit ctx: Context): Option[WildcardPattern] = {
1011+
pattern match {
1012+
case pattern: tpd.Ident if tpd.isWildcardArg(pattern) => Some(pattern)
1013+
case _ => None
1014+
}
1015+
}
1016+
1017+
def Pattern_WildcardPattern_module_apply(tpe: TypeOrBounds)(implicit ctx: Context): WildcardPattern =
1018+
untpd.Ident(nme.WILDCARD).withType(tpe)
1019+
10081020
//
10091021
// TYPES
10101022
//

compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
6666
}
6767
}
6868
else {
69-
assert(!enclosingInlineds.nonEmpty, "unexpanded macro")
69+
assert(enclosingInlineds.isEmpty, "unexpanded macro")
7070
assert(ctx.owner.isInlineMethod)
7171
if (Splicer.canBeSpliced(body)) { // level 0 inside an inline definition
7272
transform(body)(spliceContext) // Just check PCP

docs/docs/reference/other-new-features/tasty-reflect.md

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ TASTy Reflect provides the following types:
139139
+- Unapply
140140
+- Alternative
141141
+- TypeTest
142+
+- WildcardPattern
142143
143144
144145
+- NoPrefix

library/src-bootstrapped/scala/internal/quoted/Matcher.scala

+3
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,9 @@ object Matcher {
246246
case (Pattern.TypeTest(tpt1), Pattern.TypeTest(tpt2)) =>
247247
(env, treeMatches(tpt1, tpt2))
248248

249+
case (Pattern.WildcardPattern(), Pattern.WildcardPattern()) =>
250+
(env, Some(()))
251+
249252
case _ =>
250253
if (debug)
251254
println(

library/src/scala/tasty/reflect/Core.scala

+4
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ package scala.tasty.reflect
6262
* +- Unapply
6363
* +- Alternatives
6464
* +- TypeTest
65+
* +- WildcardPattern
6566
*
6667
*
6768
* +- NoPrefix
@@ -304,6 +305,9 @@ trait Core {
304305
/** Pattern representing a `x: Y` type test. */
305306
type TypeTest = kernel.TypeTest
306307

308+
/** Pattern representing a `_` pattern */
309+
type WildcardPattern = kernel.WildcardPattern
310+
307311
/** Type or bounds */
308312
type TypeOrBounds = kernel.TypeOrBounds
309313

library/src/scala/tasty/reflect/Kernel.scala

+8
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ package scala.tasty.reflect
6161
* +- Unapply
6262
* +- Alternatives
6363
* +- TypeTest
64+
* +- WildcardPattern
6465
*
6566
*
6667
* +- NoPrefix
@@ -801,6 +802,13 @@ trait Kernel {
801802
def Pattern_TypeTest_module_apply(tpt: TypeTree)(implicit ctx: Context): TypeTest
802803
def Pattern_TypeTest_module_copy(original: TypeTest)(tpt: TypeTree)(implicit ctx: Context): TypeTest
803804

805+
/** Pattern representing a `_` pattern */
806+
type WildcardPattern <: Pattern
807+
808+
def matchPattern_WildcardPattern(pattern: Pattern)(implicit ctx: Context): Option[WildcardPattern]
809+
810+
def Pattern_WildcardPattern_module_apply(tpe: TypeOrBounds)(implicit ctx: Context): WildcardPattern
811+
804812
//
805813
// TYPES
806814
//

library/src/scala/tasty/reflect/PatternOps.scala

+12
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ trait PatternOps extends Core {
105105
kernel.matchPattern_TypeTest(pattern).map(_.tpt)
106106
}
107107

108+
object IsWildcardPattern {
109+
def unapply(pattern: Pattern)(implicit ctx: Context): Option[WildcardPattern] =
110+
kernel.matchPattern_WildcardPattern(pattern)
111+
}
112+
113+
object WildcardPattern {
114+
def apply(tpe: TypeOrBounds)(implicit ctx: Context): WildcardPattern =
115+
kernel.Pattern_WildcardPattern_module_apply(tpe)
116+
def unapply(pattern: Pattern)(implicit ctx: Context): Boolean =
117+
kernel.matchPattern_WildcardPattern(pattern).isDefined
118+
}
119+
108120
}
109121

110122
}

library/src/scala/tasty/reflect/Printers.scala

+7-5
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,8 @@ trait Printers
265265
this += "Pattern.Alternative(" ++= patterns += ")"
266266
case Pattern.TypeTest(tpt) =>
267267
this += "Pattern.TypeTest(" += tpt += ")"
268+
case Pattern.WildcardPattern() =>
269+
this += "Pattern.WildcardPattern()"
268270
}
269271

270272
def visitConstant(x: Constant): Buffer = x match {
@@ -1308,12 +1310,12 @@ trait Printers
13081310

13091311
def printPattern(pattern: Pattern): Buffer = pattern match {
13101312
case Pattern.Value(v) =>
1311-
v match {
1312-
case Ident("_") => this += "_"
1313-
case _ => printTree(v)
1314-
}
1313+
printTree(v)
1314+
1315+
case Pattern.WildcardPattern() =>
1316+
this += "_"
13151317

1316-
case Pattern.Bind(name, Pattern.Value(Ident("_"))) =>
1318+
case Pattern.Bind(name, Pattern.WildcardPattern()) =>
13171319
this += name
13181320

13191321
case Pattern.Bind(name, Pattern.TypeTest(tpt)) =>

library/src/scala/tasty/reflect/TreeUtils.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ trait TreeUtils
102102
case Pattern.Unapply(fun, implicits, patterns) => foldPatterns(foldTrees(foldTree(x, fun), implicits), patterns)
103103
case Pattern.Alternatives(patterns) => foldPatterns(x, patterns)
104104
case Pattern.TypeTest(tpt) => foldTree(x, tpt)
105+
case Pattern.WildcardPattern() => x
105106
}
106107

107108
}
@@ -243,7 +244,7 @@ trait TreeUtils
243244
}
244245

245246
def transformPattern(pattern: Pattern)(implicit ctx: Context): Pattern = pattern match {
246-
case Pattern.Value(_) =>
247+
case Pattern.Value(_) | Pattern.WildcardPattern() =>
247248
pattern
248249
case Pattern.IsTypeTest(pattern) =>
249250
Pattern.TypeTest.copy(pattern)(transformTypeTree(pattern.tpt))
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
DefDef("foo", Nil, Nil, TypeIdent("Int"), Some(Apply(Select(Literal(Constant.Int(1)), "+"), List(Literal(Constant.Int(2))))))
22
ValDef("bar", TypeIdent("Int"), Some(Apply(Select(Literal(Constant.Int(2)), "+"), List(Literal(Constant.Int(3))))))
3-
Pattern.Bind("x", Pattern.Value(Ident("_")))
3+
Pattern.Bind("x", Pattern.WildcardPattern())
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
DefDef("foo", Nil, Nil, Inferred(), None)
22
ValDef("bar", Inferred(), None)
3-
Pattern.Bind("x", Pattern.Value(Ident("_")))
3+
Pattern.Bind("x", Pattern.WildcardPattern())

tests/run/tasty-extractors-1.check

+7-7
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ Type.SymRef(IsClassDefSymbol(<scala.Int>), Type.ThisType(Type.SymRef(IsPackageDe
4040
Inlined(None, Nil, Match(Literal(Constant.String("a")), List(CaseDef(Pattern.Value(Literal(Constant.String("a"))), None, Block(Nil, Literal(Constant.Unit()))))))
4141
Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix())))
4242

43-
Inlined(None, Nil, Match(Literal(Constant.String("b")), List(CaseDef(Pattern.Bind("n", Pattern.Value(Ident("_"))), None, Block(Nil, Literal(Constant.Unit()))))))
43+
Inlined(None, Nil, Match(Literal(Constant.String("b")), List(CaseDef(Pattern.Bind("n", Pattern.WildcardPattern()), None, Block(Nil, Literal(Constant.Unit()))))))
4444
Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix())))
4545

4646
Inlined(None, Nil, Match(Literal(Constant.String("c")), List(CaseDef(Pattern.Bind("n", Pattern.TypeTest(TypeIdent("String"))), None, Block(Nil, Literal(Constant.Unit()))))))
4747
Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix())))
4848

49-
Inlined(None, Nil, Match(Literal(Constant.String("e")), List(CaseDef(Pattern.Value(Ident("_")), None, Block(Nil, Literal(Constant.Unit()))))))
49+
Inlined(None, Nil, Match(Literal(Constant.String("e")), List(CaseDef(Pattern.WildcardPattern(), None, Block(Nil, Literal(Constant.Unit()))))))
5050
Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix())))
5151

5252
Inlined(None, Nil, Match(Literal(Constant.String("f")), List(CaseDef(Pattern.TypeTest(TypeIdent("String")), None, Block(Nil, Literal(Constant.Unit()))))))
@@ -55,22 +55,22 @@ Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageD
5555
Inlined(None, Nil, Match(Typed(Literal(Constant.String("g")), TypeIdent("Any")), List(CaseDef(Pattern.Alternative(List(Pattern.TypeTest(TypeIdent("String")), Pattern.TypeTest(TypeIdent("Int")))), None, Block(Nil, Literal(Constant.Unit()))))))
5656
Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix())))
5757

58-
Inlined(None, Nil, Match(Literal(Constant.String("h")), List(CaseDef(Pattern.Value(Ident("_")), Some(Literal(Constant.Boolean(false))), Block(Nil, Literal(Constant.Unit()))))))
58+
Inlined(None, Nil, Match(Literal(Constant.String("h")), List(CaseDef(Pattern.WildcardPattern(), Some(Literal(Constant.Boolean(false))), Block(Nil, Literal(Constant.Unit()))))))
5959
Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix())))
6060

61-
Inlined(None, Nil, Block(List(ValDef("a", Inferred(), Some(Literal(Constant.String("o"))))), Match(Literal(Constant.String("i")), List(CaseDef(Pattern.Bind("a", Pattern.Value(Ident("_"))), None, Block(Nil, Literal(Constant.Unit())))))))
61+
Inlined(None, Nil, Block(List(ValDef("a", Inferred(), Some(Literal(Constant.String("o"))))), Match(Literal(Constant.String("i")), List(CaseDef(Pattern.Bind("a", Pattern.WildcardPattern()), None, Block(Nil, Literal(Constant.Unit())))))))
6262
Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix())))
6363

64-
Inlined(None, Nil, Match(Ident("Nil"), List(CaseDef(Pattern.Unapply(TypeApply(Select(Ident("List"), "unapplySeq"), List(Inferred())), Nil, List(Pattern.Bind("a", Pattern.Value(Ident("_"))), Pattern.Bind("b", Pattern.Value(Ident("_"))), Pattern.Bind("c", Pattern.Value(Ident("_"))))), None, Block(Nil, Literal(Constant.Unit()))))))
64+
Inlined(None, Nil, Match(Ident("Nil"), List(CaseDef(Pattern.Unapply(TypeApply(Select(Ident("List"), "unapplySeq"), List(Inferred())), Nil, List(Pattern.Bind("a", Pattern.WildcardPattern()), Pattern.Bind("b", Pattern.WildcardPattern()), Pattern.Bind("c", Pattern.WildcardPattern()))), None, Block(Nil, Literal(Constant.Unit()))))))
6565
Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix())))
6666

67-
Inlined(None, Nil, Try(Literal(Constant.Int(1)), List(CaseDef(Pattern.Value(Ident("_")), None, Block(Nil, Literal(Constant.Unit())))), None))
67+
Inlined(None, Nil, Try(Literal(Constant.Int(1)), List(CaseDef(Pattern.WildcardPattern(), None, Block(Nil, Literal(Constant.Unit())))), None))
6868
Type.OrType(Type.SymRef(IsClassDefSymbol(<scala.Int>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix()))), Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix()))))
6969

7070
Inlined(None, Nil, Try(Literal(Constant.Int(2)), Nil, Some(Literal(Constant.Unit()))))
7171
Type.ConstantType(Constant.Int(2))
7272

73-
Inlined(None, Nil, Try(Literal(Constant.Int(3)), List(CaseDef(Pattern.Value(Ident("_")), None, Block(Nil, Literal(Constant.Unit())))), Some(Literal(Constant.Unit()))))
73+
Inlined(None, Nil, Try(Literal(Constant.Int(3)), List(CaseDef(Pattern.WildcardPattern(), None, Block(Nil, Literal(Constant.Unit())))), Some(Literal(Constant.Unit()))))
7474
Type.OrType(Type.SymRef(IsClassDefSymbol(<scala.Int>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix()))), Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix()))))
7575

7676
Inlined(None, Nil, Apply(Select(Literal(Constant.String("a")), "=="), List(Literal(Constant.String("b")))))

tests/run/tasty-extractors-2.check

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageD
4949
Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("<init>", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil)), Nil, None, List(DefDef("a", Nil, Nil, Inferred(), Some(Literal(Constant.Int(0))))))), Literal(Constant.Unit())))
5050
Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix())))
5151

52-
Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("<init>", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil), TypeSelect(Select(Ident("_root_"), "scala"), "Product"), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), Nil, None, List(DefDef("productElementName", Nil, List(List(ValDef("x$1", TypeSelect(Select(Ident("_root_"), "scala"), "Int"), None))), TypeSelect(Select(Ident("java"), "lang"), "String"), Some(Match(Ident("x$1"), List(CaseDef(Pattern.Value(Ident("_")), None, Apply(Ident("throw"), List(Apply(Select(New(TypeSelect(Select(Ident("java"), "lang"), "IndexOutOfBoundsException")), "<init>"), List(Apply(Select(Select(Select(Ident("java"), "lang"), "String"), "valueOf"), List(Ident("x$1")))))))))))), DefDef("copy", Nil, List(Nil), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil))))), ValDef("Foo", TypeIdent("Foo$"), Some(Apply(Select(New(TypeIdent("Foo$")), "<init>"), Nil))), ClassDef("Foo$", DefDef("<init>", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil), Applied(Inferred(), List(Inferred())), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), Nil, Some(ValDef("_", Singleton(Ident("Foo")), None)), List(DefDef("apply", Nil, List(Nil), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil))), DefDef("unapply", Nil, List(List(ValDef("x$1", Inferred(), None))), Inferred(), Some(Literal(Constant.Boolean(true))))))), Literal(Constant.Unit())))
52+
Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("<init>", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil), TypeSelect(Select(Ident("_root_"), "scala"), "Product"), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), Nil, None, List(DefDef("productElementName", Nil, List(List(ValDef("x$1", TypeSelect(Select(Ident("_root_"), "scala"), "Int"), None))), TypeSelect(Select(Ident("java"), "lang"), "String"), Some(Match(Ident("x$1"), List(CaseDef(Pattern.WildcardPattern(), None, Apply(Ident("throw"), List(Apply(Select(New(TypeSelect(Select(Ident("java"), "lang"), "IndexOutOfBoundsException")), "<init>"), List(Apply(Select(Select(Select(Ident("java"), "lang"), "String"), "valueOf"), List(Ident("x$1")))))))))))), DefDef("copy", Nil, List(Nil), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil))))), ValDef("Foo", TypeIdent("Foo$"), Some(Apply(Select(New(TypeIdent("Foo$")), "<init>"), Nil))), ClassDef("Foo$", DefDef("<init>", Nil, List(Nil), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil), Applied(Inferred(), List(Inferred())), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), Nil, Some(ValDef("_", Singleton(Ident("Foo")), None)), List(DefDef("apply", Nil, List(Nil), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil))), DefDef("unapply", Nil, List(List(ValDef("x$1", Inferred(), None))), Inferred(), Some(Literal(Constant.Boolean(true))))))), Literal(Constant.Unit())))
5353
Type.SymRef(IsClassDefSymbol(<scala.Unit>), Type.ThisType(Type.SymRef(IsPackageDefSymbol(<scala>), NoPrefix())))
5454

5555
Inlined(None, Nil, Block(List(ClassDef("Foo1", DefDef("<init>", Nil, List(List(ValDef("a", TypeIdent("Int"), None))), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil)), Nil, None, List(ValDef("a", Inferred(), None)))), Literal(Constant.Unit())))

0 commit comments

Comments
 (0)