From e23c0ad0a643a02bd3147f661d6b6225b39d2039 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 27 Sep 2019 15:22:02 +0200 Subject: [PATCH 1/2] Join Tree and Pattern in TASTy Reflection --- community-build/community-projects/semanticdb | 2 +- .../ReflectionCompilerInterface.scala | 98 +++----------- .../scala/tasty/reflect/TreeUtils.scala | 45 ++----- .../scala/tasty/reflect/TreeUtils.scala | 1 - .../src/scala/internal/quoted/Matcher.scala | 117 ++++++++--------- library/src/scala/tasty/Reflection.scala | 1 - .../tasty/reflect/CompilerInterface.scala | 92 ++++--------- library/src/scala/tasty/reflect/Core.scala | 33 ++--- .../src/scala/tasty/reflect/PatternOps.scala | 122 ------------------ .../src/scala/tasty/reflect/Printers.scala | 74 +++-------- .../src/scala/tasty/reflect/SymbolOps.scala | 5 +- library/src/scala/tasty/reflect/TreeOps.scala | 67 +++++++++- .../Yretain-trees/tasty-definitions-2.check | 2 +- .../tasty-definitions-2/Macro_1.scala | 7 +- .../Yretain-trees/tasty-definitions-3.check | 2 +- .../tasty-definitions-3/Macro_1.scala | 6 +- .../tasty-custom-show/quoted_1.scala | 1 - tests/run-macros/tasty-extractors-1.check | 22 ++-- 18 files changed, 227 insertions(+), 470 deletions(-) delete mode 100644 library/src/scala/tasty/reflect/PatternOps.scala diff --git a/community-build/community-projects/semanticdb b/community-build/community-projects/semanticdb index ffd808fccc43..d0f81b86e82e 160000 --- a/community-build/community-projects/semanticdb +++ b/community-build/community-projects/semanticdb @@ -1 +1 @@ -Subproject commit ffd808fccc43b0ddf80ad3f4b54a9bc5aac561ef +Subproject commit d0f81b86e82ea029cfcd1dfbb98d0d66ba3e2542 diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index ced02ce30139..49de5fb09d43 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -109,6 +109,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend type Statement = tpd.Tree def matchStatement(tree: Tree)(given Context): Option[Statement] = tree match { + case _: PatternTree => None case tree if tree.isTerm => Some(tree) case _ => matchDefinition(tree) } @@ -231,6 +232,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend type Term = tpd.Tree def matchTerm(tree: Tree)(given Context): Option[Term] = tree match { + case _: PatternTree => None case x: tpd.SeqLiteral => Some(tree) case _ if tree.isTerm => Some(tree) case _ => None @@ -884,14 +886,14 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend case _ => None } - def CaseDef_pattern(self: CaseDef)(given Context): Pattern = self.pat + def CaseDef_pattern(self: CaseDef)(given Context): Tree = self.pat def CaseDef_guard(self: CaseDef)(given Context): Option[Term] = optional(self.guard) def CaseDef_rhs(self: CaseDef)(given Context): Term = self.body - def CaseDef_module_apply(pattern: Pattern, guard: Option[Term], body: Term)(given Context): CaseDef = + def CaseDef_module_apply(pattern: Tree, guard: Option[Term], body: Term)(given Context): CaseDef = tpd.CaseDef(pattern, guard.getOrElse(tpd.EmptyTree), body) - def CaseDef_module_copy(original: CaseDef)(pattern: Pattern, guard: Option[Term], body: Term)(given Context): CaseDef = + def CaseDef_module_copy(original: CaseDef)(pattern: Tree, guard: Option[Term], body: Term)(given Context): CaseDef = tpd.cpy.CaseDef(original)(pattern, guard.getOrElse(tpd.EmptyTree), body) type TypeCaseDef = tpd.CaseDef @@ -910,114 +912,55 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def TypeCaseDef_module_copy(original: TypeCaseDef)(pattern: TypeTree, body: TypeTree)(given Context): TypeCaseDef = tpd.cpy.CaseDef(original)(pattern, tpd.EmptyTree, body) - // - // PATTERNS - // - - type Pattern = tpd.Tree - - def Pattern_pos(self: Pattern)(given Context): Position = self.sourcePos - def Pattern_tpe(self: Pattern)(given Context): Type = self.tpe.stripTypeVar - def Pattern_symbol(self: Pattern)(given Context): Symbol = self.symbol - - type Value = tpd.Tree - - def matchPattern_Value(pattern: Pattern): Option[Value] = pattern match { - case lit: tpd.Literal => Some(lit) - case ref: tpd.RefTree if ref.isTerm && !tpd.isWildcardArg(ref) => Some(ref) - case ths: tpd.This => Some(ths) - case _ => None - } - - def Pattern_Value_value(self: Value)(given Context): Term = self - - def Pattern_Value_module_apply(term: Term)(given Context): Value = term match { - case lit: tpd.Literal => lit - case ref: tpd.RefTree if ref.isTerm => ref - case ths: tpd.This => ths - } - def Pattern_Value_module_copy(original: Value)(term: Term)(given Context): Value = term match { - case lit: tpd.Literal => tpd.cpy.Literal(original)(lit.const) - case ref: tpd.RefTree if ref.isTerm => tpd.cpy.Ref(original.asInstanceOf[tpd.RefTree])(ref.name) - case ths: tpd.This => tpd.cpy.This(original)(ths.qual) - } - type Bind = tpd.Bind - def matchPattern_Bind(x: Pattern)(given Context): Option[Bind] = x match { + def matchTree_Bind(x: Tree)(given Context): Option[Bind] = x match { case x: tpd.Bind if x.name.isTermName => Some(x) case _ => None } - def Pattern_Bind_name(self: Bind)(given Context): String = self.name.toString + def Tree_Bind_name(self: Bind)(given Context): String = self.name.toString - def Pattern_Bind_pattern(self: Bind)(given Context): Pattern = self.body + def Tree_Bind_pattern(self: Bind)(given Context): Tree = self.body - def Pattern_Bind_module_copy(original: Bind)(name: String, pattern: Pattern)(given Context): Bind = + def Tree_Bind_module_copy(original: Bind)(name: String, pattern: Tree)(given Context): Bind = withDefaultPos(tpd.cpy.Bind(original)(name.toTermName, pattern)) type Unapply = tpd.UnApply - def matchPattern_Unapply(pattern: Pattern)(given Context): Option[Unapply] = pattern match { + def matchTree_Unapply(pattern: Tree)(given Context): Option[Unapply] = pattern match { case pattern @ Trees.UnApply(_, _, _) => Some(pattern) case Trees.Typed(pattern @ Trees.UnApply(_, _, _), _) => Some(pattern) case _ => None } - def Pattern_Unapply_fun(self: Unapply)(given Context): Term = self.fun - def Pattern_Unapply_implicits(self: Unapply)(given Context): List[Term] = self.implicits - def Pattern_Unapply_patterns(self: Unapply)(given Context): List[Pattern] = effectivePatterns(self.patterns) + def Tree_Unapply_fun(self: Unapply)(given Context): Term = self.fun + def Tree_Unapply_implicits(self: Unapply)(given Context): List[Term] = self.implicits + def Tree_Unapply_patterns(self: Unapply)(given Context): List[Tree] = effectivePatterns(self.patterns) - def Pattern_Unapply_module_copy(original: Unapply)(fun: Term, implicits: List[Term], patterns: List[Pattern])(given Context): Unapply = + def Tree_Unapply_module_copy(original: Unapply)(fun: Term, implicits: List[Term], patterns: List[Tree])(given Context): Unapply = withDefaultPos(tpd.cpy.UnApply(original)(fun, implicits, patterns)) - private def effectivePatterns(patterns: List[Pattern]): List[Pattern] = patterns match { + private def effectivePatterns(patterns: List[Tree]): List[Tree] = patterns match { case patterns0 :+ Trees.SeqLiteral(elems, _) => patterns0 ::: elems case _ => patterns } type Alternatives = tpd.Alternative - def matchPattern_Alternatives(pattern: Pattern)(given Context): Option[Alternatives] = pattern match { + def matchTree_Alternatives(pattern: Tree)(given Context): Option[Alternatives] = pattern match { case pattern: tpd.Alternative => Some(pattern) case _ => None } - def Pattern_Alternatives_patterns(self: Alternatives)(given Context): List[Pattern] = self.trees + def Tree_Alternatives_patterns(self: Alternatives)(given Context): List[Tree] = self.trees - def Pattern_Alternatives_module_apply(patterns: List[Pattern])(given Context): Alternatives = + def Tree_Alternatives_module_apply(patterns: List[Tree])(given Context): Alternatives = withDefaultPos(tpd.Alternative(patterns)) - def Pattern_Alternatives_module_copy(original: Alternatives)(patterns: List[Pattern])(given Context): Alternatives = + def Tree_Alternatives_module_copy(original: Alternatives)(patterns: List[Tree])(given Context): Alternatives = tpd.cpy.Alternative(original)(patterns) - type TypeTest = tpd.Typed - - def matchPattern_TypeTest(pattern: Pattern)(given Context): Option[TypeTest] = pattern match { - case Trees.Typed(_: tpd.UnApply, _) => None - case pattern: tpd.Typed => Some(pattern) - case _ => None - } - - def Pattern_TypeTest_tpt(self: TypeTest)(given Context): TypeTree = self.tpt - - def Pattern_TypeTest_module_apply(tpt: TypeTree)(given ctx: Context): TypeTest = - withDefaultPos(tpd.Typed(untpd.Ident(nme.WILDCARD)(ctx.source).withType(tpt.tpe), tpt)) - - def Pattern_TypeTest_module_copy(original: TypeTest)(tpt: TypeTree)(given Context): TypeTest = - tpd.cpy.Typed(original)(untpd.Ident(nme.WILDCARD).withSpan(original.span).withType(tpt.tpe), tpt) - - type WildcardPattern = tpd.Ident - - def matchPattern_WildcardPattern(pattern: Pattern)(given Context): Option[WildcardPattern] = - pattern match { - case pattern: tpd.Ident if tpd.isWildcardArg(pattern) => Some(pattern) - case _ => None - } - - def Pattern_WildcardPattern_module_apply(tpe: TypeOrBounds)(given Context): WildcardPattern = - untpd.Ident(nme.WILDCARD).withType(tpe) - // // TYPES // @@ -1461,9 +1404,6 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Symbol_tree(self: Symbol)(given Context): Tree = FromSymbol.definitionFromSym(self) - def Symbol_pattern(self: Symbol)(given ctx: Context): Pattern = - FromSymbol.definitionFromSym(self) - def Symbol_privateWithin(self: Symbol)(given Context): Option[Type] = { val within = self.privateWithin if (within.exists && !self.is(core.Flags.Protected)) Some(within.typeRef) diff --git a/library/src-bootstrapped/scala/tasty/reflect/TreeUtils.scala b/library/src-bootstrapped/scala/tasty/reflect/TreeUtils.scala index f3c5e7c44030..9d22cae6f978 100644 --- a/library/src-bootstrapped/scala/tasty/reflect/TreeUtils.scala +++ b/library/src-bootstrapped/scala/tasty/reflect/TreeUtils.scala @@ -4,7 +4,6 @@ package reflect /** Tasty reflect case definition */ trait TreeUtils extends Core - with PatternOps with SymbolOps with TreeOps { self: Reflection => @@ -12,10 +11,8 @@ trait TreeUtils // Ties the knot of the traversal: call `foldOver(x, tree))` to dive in the `tree` node. def foldTree(x: X, tree: Tree)(given ctx: Context): X - def foldPattern(x: X, tree: Pattern)(given ctx: Context): X def foldTrees(x: X, trees: Iterable[Tree])(given ctx: Context): X = trees.foldLeft(x)(foldTree) - def foldPatterns(x: X, trees: Iterable[Pattern])(given ctx: Context): X = trees.foldLeft(x)(foldPattern) def foldOverTree(x: X, tree: Tree)(given ctx: Context): X = { def localCtx(definition: Definition): Context = definition.symbol.localContext @@ -92,32 +89,22 @@ trait TreeUtils foldTrees(foldTree(boundopt.fold(x)(foldTree(x, _)), selector), cases) case WildcardTypeTree() => x case TypeBoundsTree(lo, hi) => foldTree(foldTree(x, lo), hi) - case CaseDef(pat, guard, body) => foldTree(foldTrees(foldPattern(x, pat), guard), body) + case CaseDef(pat, guard, body) => foldTree(foldTrees(foldTree(x, pat), guard), body) case TypeCaseDef(pat, body) => foldTree(foldTree(x, pat), body) + case Bind(_, body) => foldTree(x, body) + case Unapply(fun, implicits, patterns) => foldTrees(foldTrees(foldTree(x, fun), implicits), patterns) + case Alternatives(patterns) => foldTrees(x, patterns) } } - - def foldOverPattern(x: X, tree: Pattern)(given ctx: Context): X = tree match { - case Pattern.Value(v) => foldTree(x, v) - case Pattern.Bind(_, body) => foldPattern(x, body) - case Pattern.Unapply(fun, implicits, patterns) => foldPatterns(foldTrees(foldTree(x, fun), implicits), patterns) - case Pattern.Alternatives(patterns) => foldPatterns(x, patterns) - case Pattern.TypeTest(tpt) => foldTree(x, tpt) - case Pattern.WildcardPattern() => x - } - } abstract class TreeTraverser extends TreeAccumulator[Unit] { def traverseTree(tree: Tree)(given ctx: Context): Unit = traverseTreeChildren(tree) - def traversePattern(tree: Pattern)(given ctx: Context): Unit = traversePatternChildren(tree) def foldTree(x: Unit, tree: Tree)(given ctx: Context): Unit = traverseTree(tree) - def foldPattern(x: Unit, tree: Pattern)(given ctx: Context) = traversePattern(tree) protected def traverseTreeChildren(tree: Tree)(given ctx: Context): Unit = foldOverTree((), tree) - protected def traversePatternChildren(tree: Pattern)(given ctx: Context): Unit = foldOverPattern((), tree) } @@ -138,6 +125,12 @@ trait TreeUtils transformCaseDef(tree) case IsTypeCaseDef(tree) => transformTypeCaseDef(tree) + case IsBind(pattern) => + Bind.copy(pattern)(pattern.name, pattern.pattern) + case IsUnapply(pattern) => + Unapply.copy(pattern)(transformTerm(pattern.fun), transformSubTrees(pattern.implicits), transformTrees(pattern.patterns)) + case IsAlternatives(pattern) => + Alternatives.copy(pattern)(transformTrees(pattern.patterns)) } } @@ -237,26 +230,13 @@ trait TreeUtils } def transformCaseDef(tree: CaseDef)(given ctx: Context): CaseDef = { - CaseDef.copy(tree)(transformPattern(tree.pattern), tree.guard.map(transformTerm), transformTerm(tree.rhs)) + CaseDef.copy(tree)(transformTree(tree.pattern), tree.guard.map(transformTerm), transformTerm(tree.rhs)) } def transformTypeCaseDef(tree: TypeCaseDef)(given ctx: Context): TypeCaseDef = { TypeCaseDef.copy(tree)(transformTypeTree(tree.pattern), transformTypeTree(tree.rhs)) } - def transformPattern(pattern: Pattern)(given ctx: Context): Pattern = pattern match { - case Pattern.Value(_) | Pattern.WildcardPattern() => - pattern - case Pattern.IsTypeTest(pattern) => - Pattern.TypeTest.copy(pattern)(transformTypeTree(pattern.tpt)) - case Pattern.IsUnapply(pattern) => - Pattern.Unapply.copy(pattern)(transformTerm(pattern.fun), transformSubTrees(pattern.implicits), transformPatterns(pattern.patterns)) - case Pattern.IsAlternatives(pattern) => - Pattern.Alternatives.copy(pattern)(transformPatterns(pattern.patterns)) - case Pattern.IsBind(pattern) => - Pattern.Bind.copy(pattern)(pattern.name, transformPattern(pattern.pattern)) - } - def transformStats(trees: List[Statement])(given ctx: Context): List[Statement] = trees mapConserve (transformStatement(_)) @@ -275,9 +255,6 @@ trait TreeUtils def transformTypeCaseDefs(trees: List[TypeCaseDef])(given ctx: Context): List[TypeCaseDef] = trees mapConserve (transformTypeCaseDef(_)) - def transformPatterns(trees: List[Pattern])(given ctx: Context): List[Pattern] = - trees mapConserve (transformPattern(_)) - def transformSubTrees[Tr <: Tree](trees: List[Tr])(given ctx: Context): List[Tr] = transformTrees(trees).asInstanceOf[List[Tr]] diff --git a/library/src-non-bootstrapped/scala/tasty/reflect/TreeUtils.scala b/library/src-non-bootstrapped/scala/tasty/reflect/TreeUtils.scala index 6731add13c44..204172d6e234 100644 --- a/library/src-non-bootstrapped/scala/tasty/reflect/TreeUtils.scala +++ b/library/src-non-bootstrapped/scala/tasty/reflect/TreeUtils.scala @@ -4,7 +4,6 @@ package reflect /** Tasty reflect case definition */ trait TreeUtils extends Core - with PatternOps with SymbolOps with TreeOps { self: Reflection => diff --git a/library/src/scala/internal/quoted/Matcher.scala b/library/src/scala/internal/quoted/Matcher.scala index f1643360bc5b..d3c8ce7c2c14 100644 --- a/library/src/scala/internal/quoted/Matcher.scala +++ b/library/src/scala/internal/quoted/Matcher.scala @@ -286,7 +286,7 @@ private[quoted] object Matcher { } private def caseMatches(scrutinee: CaseDef, pattern: CaseDef)(given Context, Env): Matching = { - val (caseEnv, patternMatch) = scrutinee.pattern =?= pattern.pattern + val (caseEnv, patternMatch) = patternsMatches(scrutinee.pattern, pattern.pattern) withEnv(caseEnv) { patternMatch && treeOptMatches(scrutinee.guard, pattern.guard) && @@ -294,70 +294,67 @@ private[quoted] object Matcher { } } - private given patternOps: { - - /** Check that the pattern trees match and return the contents from the pattern holes. - * Return a tuple with the new environment containing the bindings defined in this pattern and a matching. - * The matching is None if the pattern trees do not match otherwise return Some of a tuple containing all the contents in the holes. - * - * @param scrutinee The pattern tree beeing matched - * @param pattern The pattern tree that the scrutinee should match. Contains `patternHole` holes. - * @param `summon[Env]` Set of tuples containing pairs of symbols (s, p) where s defines a symbol in `scrutinee` which corresponds to symbol p in `pattern`. - * @return The new environment containing the bindings defined in this pattern tuppled with - * `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes. - */ - def (scrutinee: Pattern) =?= (pattern: Pattern)(given Context, Env): (Env, Matching) = (scrutinee, pattern) match { - case (Pattern.Value(v1), Pattern.Unapply(TypeApply(Select(patternHole @ Ident("patternHole"), "unapply"), List(tpt)), Nil, Nil)) - if patternHole.symbol.owner.fullName == "scala.runtime.quoted.Matcher$" => - (summon[Env], matched(v1.seal)) - - case (Pattern.Value(v1), Pattern.Value(v2)) => - (summon[Env], v1 =?= v2) - - case (Pattern.Bind(name1, body1), Pattern.Bind(name2, body2)) => - val bindEnv = summon[Env] + (scrutinee.symbol -> pattern.symbol) - (body1 =?= body2)(given summon[Context], bindEnv) - - case (Pattern.Unapply(fun1, implicits1, patterns1), Pattern.Unapply(fun2, implicits2, patterns2)) => - val (patEnv, patternsMatch) = foldPatterns(patterns1, patterns2) - (patEnv, fun1 =?= fun2 && implicits1 =?= implicits2 && patternsMatch) - - case (Pattern.Alternatives(patterns1), Pattern.Alternatives(patterns2)) => - foldPatterns(patterns1, patterns2) - - case (Pattern.TypeTest(tpt1), Pattern.TypeTest(tpt2)) => - (summon[Env], tpt1 =?= tpt2) - - case (Pattern.WildcardPattern(), Pattern.WildcardPattern()) => - (summon[Env], matched) - - case _ => - if (debug) - println( - s""">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - |Scrutinee - | ${scrutinee.show} - | - |${scrutinee.showExtractors} - | - |did not match pattern - | ${pattern.show} - | - |${pattern.showExtractors} - | - | - | - | - |""".stripMargin) - (summon[Env], notMatched) - } + /** Check that the pattern trees match and return the contents from the pattern holes. + * Return a tuple with the new environment containing the bindings defined in this pattern and a matching. + * The matching is None if the pattern trees do not match otherwise return Some of a tuple containing all the contents in the holes. + * + * @param scrutinee The pattern tree beeing matched + * @param pattern The pattern tree that the scrutinee should match. Contains `patternHole` holes. + * @param `summon[Env]` Set of tuples containing pairs of symbols (s, p) where s defines a symbol in `scrutinee` which corresponds to symbol p in `pattern`. + * @return The new environment containing the bindings defined in this pattern tuppled with + * `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes. + */ + private def patternsMatches(scrutinee: Tree, pattern: Tree)(given Context, Env): (Env, Matching) = (scrutinee, pattern) match { + case (IsTerm(v1), Unapply(TypeApply(Select(patternHole @ Ident("patternHole"), "unapply"), List(tpt)), Nil, Nil)) + if patternHole.symbol.owner.fullName == "scala.runtime.quoted.Matcher$" => + (summon[Env], matched(v1.seal)) + + case (Ident("_"), Ident("_")) => + (summon[Env], matched) + + case (Bind(name1, body1), Bind(name2, body2)) => + val bindEnv = summon[Env] + (scrutinee.symbol -> pattern.symbol) + patternsMatches(body1, body2)(given summon[Context], bindEnv) + + case (Unapply(fun1, implicits1, patterns1), Unapply(fun2, implicits2, patterns2)) => + val (patEnv, patternsMatch) = foldPatterns(patterns1, patterns2) + (patEnv, patternsMatches(fun1, fun2)._2 && implicits1 =?= implicits2 && patternsMatch) + + case (Alternatives(patterns1), Alternatives(patterns2)) => + foldPatterns(patterns1, patterns2) + + case (Typed(Ident("_"), tpt1), Typed(Ident("_"), tpt2)) => + (summon[Env], tpt1 =?= tpt2) + + case (IsTerm(v1), IsTerm(v2)) => + (summon[Env], v1 =?= v2) + + case _ => + if (debug) + println( + s""">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + |Scrutinee + | ${scrutinee.show} + | + |${scrutinee.showExtractors} + | + |did not match pattern + | ${pattern.show} + | + |${pattern.showExtractors} + | + | + | + | + |""".stripMargin) + (summon[Env], notMatched) } - private def foldPatterns(patterns1: List[Pattern], patterns2: List[Pattern])(given Context, Env): (Env, Matching) = { + private def foldPatterns(patterns1: List[Tree], patterns2: List[Tree])(given Context, Env): (Env, Matching) = { if (patterns1.size != patterns2.size) (summon[Env], notMatched) else patterns1.zip(patterns2).foldLeft((summon[Env], matched)) { (acc, x) => - val (env, res) = (x._1 =?= x._2)(given summon[Context], acc._1) + val (env, res) = patternsMatches(x._1, x._2)(given summon[Context], acc._1) (env, acc._2 && res) } } diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index bc7a7e1598f1..90b4d2052cac 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -13,7 +13,6 @@ class Reflection(private[scala] val internal: CompilerInterface) with ImplicitsOps with ImportSelectorOps with QuotedOps - with PatternOps with PositionOps with Printers with ReportingOps diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index 194be39a2984..c91fdcc3e20a 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -57,16 +57,13 @@ import scala.runtime.quoted.Unpickler * | * +- TypeBoundsTree * +- WildcardTypeTree +* | * +- CaseDef * +- TypeCaseDef - * - * +- Pattern --+- Value - * +- Bind - * +- Unapply - * +- Alternatives - * +- TypeTest - * +- WildcardPattern - * + * | + * +- Bind + * +- Unapply + * +- Alternatives * * +- NoPrefix * +- TypeOrBounds -+- TypeBounds @@ -718,12 +715,12 @@ trait CompilerInterface { def matchCaseDef(tree: Tree)(given ctx: Context): Option[CaseDef] - def CaseDef_pattern(self: CaseDef)(given ctx: Context): Pattern + def CaseDef_pattern(self: CaseDef)(given ctx: Context): Tree def CaseDef_guard(self: CaseDef)(given ctx: Context): Option[Term] def CaseDef_rhs(self: CaseDef)(given ctx: Context): Term - def CaseDef_module_apply(pattern: Pattern, guard: Option[Term], body: Term)(given ctx: Context): CaseDef - def CaseDef_module_copy(original: CaseDef)(pattern: Pattern, guard: Option[Term], body: Term)(given ctx: Context): CaseDef + def CaseDef_module_apply(pattern: Tree, guard: Option[Term], body: Term)(given ctx: Context): CaseDef + def CaseDef_module_copy(original: CaseDef)(pattern: Tree, guard: Option[Term], body: Term)(given ctx: Context): CaseDef /** Branch of a type pattern match */ type TypeCaseDef <: Tree @@ -740,73 +737,40 @@ trait CompilerInterface { // PATTERNS // - /** Pattern tree of the pattern part of a CaseDef */ - type Pattern <: AnyRef - - def Pattern_pos(self: Pattern)(given ctx: Context): Position - def Pattern_tpe(self: Pattern)(given ctx: Context): Type - def Pattern_symbol(self: Pattern)(given ctx: Context): Symbol - - /** Pattern representing a value. This includes `1`, ```x``` and `_` */ - type Value <: Pattern - - def matchPattern_Value(pattern: Pattern): Option[Value] - - def Pattern_Value_value(self: Value)(given ctx: Context): Term - - def Pattern_Value_module_apply(term: Term)(given ctx: Context): Value - def Pattern_Value_module_copy(original: Value)(term: Term)(given ctx: Context): Value + /** Tree representing a binding pattern `_ @ _` */ + type Bind <: Tree - /** Pattern representing a `_ @ _` binding. */ - type Bind <: Pattern + def matchTree_Bind(x: Tree)(given ctx: Context): Option[Bind] - def matchPattern_Bind(x: Pattern)(given ctx: Context): Option[Bind] + def Tree_Bind_name(self: Bind)(given ctx: Context): String - def Pattern_Bind_name(self: Bind)(given ctx: Context): String + def Tree_Bind_pattern(self: Bind)(given ctx: Context): Tree - def Pattern_Bind_pattern(self: Bind)(given ctx: Context): Pattern + def Tree_Bind_module_copy(original: Bind)(name: String, pattern: Tree)(given ctx: Context): Bind - def Pattern_Bind_module_copy(original: Bind)(name: String, pattern: Pattern)(given ctx: Context): Bind + /** Tree representing an unapply pattern `Xyz(...)` */ + type Unapply <: Tree - /** Pattern representing a `Xyz(...)` unapply. */ - type Unapply <: Pattern + def matchTree_Unapply(pattern: Tree)(given ctx: Context): Option[Unapply] - def matchPattern_Unapply(pattern: Pattern)(given ctx: Context): Option[Unapply] + def Tree_Unapply_fun(self: Unapply)(given ctx: Context): Term - def Pattern_Unapply_fun(self: Unapply)(given ctx: Context): Term + def Tree_Unapply_implicits(self: Unapply)(given ctx: Context): List[Term] - def Pattern_Unapply_implicits(self: Unapply)(given ctx: Context): List[Term] + def Tree_Unapply_patterns(self: Unapply)(given ctx: Context): List[Tree] - def Pattern_Unapply_patterns(self: Unapply)(given ctx: Context): List[Pattern] + def Tree_Unapply_module_copy(original: Unapply)(fun: Term, implicits: List[Term], patterns: List[Tree])(given ctx: Context): Unapply - def Pattern_Unapply_module_copy(original: Unapply)(fun: Term, implicits: List[Term], patterns: List[Pattern])(given ctx: Context): Unapply + /** Tree representing pattern alternatives `X | Y | ...` */ + type Alternatives <: Tree - /** Pattern representing `X | Y | ...` alternatives. */ - type Alternatives <: Pattern + def matchTree_Alternatives(pattern: Tree)(given ctx: Context): Option[Alternatives] - def matchPattern_Alternatives(pattern: Pattern)(given ctx: Context): Option[Alternatives] + def Tree_Alternatives_patterns(self: Alternatives)(given ctx: Context): List[Tree] - def Pattern_Alternatives_patterns(self: Alternatives)(given ctx: Context): List[Pattern] + def Tree_Alternatives_module_apply(patterns: List[Tree])(given ctx: Context): Alternatives + def Tree_Alternatives_module_copy(original: Alternatives)(patterns: List[Tree])(given ctx: Context): Alternatives - def Pattern_Alternatives_module_apply(patterns: List[Pattern])(given ctx: Context): Alternatives - def Pattern_Alternatives_module_copy(original: Alternatives)(patterns: List[Pattern])(given ctx: Context): Alternatives - - /** Pattern representing a `x: Y` type test. */ - type TypeTest <: Pattern - - def matchPattern_TypeTest(pattern: Pattern)(given ctx: Context): Option[TypeTest] - - def Pattern_TypeTest_tpt(self: TypeTest)(given ctx: Context): TypeTree - - def Pattern_TypeTest_module_apply(tpt: TypeTree)(given ctx: Context): TypeTest - def Pattern_TypeTest_module_copy(original: TypeTest)(tpt: TypeTree)(given ctx: Context): TypeTest - - /** Pattern representing a `_` pattern */ - type WildcardPattern <: Pattern - - def matchPattern_WildcardPattern(pattern: Pattern)(given ctx: Context): Option[WildcardPattern] - - def Pattern_WildcardPattern_module_apply(tpe: TypeOrBounds)(given ctx: Context): WildcardPattern // // TYPES @@ -1198,8 +1162,6 @@ trait CompilerInterface { def Symbol_tree(self: Symbol)(given ctx: Context): Tree - def Symbol_pattern(self: Symbol)(given ctx: Context): Pattern - def Symbol_isLocalDummy(self: Symbol)(given ctx: Context): Boolean def Symbol_isRefinementClass(self: Symbol)(given ctx: Context): Boolean diff --git a/library/src/scala/tasty/reflect/Core.scala b/library/src/scala/tasty/reflect/Core.scala index d046b21847a5..d74217a3001b 100644 --- a/library/src/scala/tasty/reflect/Core.scala +++ b/library/src/scala/tasty/reflect/Core.scala @@ -54,13 +54,16 @@ package scala.tasty.reflect * | * +- TypeBoundsTree * +- WildcardTypeTree + * | * +- CaseDef + * | * +- TypeCaseDef + * +- Bind + * +- Unapply + * +- Alternatives * * +- Pattern --+- Value - * +- Bind - * +- Unapply - * +- Alternatives + * +- TypeTest * +- WildcardPattern * @@ -284,26 +287,14 @@ trait Core { /** Branch of a type pattern match */ type TypeCaseDef = internal.TypeCaseDef - /** Pattern tree of the pattern part of a CaseDef */ - type Pattern = internal.Pattern - - /** Pattern representing a value. This includes `1`, ```x``` and `_` */ - type Value = internal.Value - - /** Pattern representing a `_ @ _` binding. */ - type Bind = internal.Bind - - /** Pattern representing a `Xyz(...)` unapply. */ - type Unapply = internal.Unapply - - /** Pattern representing `X | Y | ...` alternatives. */ - type Alternatives = internal.Alternatives + /** Pattern representing a `_ @ _` binding. */ + type Bind = internal.Bind - /** Pattern representing a `x: Y` type test. */ - type TypeTest = internal.TypeTest + /** Pattern representing a `Xyz(...)` unapply. */ + type Unapply = internal.Unapply - /** Pattern representing a `_` pattern */ - type WildcardPattern = internal.WildcardPattern + /** Pattern representing `X | Y | ...` alternatives. */ + type Alternatives = internal.Alternatives /** Type or bounds */ type TypeOrBounds = internal.TypeOrBounds diff --git a/library/src/scala/tasty/reflect/PatternOps.scala b/library/src/scala/tasty/reflect/PatternOps.scala deleted file mode 100644 index 491652ba8465..000000000000 --- a/library/src/scala/tasty/reflect/PatternOps.scala +++ /dev/null @@ -1,122 +0,0 @@ -package scala.tasty -package reflect - -trait PatternOps extends Core { - - implicit class ValueAPI(value: Value) { - def value(given ctx: Context): Term = internal.Pattern_Value_value(value) - } - - implicit class BindAPI(bind: Bind) { - def name(given ctx: Context): String = internal.Pattern_Bind_name(bind) - def pattern(given ctx: Context): Pattern = internal.Pattern_Bind_pattern(bind) - } - - implicit class UnapplyAPI(unapply: Unapply) { - def fun(given ctx: Context): Term = internal.Pattern_Unapply_fun(unapply) - def implicits(given ctx: Context): List[Term] = internal.Pattern_Unapply_implicits(unapply) - def patterns(given ctx: Context): List[Pattern] = internal.Pattern_Unapply_patterns(unapply) - } - - implicit class AlternativesAPI(alternatives: Alternatives) { - def patterns(given ctx: Context): List[Pattern] = internal.Pattern_Alternatives_patterns(alternatives) - } - - implicit class TypeTestAPI(typeTest: TypeTest) { - def tpt(given ctx: Context): TypeTree = internal.Pattern_TypeTest_tpt(typeTest) - } - - implicit class PatternAPI(self: Pattern) { - /** Position in the source code */ - def pos(given ctx: Context): Position = internal.Pattern_pos(self) - - def tpe(given ctx: Context): Type = internal.Pattern_tpe(self) - - def symbol(given ctx: Context): Symbol = internal.Pattern_symbol(self) - } - - object Pattern { - - object IsValue { - def unapply(pattern: Pattern)(given ctx: Context): Option[Value] = - internal.matchPattern_Value(pattern) - } - - object Value { - def apply(tpt: Term)(given ctx: Context): Value = - internal.Pattern_Value_module_apply(tpt) - def copy(original: Value)(tpt: Term)(given ctx: Context): Value = - internal.Pattern_Value_module_copy(original)(tpt) - def unapply(pattern: Pattern)(given ctx: Context): Option[Term] = - internal.matchPattern_Value(pattern).map(_.value) - } - - object IsBind { - def unapply(pattern: Pattern)(given ctx: Context): Option[Bind] = - internal.matchPattern_Bind(pattern) - } - - object Bind { - // TODO def apply(name: String, pattern: Pattern)(given ctx: Context): Bind - def copy(original: Bind)(name: String, pattern: Pattern)(given ctx: Context): Bind = - internal.Pattern_Bind_module_copy(original)(name, pattern) - def unapply(pattern: Pattern)(given ctx: Context): Option[(String, Pattern)] = - internal.matchPattern_Bind(pattern).map(x => (x.name, x.pattern)) - } - - object IsUnapply { - def unapply(pattern: Pattern)(given ctx: Context): Option[Unapply] = - internal.matchPattern_Unapply(pattern) - } - - object Unapply { - // TODO def apply(fun: Term, implicits: List[Term], patterns: List[Pattern])(given ctx: Context): Unapply - def copy(original: Unapply)(fun: Term, implicits: List[Term], patterns: List[Pattern])(given ctx: Context): Unapply = - internal.Pattern_Unapply_module_copy(original)(fun, implicits, patterns) - def unapply(pattern: Pattern)(given ctx: Context): Option[(Term, List[Term], List[Pattern])] = - internal.matchPattern_Unapply(pattern).map(x => (x.fun, x.implicits, x.patterns)) - } - - object IsAlternatives { - def unapply(pattern: Pattern)(given ctx: Context): Option[Alternatives] = - internal.matchPattern_Alternatives(pattern) - } - - object Alternatives { - def apply(patterns: List[Pattern])(given ctx: Context): Alternatives = - internal.Pattern_Alternatives_module_apply(patterns) - def copy(original: Alternatives)(patterns: List[Pattern])(given ctx: Context): Alternatives = - internal.Pattern_Alternatives_module_copy(original)(patterns) - def unapply(pattern: Pattern)(given ctx: Context): Option[List[Pattern]] = - internal.matchPattern_Alternatives(pattern).map(_.patterns) - } - - object IsTypeTest { - def unapply(pattern: Pattern)(given ctx: Context): Option[TypeTest] = - internal.matchPattern_TypeTest(pattern) - } - - object TypeTest { - def apply(tpt: TypeTree)(given ctx: Context): TypeTest = - internal.Pattern_TypeTest_module_apply(tpt) - def copy(original: TypeTest)(tpt: TypeTree)(given ctx: Context): TypeTest = - internal.Pattern_TypeTest_module_copy(original)(tpt) - def unapply(pattern: Pattern)(given ctx: Context): Option[TypeTree] = - internal.matchPattern_TypeTest(pattern).map(_.tpt) - } - - object IsWildcardPattern { - def unapply(pattern: Pattern)(given ctx: Context): Option[WildcardPattern] = - internal.matchPattern_WildcardPattern(pattern) - } - - object WildcardPattern { - def apply(tpe: TypeOrBounds)(given ctx: Context): WildcardPattern = - internal.Pattern_WildcardPattern_module_apply(tpe) - def unapply(pattern: Pattern)(given ctx: Context): Boolean = - internal.matchPattern_WildcardPattern(pattern).isDefined - } - - } - -} diff --git a/library/src/scala/tasty/reflect/Printers.scala b/library/src/scala/tasty/reflect/Printers.scala index afb04ef51f48..760e90779710 100644 --- a/library/src/scala/tasty/reflect/Printers.scala +++ b/library/src/scala/tasty/reflect/Printers.scala @@ -10,7 +10,6 @@ trait Printers with FlagsOps with IdOps with ImportSelectorOps - with PatternOps with PositionOps with SignatureOps with StandardDefinitions @@ -44,19 +43,6 @@ trait Printers new SourceCodePrinter(syntaxHighlight).showTypeOrBounds(tpe) } - /** Adds `show` as an extension method of a `Pattern` */ - implicit class PatternShowDeco(pattern: Pattern) { - /** Shows the tree as extractors */ - def showExtractors(given ctx: Context): String = new ExtractorsPrinter().showPattern(pattern) - - /** Shows the tree as fully typed source code */ - def show(given ctx: Context): String = show(SyntaxHighlight.plain) - - /** Shows the tree as fully typed source code */ - def show(syntaxHighlight: SyntaxHighlight)(given ctx: Context): String = - new SourceCodePrinter(syntaxHighlight).showPattern(pattern) - } - /** Adds `show` as an extension method of a `Constant` */ implicit class ConstantShowDeco(const: Constant) { /** Shows the tree as extractors */ @@ -101,8 +87,6 @@ trait Printers def showTree(tree: Tree)(given ctx: Context): String - def showPattern(pattern: Pattern)(given ctx: Context): String - def showTypeOrBounds(tpe: TypeOrBounds)(given ctx: Context): String def showConstant(const: Constant)(given ctx: Context): String @@ -118,9 +102,6 @@ trait Printers def showTree(tree: Tree)(given ctx: Context): String = new Buffer().visitTree(tree).result() - def showPattern(pattern: Pattern)(given ctx: Context): String = - new Buffer().visitPattern(pattern).result() - def showTypeOrBounds(tpe: TypeOrBounds)(given ctx: Context): String = new Buffer().visitType(tpe).result() @@ -271,21 +252,12 @@ trait Printers this += "CaseDef(" += pat += ", " += guard += ", " += body += ")" case TypeCaseDef(pat, body) => this += "TypeCaseDef(" += pat += ", " += body += ")" - } - - def visitPattern(x: Pattern): Buffer = x match { - case Pattern.Value(v) => - this += "Pattern.Value(" += v += ")" - case Pattern.Bind(name, body) => - this += "Pattern.Bind(\"" += name += "\", " += body += ")" - case Pattern.Unapply(fun, implicits, patterns) => - this += "Pattern.Unapply(" += fun += ", " ++= implicits += ", " ++= patterns += ")" - case Pattern.Alternatives(patterns) => - this += "Pattern.Alternative(" ++= patterns += ")" - case Pattern.TypeTest(tpt) => - this += "Pattern.TypeTest(" += tpt += ")" - case Pattern.WildcardPattern() => - this += "Pattern.WildcardPattern()" + case Bind(name, body) => + this += "Bind(\"" += name += "\", " += body += ")" + case Unapply(fun, implicits, patterns) => + this += "Unapply(" += fun += ", " ++= implicits += ", " ++= patterns += ")" + case Alternatives(patterns) => + this += "Alternative(" ++= patterns += ")" } def visitConstant(x: Constant): Buffer = x match { @@ -392,11 +364,6 @@ trait Printers def +++=(x: List[List[Tree]]): Buffer = { visitList(x, ++=); buff } } - private implicit class PatternOps(buff: Buffer) { - def +=(x: Pattern): Buffer = { visitPattern(x); buff } - def ++=(x: List[Pattern]): Buffer = { visitList(x, visitPattern); buff } - } - private implicit class ConstantOps(buff: Buffer) { def +=(x: Constant): Buffer = { visitConstant(x); buff } } @@ -459,9 +426,6 @@ trait Printers def showTree(tree: Tree)(given ctx: Context): String = (new Buffer).printTree(tree).result() - def showPattern(pattern: Pattern)(given ctx: Context): String = - (new Buffer).printPattern(pattern).result() - def showTypeOrBounds(tpe: TypeOrBounds)(given ctx: Context): String = (new Buffer).printTypeOrBound(tpe)(given None).result() @@ -1139,8 +1103,8 @@ trait Printers this } - def printPatterns(cases: List[Pattern], sep: String): Buffer = { - def printSeparated(list: List[Pattern]): Unit = list match { + def printPatterns(cases: List[Tree], sep: String): Buffer = { + def printSeparated(list: List[Tree]): Unit = list match { case Nil => case x :: Nil => printPattern(x) case x :: xs => @@ -1323,25 +1287,22 @@ trait Printers this } - def printPattern(pattern: Pattern): Buffer = pattern match { - case Pattern.Value(v) => - printTree(v) - - case Pattern.WildcardPattern() => + def printPattern(pattern: Tree): Buffer = pattern match { + case Ident("_") => this += "_" - case Pattern.Bind(name, Pattern.WildcardPattern()) => + case Bind(name, Ident("_")) => this += name - case Pattern.Bind(name, Pattern.TypeTest(tpt)) => + case Bind(name, Typed(Ident("_"), tpt)) => this += highlightValDef(name) += ": " printTypeTree(tpt) - case Pattern.Bind(name, pattern) => + case Bind(name, pattern) => this += name += " @ " printPattern(pattern) - case Pattern.Unapply(fun, implicits, patterns) => + case Unapply(fun, implicits, patterns) => val fun2 = fun match { case TypeApply(fun2, _) => fun2 case _ => fun @@ -1356,13 +1317,16 @@ trait Printers } inParens(printPatterns(patterns, ", ")) - case Pattern.Alternatives(trees) => + case Alternatives(trees) => inParens(printPatterns(trees, " | ")) - case Pattern.TypeTest(tpt) => + case Typed(Ident("_"), tpt) => this += "_: " printTypeOrBoundsTree(tpt) + case IsTerm(v) => + printTree(v) + case _ => throw new MatchError(pattern.showExtractors) diff --git a/library/src/scala/tasty/reflect/SymbolOps.scala b/library/src/scala/tasty/reflect/SymbolOps.scala index 98e8b8276e21..914db2037e1d 100644 --- a/library/src/scala/tasty/reflect/SymbolOps.scala +++ b/library/src/scala/tasty/reflect/SymbolOps.scala @@ -49,14 +49,11 @@ trait SymbolOps extends Core { selfSymbolOps: FlagsOps => * if this symbol `isTypeDef` it will return a `TypeDef`, * if this symbol `isValDef` it will return a `ValDef`, * if this symbol `isDefDef` it will return a `DefDef` + * if this symbol `isBind` it will return a `Bind` */ def tree(given ctx: Context): Tree = internal.Symbol_tree(self) - /** Pattern of this definition */ - def pattern(given ctx: Context): Pattern = - internal.Symbol_pattern(self) - /** Annotations attached to this symbol */ def annots(given ctx: Context): List[Term] = internal.Symbol_annots(self) diff --git a/library/src/scala/tasty/reflect/TreeOps.scala b/library/src/scala/tasty/reflect/TreeOps.scala index 40bb74a7f2b4..52ea20496372 100644 --- a/library/src/scala/tasty/reflect/TreeOps.scala +++ b/library/src/scala/tasty/reflect/TreeOps.scala @@ -1125,7 +1125,7 @@ trait TreeOps extends Core { // ----- CaseDefs ------------------------------------------------ implicit class CaseDefAPI(caseDef: CaseDef) { - def pattern(given ctx: Context): Pattern = internal.CaseDef_pattern(caseDef) + def pattern(given ctx: Context): Tree = internal.CaseDef_pattern(caseDef) def guard(given ctx: Context): Option[Term] = internal.CaseDef_guard(caseDef) def rhs(given ctx: Context): Term = internal.CaseDef_rhs(caseDef) } @@ -1136,13 +1136,13 @@ trait TreeOps extends Core { } object CaseDef { - def apply(pattern: Pattern, guard: Option[Term], rhs: Term)(given ctx: Context): CaseDef = + def apply(pattern: Tree, guard: Option[Term], rhs: Term)(given ctx: Context): CaseDef = internal.CaseDef_module_apply(pattern, guard, rhs) - def copy(original: CaseDef)(pattern: Pattern, guard: Option[Term], rhs: Term)(given ctx: Context): CaseDef = + def copy(original: CaseDef)(pattern: Tree, guard: Option[Term], rhs: Term)(given ctx: Context): CaseDef = internal.CaseDef_module_copy(original)(pattern, guard, rhs) - def unapply(tree: Tree)(given ctx: Context): Option[(Pattern, Option[Term], Term)] = + def unapply(tree: Tree)(given ctx: Context): Option[(Tree, Option[Term], Term)] = internal.matchCaseDef(tree).map( x => (x.pattern, x.guard, x.rhs)) } @@ -1166,4 +1166,63 @@ trait TreeOps extends Core { def unapply(tree: Tree)(given ctx: Context): Option[(TypeTree, TypeTree)] = internal.matchTypeCaseDef(tree).map( x => (x.pattern, x.rhs)) } + + // ----- Trees ------------------------------------------------ + + object IsBind { + def unapply(pattern: Tree)(given ctx: Context): Option[Bind] = + internal.matchTree_Bind(pattern) + } + + object Bind { + // TODO def apply(name: String, pattern: Tree)(given ctx: Context): Bind + def copy(original: Bind)(name: String, pattern: Tree)(given ctx: Context): Bind = + internal.Tree_Bind_module_copy(original)(name, pattern) + def unapply(pattern: Tree)(given ctx: Context): Option[(String, Tree)] = + internal.matchTree_Bind(pattern).map(x => (x.name, x.pattern)) + } + + implicit class BindAPI(bind: Bind) { + def name(given ctx: Context): String = internal.Tree_Bind_name(bind) + def pattern(given ctx: Context): Tree = internal.Tree_Bind_pattern(bind) + } + + object IsUnapply { + def unapply(pattern: Tree)(given ctx: Context): Option[Unapply] = + internal.matchTree_Unapply(pattern) + } + + object Unapply { + // TODO def apply(fun: Term, implicits: List[Term], patterns: List[Tree])(given ctx: Context): Unapply + def copy(original: Unapply)(fun: Term, implicits: List[Term], patterns: List[Tree])(given ctx: Context): Unapply = + internal.Tree_Unapply_module_copy(original)(fun, implicits, patterns) + def unapply(pattern: Tree)(given ctx: Context): Option[(Term, List[Term], List[Tree])] = + internal.matchTree_Unapply(pattern).map(x => (x.fun, x.implicits, x.patterns)) + } + + implicit class UnapplyAPI(unapply: Unapply) { + def fun(given ctx: Context): Term = internal.Tree_Unapply_fun(unapply) + def implicits(given ctx: Context): List[Term] = internal.Tree_Unapply_implicits(unapply) + def patterns(given ctx: Context): List[Tree] = internal.Tree_Unapply_patterns(unapply) + } + + object IsAlternatives { + def unapply(pattern: Tree)(given ctx: Context): Option[Alternatives] = + internal.matchTree_Alternatives(pattern) + } + + object Alternatives { + def apply(patterns: List[Tree])(given ctx: Context): Alternatives = + internal.Tree_Alternatives_module_apply(patterns) + def copy(original: Alternatives)(patterns: List[Tree])(given ctx: Context): Alternatives = + internal.Tree_Alternatives_module_copy(original)(patterns) + def unapply(pattern: Tree)(given ctx: Context): Option[List[Tree]] = + internal.matchTree_Alternatives(pattern).map(_.patterns) + } + + implicit class AlternativesAPI(alternatives: Alternatives) { + def patterns(given ctx: Context): List[Tree] = internal.Tree_Alternatives_patterns(alternatives) + } + + } diff --git a/tests/run-custom-args/Yretain-trees/tasty-definitions-2.check b/tests/run-custom-args/Yretain-trees/tasty-definitions-2.check index 6d640b4ee1bc..f487bcdcb6c2 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-definitions-2.check +++ b/tests/run-custom-args/Yretain-trees/tasty-definitions-2.check @@ -1,3 +1,3 @@ DefDef("foo", Nil, Nil, TypeIdent("Int"), Some(Apply(Select(Literal(Constant(1)), "+"), List(Literal(Constant(2)))))) ValDef("bar", TypeIdent("Int"), Some(Apply(Select(Literal(Constant(2)), "+"), List(Literal(Constant(3)))))) -Pattern.Bind("x", Pattern.WildcardPattern()) +Bind("x", Ident("_")) diff --git a/tests/run-custom-args/Yretain-trees/tasty-definitions-2/Macro_1.scala b/tests/run-custom-args/Yretain-trees/tasty-definitions-2/Macro_1.scala index 1888f572a840..b68ff003b267 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-definitions-2/Macro_1.scala +++ b/tests/run-custom-args/Yretain-trees/tasty-definitions-2/Macro_1.scala @@ -8,12 +8,9 @@ object Foo { def inspectBodyImpl(x: Expr[Int])(given qctx: QuoteContext): Expr[String] = { import qctx.tasty._ - def definitionString(sym: Symbol): Expr[String] = - if sym.isBind then sym.pattern.showExtractors - else sym.tree.showExtractors x.unseal match { - case Inlined(None, Nil, arg) => definitionString(arg.symbol) - case arg => definitionString(arg.symbol) // TODO should all by name parameters be in an inline node? + case Inlined(None, Nil, arg) => arg.symbol.tree.showExtractors + case arg => arg.symbol.tree.showExtractors // TODO should all by name parameters be in an inline node? } } diff --git a/tests/run-custom-args/Yretain-trees/tasty-definitions-3.check b/tests/run-custom-args/Yretain-trees/tasty-definitions-3.check index 5b7a3da23416..11668d95952e 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-definitions-3.check +++ b/tests/run-custom-args/Yretain-trees/tasty-definitions-3.check @@ -1,3 +1,3 @@ DefDef("foo", Nil, Nil, Inferred(), None) ValDef("bar", Inferred(), None) -Pattern.Bind("x", Pattern.WildcardPattern()) +Bind("x", Ident("_")) diff --git a/tests/run-custom-args/Yretain-trees/tasty-definitions-3/Macro_1.scala b/tests/run-custom-args/Yretain-trees/tasty-definitions-3/Macro_1.scala index 335dd01eb392..4fc2489292d9 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-definitions-3/Macro_1.scala +++ b/tests/run-custom-args/Yretain-trees/tasty-definitions-3/Macro_1.scala @@ -8,11 +8,9 @@ object Foo { def inspectBodyImpl(x: Expr[Int])(given qctx: QuoteContext): Expr[String] = { import qctx.tasty._ - def definitionString(sym: Symbol): Expr[String] = - if sym.isBind then sym.pattern.showExtractors else sym.tree.showExtractors x.unseal match { - case Inlined(None, Nil, arg) => definitionString(arg.symbol) - case arg => definitionString(arg.symbol) // TODO should all by name parameters be in an inline node? + case Inlined(None, Nil, arg) => arg.symbol.tree.showExtractors + case arg => arg.symbol.tree.showExtractors // TODO should all by name parameters be in an inline node? } } } diff --git a/tests/run-macros/tasty-custom-show/quoted_1.scala b/tests/run-macros/tasty-custom-show/quoted_1.scala index 3eb638380162..aefdbbf79c9d 100644 --- a/tests/run-macros/tasty-custom-show/quoted_1.scala +++ b/tests/run-macros/tasty-custom-show/quoted_1.scala @@ -42,7 +42,6 @@ object Macros { import qctx.tasty._ new Printer { def showTree(tree: Tree)(implicit ctx: Context): String = "Tree" - def showPattern(pattern: Pattern)(implicit ctx: Context): String = "Pattern" def showTypeOrBounds(tpe: TypeOrBounds)(implicit ctx: Context): String = "TypeOrBounds" def showConstant(const: Constant)(implicit ctx: Context): String = "Constant" def showSymbol(symbol: Symbol)(implicit ctx: Context): String = "Symbol" diff --git a/tests/run-macros/tasty-extractors-1.check b/tests/run-macros/tasty-extractors-1.check index 593d10788d1f..864c5103bcfb 100644 --- a/tests/run-macros/tasty-extractors-1.check +++ b/tests/run-macros/tasty-extractors-1.check @@ -37,40 +37,40 @@ Type.ConstantType(Constant(3)) Inlined(None, Nil, If(Typed(Literal(Constant(true)), TypeIdent("Boolean")), Literal(Constant(1)), Literal(Constant(2)))) Type.OrType(Type.ConstantType(Constant(1)), Type.ConstantType(Constant(2))) -Inlined(None, Nil, Match(Literal(Constant("a")), List(CaseDef(Pattern.Value(Literal(Constant("a"))), None, Block(Nil, Literal(Constant(()))))))) +Inlined(None, Nil, Match(Literal(Constant("a")), List(CaseDef(Literal(Constant("a")), None, Block(Nil, Literal(Constant(()))))))) Type.TypeRef(Type.ThisType(Type.TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Literal(Constant("b")), List(CaseDef(Pattern.Bind("n", Pattern.WildcardPattern()), None, Block(Nil, Literal(Constant(()))))))) +Inlined(None, Nil, Match(Literal(Constant("b")), List(CaseDef(Bind("n", Ident("_")), None, Block(Nil, Literal(Constant(()))))))) Type.TypeRef(Type.ThisType(Type.TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Literal(Constant("c")), List(CaseDef(Pattern.Bind("n", Pattern.TypeTest(TypeIdent("String"))), None, Block(Nil, Literal(Constant(()))))))) +Inlined(None, Nil, Match(Literal(Constant("c")), List(CaseDef(Bind("n", Typed(Ident("_"), TypeIdent("String"))), None, Block(Nil, Literal(Constant(()))))))) Type.TypeRef(Type.ThisType(Type.TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Literal(Constant("e")), List(CaseDef(Pattern.WildcardPattern(), None, Block(Nil, Literal(Constant(()))))))) +Inlined(None, Nil, Match(Literal(Constant("e")), List(CaseDef(Ident("_"), None, Block(Nil, Literal(Constant(()))))))) Type.TypeRef(Type.ThisType(Type.TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Literal(Constant("f")), List(CaseDef(Pattern.TypeTest(TypeIdent("String")), None, Block(Nil, Literal(Constant(()))))))) +Inlined(None, Nil, Match(Literal(Constant("f")), List(CaseDef(Typed(Ident("_"), TypeIdent("String")), None, Block(Nil, Literal(Constant(()))))))) Type.TypeRef(Type.ThisType(Type.TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Typed(Literal(Constant("g")), TypeIdent("Any")), List(CaseDef(Pattern.Alternative(List(Pattern.TypeTest(TypeIdent("String")), Pattern.TypeTest(TypeIdent("Int")))), None, Block(Nil, Literal(Constant(()))))))) +Inlined(None, Nil, Match(Typed(Literal(Constant("g")), TypeIdent("Any")), List(CaseDef(Alternative(List(Typed(Ident("_"), TypeIdent("String")), Typed(Ident("_"), TypeIdent("Int")))), None, Block(Nil, Literal(Constant(()))))))) Type.TypeRef(Type.ThisType(Type.TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Match(Literal(Constant("h")), List(CaseDef(Pattern.WildcardPattern(), Some(Literal(Constant(false))), Block(Nil, Literal(Constant(()))))))) +Inlined(None, Nil, Match(Literal(Constant("h")), List(CaseDef(Ident("_"), Some(Literal(Constant(false))), Block(Nil, Literal(Constant(()))))))) Type.TypeRef(Type.ThisType(Type.TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Block(List(ValDef("a", Inferred(), Some(Literal(Constant("o"))))), Match(Literal(Constant("i")), List(CaseDef(Pattern.Bind("a", Pattern.WildcardPattern()), None, Block(Nil, Literal(Constant(())))))))) +Inlined(None, Nil, Block(List(ValDef("a", Inferred(), Some(Literal(Constant("o"))))), Match(Literal(Constant("i")), List(CaseDef(Bind("a", Ident("_")), None, Block(Nil, Literal(Constant(())))))))) Type.TypeRef(Type.ThisType(Type.TypeRef(NoPrefix(), "scala")), "Unit") -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(()))))))) +Inlined(None, Nil, Match(Ident("Nil"), List(CaseDef(Unapply(TypeApply(Select(Ident("List"), "unapplySeq"), List(Inferred())), Nil, List(Bind("a", Ident("_")), Bind("b", Ident("_")), Bind("c", Ident("_")))), None, Block(Nil, Literal(Constant(()))))))) Type.TypeRef(Type.ThisType(Type.TypeRef(NoPrefix(), "scala")), "Unit") -Inlined(None, Nil, Try(Literal(Constant(1)), List(CaseDef(Pattern.WildcardPattern(), None, Block(Nil, Literal(Constant(()))))), None)) +Inlined(None, Nil, Try(Literal(Constant(1)), List(CaseDef(Ident("_"), None, Block(Nil, Literal(Constant(()))))), None)) Type.OrType(Type.ConstantType(Constant(1)), Type.TypeRef(Type.ThisType(Type.TypeRef(NoPrefix(), "scala")), "Unit")) Inlined(None, Nil, Try(Literal(Constant(2)), Nil, Some(Literal(Constant(()))))) Type.ConstantType(Constant(2)) -Inlined(None, Nil, Try(Literal(Constant(3)), List(CaseDef(Pattern.WildcardPattern(), None, Block(Nil, Literal(Constant(()))))), Some(Literal(Constant(()))))) +Inlined(None, Nil, Try(Literal(Constant(3)), List(CaseDef(Ident("_"), None, Block(Nil, Literal(Constant(()))))), Some(Literal(Constant(()))))) Type.OrType(Type.ConstantType(Constant(3)), Type.TypeRef(Type.ThisType(Type.TypeRef(NoPrefix(), "scala")), "Unit")) Inlined(None, Nil, Apply(Select(Literal(Constant("a")), "=="), List(Literal(Constant("b"))))) From 49ace53ecd47c346e8e19d42c24244b85fc3f196 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 1 Oct 2019 10:55:52 +0200 Subject: [PATCH 2/2] Update docs --- library/src/scala/tasty/reflect/Core.scala | 5 ----- 1 file changed, 5 deletions(-) diff --git a/library/src/scala/tasty/reflect/Core.scala b/library/src/scala/tasty/reflect/Core.scala index d74217a3001b..b6c5717db2c9 100644 --- a/library/src/scala/tasty/reflect/Core.scala +++ b/library/src/scala/tasty/reflect/Core.scala @@ -62,11 +62,6 @@ package scala.tasty.reflect * +- Unapply * +- Alternatives * - * +- Pattern --+- Value - - * +- TypeTest - * +- WildcardPattern - * * * +- NoPrefix * +- TypeOrBounds -+- TypeBounds