diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala index af9c9ca1ea79..e5425c5cb851 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/KernelImpl.scala @@ -516,7 +516,7 @@ class KernelImpl(val rootContext: core.Contexts.Context, val rootPosition: util. type Match = tpd.Match def matchMatch(x: Term)(implicit ctx: Context): Option[Match] = x match { - case x: tpd.Match => Some(x) + case x: tpd.Match if !x.selector.isEmpty => Some(x) case _ => None } @@ -529,6 +529,21 @@ class KernelImpl(val rootContext: core.Contexts.Context, val rootPosition: util. def Match_copy(original: Tree)(selector: Term, cases: List[CaseDef])(implicit ctx: Context): Match = tpd.cpy.Match(original)(selector, cases) + type ImplicitMatch = tpd.Match + + def matchImplicitMatch(x: Term)(implicit ctx: Context): Option[Match] = x match { + case x: tpd.Match if x.selector.isEmpty => Some(x) + case _ => None + } + + def ImplicitMatch_cases(self: Match)(implicit ctx: Context): List[CaseDef] = self.cases + + def ImplicitMatch_apply(cases: List[CaseDef])(implicit ctx: Context): ImplicitMatch = + withDefaultPos(ctx => tpd.Match(tpd.EmptyTree, cases)(ctx)) + + def ImplicitMatch_copy(original: Tree)(cases: List[CaseDef])(implicit ctx: Context): ImplicitMatch = + tpd.cpy.Match(original)(tpd.EmptyTree, cases) + type Try = tpd.Try def matchTry(x: Term)(implicit ctx: Context): Option[Try] = x match { diff --git a/compiler/test/dotc/pos-from-tasty.blacklist b/compiler/test/dotc/pos-from-tasty.blacklist index 35dd21fcbcbf..b5198d0d877a 100644 --- a/compiler/test/dotc/pos-from-tasty.blacklist +++ b/compiler/test/dotc/pos-from-tasty.blacklist @@ -24,6 +24,3 @@ i4006c.scala # Not sure what's wring here i4203.scala t6278-synth-def.scala - -# Need to print empty tree for implicit match -i5938.scala diff --git a/compiler/test/dotc/run-from-tasty.blacklist b/compiler/test/dotc/run-from-tasty.blacklist index e9828d0c0418..fe0acf63becb 100644 --- a/compiler/test/dotc/run-from-tasty.blacklist +++ b/compiler/test/dotc/run-from-tasty.blacklist @@ -3,13 +3,3 @@ eff-dependent.scala # It seems we still harmonize types in fromTasty. Not sure where this happens puzzle.scala - -# Need to print empty tree for implicit match -implicitMatch.scala -typeclass-derivation1.scala -typeclass-derivation2.scala -typeclass-derivation2a.scala -typeclass-derivation3.scala -derive-generic.scala -deriving-interesting-prefixes.scala -companion-loading.scala diff --git a/docs/docs/reference/other-new-features/tasty-reflect.md b/docs/docs/reference/other-new-features/tasty-reflect.md index ca44c0d6c6b8..53d2fa98572d 100644 --- a/docs/docs/reference/other-new-features/tasty-reflect.md +++ b/docs/docs/reference/other-new-features/tasty-reflect.md @@ -108,6 +108,7 @@ TASTy Reflect provides the following types: | +- Lambda | +- If | +- Match + | +- ImplicitMatch | +- Try | +- Return | +- Repeated diff --git a/library/src/scala/tasty/reflect/Core.scala b/library/src/scala/tasty/reflect/Core.scala index d1e6fb4709bc..6a9041c7201d 100644 --- a/library/src/scala/tasty/reflect/Core.scala +++ b/library/src/scala/tasty/reflect/Core.scala @@ -29,6 +29,7 @@ package scala.tasty.reflect * | +- Lambda * | +- If * | +- Match + * | +- ImplicitMatch * | +- Try * | +- Return * | +- Repeated @@ -213,6 +214,9 @@ trait Core { /** Tree representing a pattern match `x match { ... }` in the source code */ type Match = kernel.Match + /** Tree representing a pattern match `implicit match { ... }` in the source code */ + type ImplicitMatch = kernel.ImplicitMatch + /** Tree representing a tyr catch `try x catch { ... } finally { ... }` in the source code */ type Try = kernel.Try diff --git a/library/src/scala/tasty/reflect/Kernel.scala b/library/src/scala/tasty/reflect/Kernel.scala index 3fe083fc51f2..82799f81b6ff 100644 --- a/library/src/scala/tasty/reflect/Kernel.scala +++ b/library/src/scala/tasty/reflect/Kernel.scala @@ -28,6 +28,7 @@ package scala.tasty.reflect * | +- Lambda * | +- If * | +- Match + * | +- ImplicitMatch * | +- Try * | +- Return * | +- Repeated @@ -455,6 +456,16 @@ trait Kernel { def Match_apply(selector: Term, cases: List[CaseDef])(implicit ctx: Context): Match def Match_copy(original: Tree)(selector: Term, cases: List[CaseDef])(implicit ctx: Context): Match + /** Tree representing a pattern match `implicit match { ... }` in the source code */ + type ImplicitMatch <: Term + + def matchImplicitMatch(tree: Tree)(implicit ctx: Context): Option[ImplicitMatch] + + def ImplicitMatch_cases(self: ImplicitMatch)(implicit ctx: Context): List[CaseDef] + + def ImplicitMatch_apply(cases: List[CaseDef])(implicit ctx: Context): ImplicitMatch + def ImplicitMatch_copy(original: Tree)(cases: List[CaseDef])(implicit ctx: Context): ImplicitMatch + /** Tree representing a tyr catch `try x catch { ... } finally { ... }` in the source code */ type Try <: Term diff --git a/library/src/scala/tasty/reflect/Printers.scala b/library/src/scala/tasty/reflect/Printers.scala index 0f34ce7edc84..9a7dbbe1f75d 100644 --- a/library/src/scala/tasty/reflect/Printers.scala +++ b/library/src/scala/tasty/reflect/Printers.scala @@ -177,6 +177,8 @@ trait Printers this += "Term.Lambda(" += meth += ", " += tpt += ")" case Term.Match(selector, cases) => this += "Term.Match(" += selector += ", " ++= cases += ")" + case Term.ImplicitMatch(cases) => + this += "Term.ImplicitMatch(" ++= cases += ")" case Term.Return(expr) => this += "Term.Return(" += expr += ")" case Term.While(cond, body) => @@ -896,6 +898,10 @@ trait Printers this += highlightKeyword(" match", color) inBlock(printCases(cases, lineBreak())) + case Term.ImplicitMatch(cases) => + this += highlightKeyword("implicit match", color) + inBlock(printCases(cases, lineBreak())) + case Term.Try(body, cases, finallyOpt) => this += highlightKeyword("try ", color) printTree(body) diff --git a/library/src/scala/tasty/reflect/TreeOps.scala b/library/src/scala/tasty/reflect/TreeOps.scala index 4175892a4e2a..cc9ce7e5e3ac 100644 --- a/library/src/scala/tasty/reflect/TreeOps.scala +++ b/library/src/scala/tasty/reflect/TreeOps.scala @@ -511,6 +511,27 @@ trait TreeOps extends Core { } + object IsImplicitMatch { + /** Matches any ImplicitMatch and returns it */ + def unapply(tree: Tree)(implicit ctx: Context): Option[ImplicitMatch] = kernel.matchImplicitMatch(tree) + } + + /** Scala implicit `match` term */ + object ImplicitMatch { + + /** Creates a pattern match `implicit match { }` */ + def apply(cases: List[CaseDef])(implicit ctx: Context): ImplicitMatch = + kernel.ImplicitMatch_apply(cases) + + def copy(original: Tree)(cases: List[CaseDef])(implicit ctx: Context): ImplicitMatch = + kernel.ImplicitMatch_copy(original)(cases) + + /** Matches a pattern match `implicit match { }` */ + def unapply(tree: Tree)(implicit ctx: Context): Option[List[CaseDef]] = + kernel.matchImplicitMatch(tree).map(_.cases) + + } + object IsTry { /** Matches any Try and returns it */ def unapply(tree: Tree)(implicit ctx: Context): Option[Try] = kernel.matchTry(tree) @@ -701,6 +722,10 @@ trait TreeOps extends Core { def cases(implicit ctx: Context): List[CaseDef] = kernel.Match_cases(self) } + implicit class ImplicitMatchAPI(self: Term.ImplicitMatch) { + def cases(implicit ctx: Context): List[CaseDef] = kernel.ImplicitMatch_cases(self) + } + implicit class TryAPI(self: Term.Try) { def body(implicit ctx: Context): Term = kernel.Try_body(self) def cases(implicit ctx: Context): List[CaseDef] = kernel.Try_cases(self)