Skip to content

Commit 59e378a

Browse files
committed
Add TASTy Reflect Pattern.WildcardPattern
Wildcard are represented with Ident but are not valid terms. The current API exposed them an the contens on a Pattern.Value which advertives them as Terms. To avoid we add Pattern.WildcardPattern and stop returning them from Pattern.Value.
1 parent e750a8a commit 59e378a

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
@@ -916,7 +916,7 @@ class KernelImpl(val rootContext: core.Contexts.Context, val rootPosition: util.
916916

917917
def matchPattern_Value(pattern: Pattern): Option[Value] = pattern match {
918918
case lit: tpd.Literal => Some(lit)
919-
case ref: tpd.RefTree if ref.isTerm => Some(ref)
919+
case ref: tpd.RefTree if ref.isTerm && !tpd.isWildcardArg(ref) => Some(ref)
920920
case ths: tpd.This => Some(ths)
921921
case _ => None
922922
}
@@ -999,6 +999,18 @@ class KernelImpl(val rootContext: core.Contexts.Context, val rootPosition: util.
999999
def Pattern_TypeTest_module_copy(original: TypeTest)(tpt: TypeTree)(implicit ctx: Context): TypeTest =
10001000
tpd.cpy.Typed(original)(untpd.Ident(nme.WILDCARD).withSpan(original.span).withType(tpt.tpe), tpt)
10011001

1002+
type WildcardPattern = tpd.Ident
1003+
1004+
def matchPattern_WildcardPattern(pattern: Pattern)(implicit ctx: Context): Option[WildcardPattern] = {
1005+
pattern match {
1006+
case pattern: tpd.Ident if tpd.isWildcardArg(pattern) => Some(pattern)
1007+
case _ => None
1008+
}
1009+
}
1010+
1011+
def Pattern_WildcardPattern_module_apply(tpe: TypeOrBounds)(implicit ctx: Context): WildcardPattern =
1012+
untpd.Ident(nme.WILDCARD).withType(tpe)
1013+
10021014
//
10031015
// TYPES
10041016
//

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
@@ -791,6 +792,13 @@ trait Kernel {
791792
def Pattern_TypeTest_module_apply(tpt: TypeTree)(implicit ctx: Context): TypeTest
792793
def Pattern_TypeTest_module_copy(original: TypeTest)(tpt: TypeTree)(implicit ctx: Context): TypeTest
793794

795+
/** Pattern representing a `_` pattern */
796+
type WildcardPattern <: Pattern
797+
798+
def matchPattern_WildcardPattern(pattern: Pattern)(implicit ctx: Context): Option[WildcardPattern]
799+
800+
def Pattern_WildcardPattern_module_apply(tpe: TypeOrBounds)(implicit ctx: Context): WildcardPattern
801+
794802
//
795803
// TYPES
796804
//

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
@@ -256,6 +256,8 @@ trait Printers
256256
this += "Pattern.Alternative(" ++= patterns += ")"
257257
case Pattern.TypeTest(tpt) =>
258258
this += "Pattern.TypeTest(" += tpt += ")"
259+
case Pattern.WildcardPattern() =>
260+
this += "Pattern.WildcardPattern()"
259261
}
260262

261263
def visitConstant(x: Constant): Buffer = x match {
@@ -1293,12 +1295,12 @@ trait Printers
12931295

12941296
def printPattern(pattern: Pattern): Buffer = pattern match {
12951297
case Pattern.Value(v) =>
1296-
v match {
1297-
case Ident("_") => this += "_"
1298-
case _ => printTree(v)
1299-
}
1298+
printTree(v)
1299+
1300+
case Pattern.WildcardPattern() =>
1301+
this += "_"
13001302

1301-
case Pattern.Bind(name, Pattern.Value(Ident("_"))) =>
1303+
case Pattern.Bind(name, Pattern.WildcardPattern()) =>
13021304
this += name
13031305

13041306
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)