From fe80b80b3f966b3a318f1192bc76c1abeeb9c189 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 6 Nov 2019 08:49:17 +0100 Subject: [PATCH 1/5] Add rewrite prototype and couple of fixes --- .../ReflectionCompilerInterface.scala | 2 +- library/src/scala/quoted/Expr.scala | 5 ++ library/src/scala/quoted/Type.scala | 5 ++ .../tasty/reflect/CompilerInterface.scala | 2 +- .../tasty/reflect/SourceCodePrinter.scala | 3 + library/src/scala/tasty/reflect/TreeOps.scala | 2 +- tests/run-macros/flops-rewrite.check | 9 ++ tests/run-macros/flops-rewrite/Macro_1.scala | 83 +++++++++++++++++++ tests/run-macros/flops-rewrite/Test_2.scala | 9 ++ 9 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 tests/run-macros/flops-rewrite.check create mode 100644 tests/run-macros/flops-rewrite/Macro_1.scala create mode 100644 tests/run-macros/flops-rewrite/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index fdbb49776a54..2858dd93bf05 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -204,7 +204,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def DefDef_apply(symbol: Symbol, rhsFn: List[Type] => List[List[Term]] => Option[Term])(given Context): DefDef = withDefaultPos(tpd.polyDefDef(symbol.asTerm, tparams => vparamss => rhsFn(tparams)(vparamss).getOrElse(tpd.EmptyTree))) - def DefDef_copy(original: DefDef)(name: String, typeParams: List[TypeDef], paramss: List[List[ValDef]], tpt: TypeTree, rhs: Option[Term])(given Context): DefDef = + def DefDef_copy(original: Tree)(name: String, typeParams: List[TypeDef], paramss: List[List[ValDef]], tpt: TypeTree, rhs: Option[Term])(given Context): DefDef = tpd.cpy.DefDef(original)(name.toTermName, typeParams, paramss, tpt, rhs.getOrElse(tpd.EmptyTree)) type ValDef = tpd.ValDef diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index d533ac680f0f..74aea7684fc3 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -190,6 +190,11 @@ package internal { * May contain references to code defined outside this TastyTreeExpr instance. */ final class TastyTreeExpr[Tree](val tree: Tree, val scopeId: Int) extends Expr[Any] { + override def equals(that: Any): Boolean = that match { + case that: TastyTreeExpr[_] => tree == that.tree && scopeId == that.scopeId + case _ => false + } + override def hashCode: Int = tree.hashCode override def toString: String = s"Expr()" } diff --git a/library/src/scala/quoted/Type.scala b/library/src/scala/quoted/Type.scala index 73ae4144e0ab..789e66977c11 100644 --- a/library/src/scala/quoted/Type.scala +++ b/library/src/scala/quoted/Type.scala @@ -71,6 +71,11 @@ package internal { /** An Type backed by a tree */ final class TreeType[Tree](val typeTree: Tree, val scopeId: Int) extends scala.quoted.Type[Any] { + override def equals(that: Any): Boolean = that match { + case that: TreeType[_] => typeTree == that.typeTree && scopeId == that.scopeId + case _ => false + } + override def hashCode: Int = typeTree.hashCode override def toString: String = s"Type()" } diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index 1fa05958fbbb..bd2595ddc8bd 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -262,7 +262,7 @@ trait CompilerInterface { def DefDef_rhs(self: DefDef)(given ctx: Context): Option[Term] def DefDef_apply(symbol: Symbol, rhsFn: List[Type] => List[List[Term]] => Option[Term])(given ctx: Context): DefDef - def DefDef_copy(original: DefDef)(name: String, typeParams: List[TypeDef], paramss: List[List[ValDef]], tpt: TypeTree, rhs: Option[Term])(given ctx: Context): DefDef + def DefDef_copy(original: Tree)(name: String, typeParams: List[TypeDef], paramss: List[List[ValDef]], tpt: TypeTree, rhs: Option[Term])(given ctx: Context): DefDef /** Tree representing a value definition in the source code This inclues `val`, `lazy val`, `var`, `object` and parameter definitions. */ type ValDef <: Definition diff --git a/library/src/scala/tasty/reflect/SourceCodePrinter.scala b/library/src/scala/tasty/reflect/SourceCodePrinter.scala index 3921b8bd6c46..767ac4d2b461 100644 --- a/library/src/scala/tasty/reflect/SourceCodePrinter.scala +++ b/library/src/scala/tasty/reflect/SourceCodePrinter.scala @@ -514,6 +514,9 @@ class SourceCodePrinter[R <: Reflection & Singleton](val tasty: R)(syntaxHighlig case IsTypeTree(tpt) => printTypeTree(tpt) + case Closure(meth, _) => + printTree(meth) + case _ => throw new MatchError(tree.showExtractors) diff --git a/library/src/scala/tasty/reflect/TreeOps.scala b/library/src/scala/tasty/reflect/TreeOps.scala index 4b2068eeb159..ced2ac45a032 100644 --- a/library/src/scala/tasty/reflect/TreeOps.scala +++ b/library/src/scala/tasty/reflect/TreeOps.scala @@ -97,7 +97,7 @@ trait TreeOps extends Core { object DefDef { def apply(symbol: Symbol, rhsFn: List[Type] => List[List[Term]] => Option[Term])(given ctx: Context): DefDef = internal.DefDef_apply(symbol, rhsFn) - def copy(original: DefDef)(name: String, typeParams: List[TypeDef], paramss: List[List[ValDef]], tpt: TypeTree, rhs: Option[Term])(given ctx: Context): DefDef = + def copy(original: Tree)(name: String, typeParams: List[TypeDef], paramss: List[List[ValDef]], tpt: TypeTree, rhs: Option[Term])(given ctx: Context): DefDef = internal.DefDef_copy(original)(name, typeParams, paramss, tpt, rhs) def unapply(tree: Tree)(given ctx: Context): Option[(String, List[TypeDef], List[List[ValDef]], TypeTree, Option[Term])] = internal.matchDefDef(tree).map(x => (x.name, x.typeParams, x.paramss, x.returnTpt, x.rhs)) diff --git a/tests/run-macros/flops-rewrite.check b/tests/run-macros/flops-rewrite.check new file mode 100644 index 000000000000..0a1a7e272b5b --- /dev/null +++ b/tests/run-macros/flops-rewrite.check @@ -0,0 +1,9 @@ +scala.Nil.map[scala.Nothing](((x: scala.Nothing) => x)) +scala.Nil + +scala.Nil.map[scala.Nothing](((x: scala.Nothing) => x)).++[scala.Nothing](scala.Nil.map[scala.Nothing](((x: scala.Nothing) => x))) +scala.Nil + +scala.Nil.map[scala.Nothing](((x: scala.Nothing) => x)).++[scala.Int](scala.List.apply[scala.Int]((3: scala.[scala.Int]))).++[scala.Int](scala.Nil) +scala.List.apply[scala.Int]((3: scala.[scala.Int])) + diff --git a/tests/run-macros/flops-rewrite/Macro_1.scala b/tests/run-macros/flops-rewrite/Macro_1.scala new file mode 100644 index 000000000000..02f9133524f1 --- /dev/null +++ b/tests/run-macros/flops-rewrite/Macro_1.scala @@ -0,0 +1,83 @@ +import scala.quoted._ + +inline def rewrite[T](x: => T): T = ${ rewriteMacro('x) } + +private def rewriteMacro[T: Type](x: Expr[T])(given QuoteContext): Expr[T] = { + val rewriter = Rewriter( + postTransform = { + case '{ Nil.map[$t]($f) } => '{ Nil } + case '{ Nil.filter($f) } => '{ Nil } + case '{ Nil.++[$t]($xs) } => xs + case '{ ($xs: List[$t]).++(Nil) } => xs + case x => x + } + ) + + val x2 = rewriter.rewrite(x) + + '{ + println(${Expr(x.show)}) + println(${Expr(x2.show)}) + println() + $x2 + } +} + +private object Rewriter { + def apply(preTransform: Expr[Any] => Expr[Any] = identity, postTransform: Expr[Any] => Expr[Any] = identity, fixPoint: Boolean = false): Rewriter = + new Rewriter(preTransform, postTransform, fixPoint) +} + +private class Rewriter(preTransform: Expr[Any] => Expr[Any], postTransform: Expr[Any] => Expr[Any], fixPoint: Boolean) { + def rewrite[T](e: Expr[T])(given QuoteContext, Type[T]): Expr[T] = { + val e2 = checkedTransform(e, preTransform) + val e3 = rewriteChildren(e2) + val e4 = checkedTransform(e3, postTransform) + if fixPoint && e4 != e then rewrite(e4) + else e4 + } + + private def checkedTransform[T: Type](e: Expr[T], transform: Expr[T] => Expr[Any])(given QuoteContext): Expr[T] = { + transform(e) match { + case '{ $x: T } => x + case '{ $x: $t } => throw new Exception( + s"""Transformed + |${e.show} + |into + |${x.show} + | + |Expected type to be + |${summon[Type[T]].show} + |but was + |${t.show} + """.stripMargin) + } + } + + def rewriteChildren[T: Type](e: Expr[T])(given qctx: QuoteContext): Expr[T] = { + import qctx.tasty.{_, given} + class MapChildren extends TreeMap { + override def transformTerm(tree: Term)(given ctx: Context): Term = tree match { + case IsClosure(_) => + tree + case IsInlined(_) | IsSelect(_) => + transformChildrenTerm(tree) + case _ => + tree.tpe match { + case IsMethodType(_) | IsPolyType(_) => + transformChildrenTerm(tree) + case _ => + tree.seal match { + case '{ $x: $t } => rewrite(x).unseal + } + } + } + def transformChildrenTerm(tree: Term)(given ctx: Context): Term = + super.transformTerm(tree) + } + (new MapChildren).transformChildrenTerm(e.unseal).seal.cast[T] // Cast will only fail if this implementation has a bug + } + +} + + diff --git a/tests/run-macros/flops-rewrite/Test_2.scala b/tests/run-macros/flops-rewrite/Test_2.scala new file mode 100644 index 000000000000..abe8de92f824 --- /dev/null +++ b/tests/run-macros/flops-rewrite/Test_2.scala @@ -0,0 +1,9 @@ +object Test { + + def main(args: Array[String]): Unit = { + rewrite(Nil.map(x => x)) + rewrite(Nil.map(x => x) ++ Nil.map(x => x)) + rewrite(Nil.map(x => x) ++ List(3) ++ Nil) + } + +} From 8a90e457b0b8b52d5680f8baf6a2e81310f658b9 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 6 Nov 2019 10:15:47 +0100 Subject: [PATCH 2/5] Add type safe rewrite prototype --- tests/run-macros/flops-rewrite-2.check | 18 ++++ .../run-macros/flops-rewrite-2/Macro_1.scala | 101 ++++++++++++++++++ tests/run-macros/flops-rewrite-2/Test_2.scala | 14 +++ tests/run-macros/flops-rewrite/Macro_1.scala | 2 +- 4 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 tests/run-macros/flops-rewrite-2.check create mode 100644 tests/run-macros/flops-rewrite-2/Macro_1.scala create mode 100644 tests/run-macros/flops-rewrite-2/Test_2.scala diff --git a/tests/run-macros/flops-rewrite-2.check b/tests/run-macros/flops-rewrite-2.check new file mode 100644 index 000000000000..722703263e81 --- /dev/null +++ b/tests/run-macros/flops-rewrite-2.check @@ -0,0 +1,18 @@ +Macro_1$package.plus(1, 4) +5 + +Macro_1$package.plus(0, a) +a + +Macro_1$package.plus(a, b) +a.+(b) + +Macro_1$package.plus(Macro_1$package.plus(a, 0), Macro_1$package.plus(0, b)) +0.+(a).+(b) + +Macro_1$package.power(4, 5) +1024 + +Macro_1$package.power(a, 5) +a.*(a.*(a.*(a.*(1.*(a))))) + diff --git a/tests/run-macros/flops-rewrite-2/Macro_1.scala b/tests/run-macros/flops-rewrite-2/Macro_1.scala new file mode 100644 index 000000000000..9e7424ed2bd2 --- /dev/null +++ b/tests/run-macros/flops-rewrite-2/Macro_1.scala @@ -0,0 +1,101 @@ +import scala.quoted._ +import scala.quoted.matching._ + +inline def rewrite[T](x: => T): T = ${ rewriteMacro('x) } + +def plus(x: Int, y: Int): Int = x + y +def times(x: Int, y: Int): Int = x * y +def power(x: Int, y: Int): Int = if y == 0 then 1 else times(x, power(x, y - 1)) + +private def rewriteMacro[T: Type](x: Expr[T])(given QuoteContext): Expr[T] = { + val rewriter = Rewriter( + postTransform = List( + Transformation[Int] { + case '{ plus($x, $y) } => + (x, y) match { + case (Const(0), _) => y + case (Const(a), Const(b)) => Expr(a + b) + case (_, Const(_)) => '{ $y + $x } + case _ => '{ $x + $y } + } + case '{ times($x, $y) } => + (x, y) match { + case (Const(0), _) => '{0} + case (Const(1), _) => y + case (Const(a), Const(b)) => Expr(a * b) + case (_, Const(_)) => '{ $y * $x } + case _ => '{ $x * $y } + } + case '{ power(${Const(x)}, ${Const(y)}) } => + Expr(power(x, y)) + case '{ power($x, ${Const(y)}) } => + if y == 0 then '{1} + else '{ times($x, power($x, ${Expr(y-1)})) } + }), + fixPoint = true + ) + + val x2 = rewriter.rewrite(x) + + '{ + println(${Expr(x.show)}) + println(${Expr(x2.show)}) + println() + $x2 + } +} + +object Transformation { + def apply[T: Type](transform: PartialFunction[Expr[T], Expr[T]]) = + new Transformation(transform) +} +class Transformation[T: Type](transform: PartialFunction[Expr[T], Expr[T]]) { + def apply[U: Type](e: Expr[U])(given QuoteContext): Expr[U] = { + e match { + case '{ $e: T } => transform.applyOrElse(e, identity) match { case '{ $e2: U } => e2 } + case e => e + } + } +} + +private object Rewriter { + def apply(preTransform: List[Transformation[_]] = Nil, postTransform: List[Transformation[_]] = Nil, fixPoint: Boolean = false): Rewriter = + new Rewriter(preTransform, postTransform, fixPoint) +} + +private class Rewriter(preTransform: List[Transformation[_]] = Nil, postTransform: List[Transformation[_]] = Nil, fixPoint: Boolean) { + def rewrite[T](e: Expr[T])(given QuoteContext, Type[T]): Expr[T] = { + val e2 = preTransform.foldLeft(e)((ei, transform) => transform(ei)) + val e3 = rewriteChildren(e2) + val e4 = postTransform.foldLeft(e3)((ei, transform) => transform(ei)) + if fixPoint && e4 != e then rewrite(e4) + else e4 + } + + def rewriteChildren[T: Type](e: Expr[T])(given qctx: QuoteContext): Expr[T] = { + import qctx.tasty.{_, given} + class MapChildren extends TreeMap { + override def transformTerm(tree: Term)(given ctx: Context): Term = tree match { + case IsClosure(_) => + tree + case IsInlined(_) | IsSelect(_) => + transformChildrenTerm(tree) + case _ => + tree.tpe.widen match { + case IsMethodType(_) | IsPolyType(_) => + transformChildrenTerm(tree) + case _ => + tree.seal match { + case '{ $x: $t } => rewrite(x).unseal + } + } + } + def transformChildrenTerm(tree: Term)(given ctx: Context): Term = + super.transformTerm(tree) + } + (new MapChildren).transformChildrenTerm(e.unseal).seal.cast[T] // Cast will only fail if this implementation has a bug + } + +} + + diff --git a/tests/run-macros/flops-rewrite-2/Test_2.scala b/tests/run-macros/flops-rewrite-2/Test_2.scala new file mode 100644 index 000000000000..11f70a6c240f --- /dev/null +++ b/tests/run-macros/flops-rewrite-2/Test_2.scala @@ -0,0 +1,14 @@ +object Test { + + def main(args: Array[String]): Unit = { + val a: Int = 5 + val b: Int = 6 + rewrite(plus(1, 4)) + rewrite(plus(0, a)) + rewrite(plus(a, b)) + rewrite(plus(plus(a, 0), plus(0, b))) + rewrite(power(4, 5)) + rewrite(power(a, 5)) + } + +} diff --git a/tests/run-macros/flops-rewrite/Macro_1.scala b/tests/run-macros/flops-rewrite/Macro_1.scala index 02f9133524f1..4c432283b74c 100644 --- a/tests/run-macros/flops-rewrite/Macro_1.scala +++ b/tests/run-macros/flops-rewrite/Macro_1.scala @@ -63,7 +63,7 @@ private class Rewriter(preTransform: Expr[Any] => Expr[Any], postTransform: Expr case IsInlined(_) | IsSelect(_) => transformChildrenTerm(tree) case _ => - tree.tpe match { + tree.tpe.widen match { case IsMethodType(_) | IsPolyType(_) => transformChildrenTerm(tree) case _ => From 6558b3417d192884dbc4fae164f44a5b1c43e5c3 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 6 Nov 2019 16:08:24 +0100 Subject: [PATCH 3/5] Add a unified prototype --- tests/run-macros/flops-rewrite-3.check | 18 +++ .../run-macros/flops-rewrite-3/Macro_1.scala | 137 ++++++++++++++++++ tests/run-macros/flops-rewrite-3/Test_2.scala | 14 ++ 3 files changed, 169 insertions(+) create mode 100644 tests/run-macros/flops-rewrite-3.check create mode 100644 tests/run-macros/flops-rewrite-3/Macro_1.scala create mode 100644 tests/run-macros/flops-rewrite-3/Test_2.scala diff --git a/tests/run-macros/flops-rewrite-3.check b/tests/run-macros/flops-rewrite-3.check new file mode 100644 index 000000000000..722703263e81 --- /dev/null +++ b/tests/run-macros/flops-rewrite-3.check @@ -0,0 +1,18 @@ +Macro_1$package.plus(1, 4) +5 + +Macro_1$package.plus(0, a) +a + +Macro_1$package.plus(a, b) +a.+(b) + +Macro_1$package.plus(Macro_1$package.plus(a, 0), Macro_1$package.plus(0, b)) +0.+(a).+(b) + +Macro_1$package.power(4, 5) +1024 + +Macro_1$package.power(a, 5) +a.*(a.*(a.*(a.*(1.*(a))))) + diff --git a/tests/run-macros/flops-rewrite-3/Macro_1.scala b/tests/run-macros/flops-rewrite-3/Macro_1.scala new file mode 100644 index 000000000000..05df12a82f97 --- /dev/null +++ b/tests/run-macros/flops-rewrite-3/Macro_1.scala @@ -0,0 +1,137 @@ +import scala.quoted._ +import scala.quoted.matching._ + +inline def rewrite[T](x: => T): T = ${ rewriteMacro('x) } + +def plus(x: Int, y: Int): Int = x + y +def times(x: Int, y: Int): Int = x * y +def power(x: Int, y: Int): Int = if y == 0 then 1 else times(x, power(x, y - 1)) + +private def rewriteMacro[T: Type](x: Expr[T])(given QuoteContext): Expr[T] = { + val rewriter = Rewriter().withFixPoint.withPost( + Transformation.safe[Int] { + case '{ plus($x, $y) } => + (x, y) match { + case (Const(0), _) => y + case (Const(a), Const(b)) => Expr(a + b) + case (_, Const(_)) => '{ $y + $x } + case _ => '{ $x + $y } + } + case '{ times($x, $y) } => + (x, y) match { + case (Const(0), _) => '{0} + case (Const(1), _) => y + case (Const(a), Const(b)) => Expr(a * b) + case (_, Const(_)) => '{ $y * $x } + case _ => '{ $x * $y } + } + case '{ power(${Const(x)}, ${Const(y)}) } => + Expr(power(x, y)) + case '{ power($x, ${Const(y)}) } => + if y == 0 then '{1} + else '{ times($x, power($x, ${Expr(y-1)})) } + } + ) + + val x2 = rewriter.rewrite(x) + + '{ + println(${Expr(x.show)}) + println(${Expr(x2.show)}) + println() + $x2 + } +} + +object Transformation { + /** A restrictive transformer that is guaranteed to generate type correct code */ + def safe[T: Type](transform: PartialFunction[Expr[T], Expr[T]]): Transformation = + new SafeTransformation(transform) + + /** A general purpose transformer that may fail while transforming. + * It will check the type of the returned Expr and will throw if the type does not conform to the expected type. + */ + def checked(transform: PartialFunction[Expr[Any], Expr[Any]]): Transformation = + new CheckedTransformation(transform) +} + +class CheckedTransformation(transform: PartialFunction[Expr[Any], Expr[Any]]) extends Transformation { + def apply[T: Type](e: Expr[T])(given QuoteContext): Expr[T] = { + transform.applyOrElse(e, identity) match { + case '{ $e2: T } => e2 + case '{ $e2: $t } => + throw new Exception( + s"""Transformed + |${e.show} + |into + |${e2.show} + | + |Expected type to be + |${summon[Type[T]].show} + |but was + |${t.show} + """.stripMargin) + } + } +} + +class SafeTransformation[U: Type](transform: PartialFunction[Expr[U], Expr[U]]) extends Transformation { + def apply[T: Type](e: Expr[T])(given QuoteContext): Expr[T] = { + e match { + case '{ $e: U } => transform.applyOrElse(e, identity) match { case '{ $e2: T } => e2 } + case e => e + } + } +} + +abstract class Transformation { + def apply[T: Type](e: Expr[T])(given QuoteContext): Expr[T] +} + +private object Rewriter { + def apply(): Rewriter = new Rewriter(Nil, Nil, false) +} + +private class Rewriter private (preTransform: List[Transformation] = Nil, postTransform: List[Transformation] = Nil, fixPoint: Boolean) { + + def withFixPoint: Rewriter = + new Rewriter(preTransform, postTransform, fixPoint = true) + def withPre(transform: Transformation): Rewriter = + new Rewriter(transform :: preTransform, postTransform, fixPoint) + def withPost(transform: Transformation): Rewriter = + new Rewriter(preTransform, transform :: postTransform, fixPoint) + + def rewrite[T](e: Expr[T])(given QuoteContext, Type[T]): Expr[T] = { + val e2 = preTransform.foldLeft(e)((ei, transform) => transform(ei)) + val e3 = rewriteChildren(e2) + val e4 = postTransform.foldLeft(e3)((ei, transform) => transform(ei)) + if fixPoint && e4 != e then rewrite(e4) else e4 + } + + def rewriteChildren[T: Type](e: Expr[T])(given qctx: QuoteContext): Expr[T] = { + import qctx.tasty.{_, given} + class MapChildren extends TreeMap { + override def transformTerm(tree: Term)(given ctx: Context): Term = tree match { + case IsClosure(_) => + tree + case IsInlined(_) | IsSelect(_) => + transformChildrenTerm(tree) + case _ => + tree.tpe.widen match { + case IsMethodType(_) | IsPolyType(_) => + transformChildrenTerm(tree) + case _ => + tree.seal match { + case '{ $x: $t } => rewrite(x).unseal + } + } + } + def transformChildrenTerm(tree: Term)(given ctx: Context): Term = + super.transformTerm(tree) + } + (new MapChildren).transformChildrenTerm(e.unseal).seal.cast[T] // Cast will only fail if this implementation has a bug + } + +} + + diff --git a/tests/run-macros/flops-rewrite-3/Test_2.scala b/tests/run-macros/flops-rewrite-3/Test_2.scala new file mode 100644 index 000000000000..11f70a6c240f --- /dev/null +++ b/tests/run-macros/flops-rewrite-3/Test_2.scala @@ -0,0 +1,14 @@ +object Test { + + def main(args: Array[String]): Unit = { + val a: Int = 5 + val b: Int = 6 + rewrite(plus(1, 4)) + rewrite(plus(0, a)) + rewrite(plus(a, b)) + rewrite(plus(plus(a, 0), plus(0, b))) + rewrite(power(4, 5)) + rewrite(power(a, 5)) + } + +} From 58477a2fa442602d08e2f9d477dda005f65af32d Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 6 Nov 2019 16:49:47 +0100 Subject: [PATCH 4/5] Add comments --- library/src/scala/quoted/Expr.scala | 5 ++++- library/src/scala/quoted/Type.scala | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index 74aea7684fc3..ed9a35c5bea1 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -191,7 +191,10 @@ package internal { */ final class TastyTreeExpr[Tree](val tree: Tree, val scopeId: Int) extends Expr[Any] { override def equals(that: Any): Boolean = that match { - case that: TastyTreeExpr[_] => tree == that.tree && scopeId == that.scopeId + case that: TastyTreeExpr[_] => + // TastyTreeExpr are wrappers around trees, therfore they are equals if their trees are equal. + // All scopeId should be equal unless two different runs of the compiler created the trees. + tree == that.tree && scopeId == that.scopeId case _ => false } override def hashCode: Int = tree.hashCode diff --git a/library/src/scala/quoted/Type.scala b/library/src/scala/quoted/Type.scala index 789e66977c11..79e71c7ad279 100644 --- a/library/src/scala/quoted/Type.scala +++ b/library/src/scala/quoted/Type.scala @@ -72,7 +72,10 @@ package internal { /** An Type backed by a tree */ final class TreeType[Tree](val typeTree: Tree, val scopeId: Int) extends scala.quoted.Type[Any] { override def equals(that: Any): Boolean = that match { - case that: TreeType[_] => typeTree == that.typeTree && scopeId == that.scopeId + case that: TreeType[_] => typeTree == + // TastyTreeExpr are wrappers around trees, therfore they are equals if their trees are equal. + // All scopeId should be equal unless two different runs of the compiler created the trees. + that.typeTree && scopeId == that.scopeId case _ => false } override def hashCode: Int = typeTree.hashCode From 845fe936a7dff6a93499c47e75102f766d23874f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 6 Nov 2019 16:54:07 +0100 Subject: [PATCH 5/5] Allow all tree copy methods to receive any tree --- .../ReflectionCompilerInterface.scala | 48 +++++++++---------- .../tasty/reflect/CompilerInterface.scala | 46 +++++++++--------- library/src/scala/tasty/reflect/TreeOps.scala | 46 +++++++++--------- 3 files changed, 70 insertions(+), 70 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index 2858dd93bf05..e4888d9047ff 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -103,7 +103,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def PackageClause_apply(pid: Ref, stats: List[Tree])(given Context): PackageClause = withDefaultPos(tpd.PackageDef(pid.asInstanceOf[tpd.RefTree], stats)) - def PackageClause_copy(original: PackageClause)(pid: Ref, stats: List[Tree])(given Context): PackageClause = + def PackageClause_copy(original: Tree)(pid: Ref, stats: List[Tree])(given Context): PackageClause = tpd.cpy.PackageDef(original)(pid, stats) type Statement = tpd.Tree @@ -128,7 +128,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Import_apply(expr: Term, selectors: List[ImportSelector])(given Context): Import = withDefaultPos(tpd.Import(expr, selectors)) - def Import_copy(original: Import)(expr: Term, selectors: List[ImportSelector])(given Context): Import = + def Import_copy(original: Tree)(expr: Term, selectors: List[ImportSelector])(given Context): Import = tpd.cpy.Import(original)(expr, selectors) type Definition = tpd.Tree @@ -171,7 +171,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def ClassDef_body(self: ClassDef)(given Context): List[Statement] = ClassDef_rhs(self).body private def ClassDef_rhs(self: ClassDef) = self.rhs.asInstanceOf[tpd.Template] - def ClassDef_copy(original: ClassDef)(name: String, constr: DefDef, parents: List[Term | TypeTree], derived: List[TypeTree], selfOpt: Option[ValDef], body: List[Statement])(given Context): ClassDef = { + def ClassDef_copy(original: Tree)(name: String, constr: DefDef, parents: List[Term | TypeTree], derived: List[TypeTree], selfOpt: Option[ValDef], body: List[Statement])(given Context): ClassDef = { val Trees.TypeDef(_, originalImpl: tpd.Template) = original tpd.cpy.TypeDef(original)(name.toTypeName, tpd.cpy.Template(originalImpl)(constr, parents, derived, selfOpt.getOrElse(tpd.EmptyValDef), body)) } @@ -186,7 +186,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def TypeDef_rhs(self: TypeDef)(given Context): TypeTree | TypeBoundsTree = self.rhs def TypeDef_apply(symbol: Symbol)(given Context): TypeDef = withDefaultPos(tpd.TypeDef(symbol.asType)) - def TypeDef_copy(original: TypeDef)(name: String, rhs: TypeTree | TypeBoundsTree)(given Context): TypeDef = + def TypeDef_copy(original: Tree)(name: String, rhs: TypeTree | TypeBoundsTree)(given Context): TypeDef = tpd.cpy.TypeDef(original)(name.toTypeName, rhs) type DefDef = tpd.DefDef @@ -220,7 +220,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def ValDef_apply(symbol: Symbol, rhs: Option[Term])(given Context): ValDef = tpd.ValDef(symbol.asTerm, rhs.getOrElse(tpd.EmptyTree)) - def ValDef_copy(original: ValDef)(name: String, tpt: TypeTree, rhs: Option[Term])(given Context): ValDef = + def ValDef_copy(original: Tree)(name: String, tpt: TypeTree, rhs: Option[Term])(given Context): ValDef = tpd.cpy.ValDef(original)(name.toTermName, tpt, rhs.getOrElse(tpd.EmptyTree)) type Term = tpd.Tree @@ -347,8 +347,8 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def NamedArg_apply(name: String, arg: Term)(given Context): NamedArg = withDefaultPos(tpd.NamedArg(name.toTermName, arg)) - def NamedArg_copy(tree: NamedArg)(name: String, arg: Term)(given Context): NamedArg = - tpd.cpy.NamedArg(tree)(name.toTermName, arg) + def NamedArg_copy(original: Tree)(name: String, arg: Term)(given Context): NamedArg = + tpd.cpy.NamedArg(original)(name.toTermName, arg) type Apply = tpd.Apply @@ -672,7 +672,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def TypeIdent_name(self: TypeIdent)(given Context): String = self.name.toString - def TypeIdent_copy(original: TypeIdent)(name: String)(given Context): TypeIdent = + def TypeIdent_copy(original: Tree)(name: String)(given Context): TypeIdent = tpd.cpy.Ident(original)(name.toTypeName) type TypeSelect = tpd.Select @@ -688,7 +688,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def TypeSelect_apply(qualifier: Term, name: String)(given Context): TypeSelect = withDefaultPos(tpd.Select(qualifier, name.toTypeName)) - def TypeSelect_copy(original: TypeSelect)(qualifier: Term, name: String)(given Context): TypeSelect = + def TypeSelect_copy(original: Tree)(qualifier: Term, name: String)(given Context): TypeSelect = tpd.cpy.Select(original)(qualifier, name.toTypeName) @@ -702,7 +702,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Projection_qualifier(self: Projection)(given Context): TypeTree = self.qualifier def Projection_name(self: Projection)(given Context): String = self.name.toString - def Projection_copy(original: Projection)(qualifier: TypeTree, name: String)(given Context): Projection = + def Projection_copy(original: Tree)(qualifier: TypeTree, name: String)(given Context): Projection = tpd.cpy.Select(original)(qualifier, name.toTypeName) type Singleton = tpd.SingletonTypeTree @@ -717,7 +717,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Singleton_apply(ref: Term)(given Context): Singleton = withDefaultPos(tpd.SingletonTypeTree(ref)) - def Singleton_copy(original: Singleton)(ref: Term)(given Context): Singleton = + def Singleton_copy(original: Tree)(ref: Term)(given Context): Singleton = tpd.cpy.SingletonTypeTree(original)(ref) type Refined = tpd.RefinedTypeTree @@ -730,7 +730,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Refined_tpt(self: Refined)(given Context): TypeTree = self.tpt def Refined_refinements(self: Refined)(given Context): List[Definition] = self.refinements - def Refined_copy(original: Refined)(tpt: TypeTree, refinements: List[Definition])(given Context): Refined = + def Refined_copy(original: Tree)(tpt: TypeTree, refinements: List[Definition])(given Context): Refined = tpd.cpy.RefinedTypeTree(original)(tpt, refinements) type Applied = tpd.AppliedTypeTree @@ -746,7 +746,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Applied_apply(tpt: TypeTree, args: List[TypeTree | TypeBoundsTree])(given Context): Applied = withDefaultPos(tpd.AppliedTypeTree(tpt, args)) - def Applied_copy(original: Applied)(tpt: TypeTree, args: List[TypeTree | TypeBoundsTree])(given Context): Applied = + def Applied_copy(original: Tree)(tpt: TypeTree, args: List[TypeTree | TypeBoundsTree])(given Context): Applied = tpd.cpy.AppliedTypeTree(original)(tpt, args) type Annotated = tpd.Annotated @@ -762,7 +762,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Annotated_apply(arg: TypeTree, annotation: Term)(given Context): Annotated = withDefaultPos(tpd.Annotated(arg, annotation)) - def Annotated_copy(original: Annotated)(arg: TypeTree, annotation: Term)(given Context): Annotated = + def Annotated_copy(original: Tree)(arg: TypeTree, annotation: Term)(given Context): Annotated = tpd.cpy.Annotated(original)(arg, annotation) type MatchTypeTree = tpd.MatchTypeTree @@ -779,7 +779,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def MatchTypeTree_apply(bound: Option[TypeTree], selector: TypeTree, cases: List[TypeCaseDef])(given Context): MatchTypeTree = withDefaultPos(tpd.MatchTypeTree(bound.getOrElse(tpd.EmptyTree), selector, cases)) - def MatchTypeTree_copy(original: MatchTypeTree)(bound: Option[TypeTree], selector: TypeTree, cases: List[TypeCaseDef])(given Context): MatchTypeTree = + def MatchTypeTree_copy(original: Tree)(bound: Option[TypeTree], selector: TypeTree, cases: List[TypeCaseDef])(given Context): MatchTypeTree = tpd.cpy.MatchTypeTree(original)(bound.getOrElse(tpd.EmptyTree), selector, cases) type ByName = tpd.ByNameTypeTree @@ -794,7 +794,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def ByName_apply(result: TypeTree)(given Context): ByName = withDefaultPos(tpd.ByNameTypeTree(result)) - def ByName_copy(original: ByName)(result: TypeTree)(given Context): ByName = + def ByName_copy(original: Tree)(result: TypeTree)(given Context): ByName = tpd.cpy.ByNameTypeTree(original)(result) type LambdaTypeTree = tpd.LambdaTypeTree @@ -810,7 +810,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Lambdaapply(tparams: List[TypeDef], body: TypeTree | TypeBoundsTree)(given Context): LambdaTypeTree = withDefaultPos(tpd.LambdaTypeTree(tparams, body)) - def Lambdacopy(original: LambdaTypeTree)(tparams: List[TypeDef], body: TypeTree | TypeBoundsTree)(given Context): LambdaTypeTree = + def Lambdacopy(original: Tree)(tparams: List[TypeDef], body: TypeTree | TypeBoundsTree)(given Context): LambdaTypeTree = tpd.cpy.LambdaTypeTree(original)(tparams, body) type TypeBind = tpd.Bind @@ -823,7 +823,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def TypeBind_name(self: TypeBind)(given Context): String = self.name.toString def TypeBind_body(self: TypeBind)(given Context): TypeTree | TypeBoundsTree = self.body - def TypeBind_copy(original: TypeBind)(name: String, tpt: TypeTree | TypeBoundsTree)(given Context): TypeBind = + def TypeBind_copy(original: Tree)(name: String, tpt: TypeTree | TypeBoundsTree)(given Context): TypeBind = tpd.cpy.Bind(original)(name.toTypeName, tpt) type TypeBlock = tpd.Block @@ -839,7 +839,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def TypeBlock_apply(aliases: List[TypeDef], tpt: TypeTree)(given Context): TypeBlock = withDefaultPos(tpd.Block(aliases, tpt)) - def TypeBlock_copy(original: TypeBlock)(aliases: List[TypeDef], tpt: TypeTree)(given Context): TypeBlock = + def TypeBlock_copy(original: Tree)(aliases: List[TypeDef], tpt: TypeTree)(given Context): TypeBlock = tpd.cpy.Block(original)(aliases, tpt) type TypeBoundsTree = tpd.TypeBoundsTree @@ -883,7 +883,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend 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: Tree, guard: Option[Term], body: Term)(given Context): CaseDef = + def CaseDef_module_copy(original: Tree)(pattern: Tree, guard: Option[Term], body: Term)(given Context): CaseDef = tpd.cpy.CaseDef(original)(pattern, guard.getOrElse(tpd.EmptyTree), body) type TypeCaseDef = tpd.CaseDef @@ -899,7 +899,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def TypeCaseDef_module_apply(pattern: TypeTree, body: TypeTree)(given Context): TypeCaseDef = tpd.CaseDef(pattern, tpd.EmptyTree, body) - def TypeCaseDef_module_copy(original: TypeCaseDef)(pattern: TypeTree, body: TypeTree)(given Context): TypeCaseDef = + def TypeCaseDef_module_copy(original: Tree)(pattern: TypeTree, body: TypeTree)(given Context): TypeCaseDef = tpd.cpy.CaseDef(original)(pattern, tpd.EmptyTree, body) type Bind = tpd.Bind @@ -913,7 +913,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Tree_Bind_pattern(self: Bind)(given Context): Tree = self.body - def Tree_Bind_module_copy(original: Bind)(name: String, pattern: Tree)(given Context): Bind = + def Tree_Bind_module_copy(original: Tree)(name: String, pattern: Tree)(given Context): Bind = withDefaultPos(tpd.cpy.Bind(original)(name.toTermName, pattern)) type Unapply = tpd.UnApply @@ -928,7 +928,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend 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 Tree_Unapply_module_copy(original: Unapply)(fun: Term, implicits: List[Term], patterns: List[Tree])(given Context): Unapply = + def Tree_Unapply_module_copy(original: Tree)(fun: Term, implicits: List[Term], patterns: List[Tree])(given Context): Unapply = withDefaultPos(tpd.cpy.UnApply(original)(fun, implicits, patterns)) private def effectivePatterns(patterns: List[Tree]): List[Tree] = patterns match { @@ -948,7 +948,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Tree_Alternatives_module_apply(patterns: List[Tree])(given Context): Alternatives = withDefaultPos(tpd.Alternative(patterns)) - def Tree_Alternatives_module_copy(original: Alternatives)(patterns: List[Tree])(given Context): Alternatives = + def Tree_Alternatives_module_copy(original: Tree)(patterns: List[Tree])(given Context): Alternatives = tpd.cpy.Alternative(original)(patterns) // diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index bd2595ddc8bd..b4007c4460ed 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -193,7 +193,7 @@ trait CompilerInterface { def PackageClause_apply(pid: Ref, stats: List[Tree])(given ctx: Context): PackageClause - def PackageClause_copy(original: PackageClause)(pid: Ref, stats: List[Tree])(given ctx: Context): PackageClause + def PackageClause_copy(original: Tree)(pid: Ref, stats: List[Tree])(given ctx: Context): PackageClause /** Tree representing a statement in the source code */ type Statement <: Tree @@ -211,7 +211,7 @@ trait CompilerInterface { def Import_apply(iexpr: Term, selectors: List[ImportSelector])(given ctx: Context): Import - def Import_copy(original: Import)(expr: Term, selectors: List[ImportSelector])(given ctx: Context): Import + def Import_copy(original: Tree)(expr: Term, selectors: List[ImportSelector])(given ctx: Context): Import /** Tree representing a definition in the source code. It can be `PackageDef`, `ClassDef`, `TypeDef`, `DefDef` or `ValDef` */ type Definition <: Statement @@ -239,7 +239,7 @@ trait CompilerInterface { def ClassDef_self(self: ClassDef)(given ctx: Context): Option[ValDef] def ClassDef_body(self: ClassDef)(given ctx: Context): List[Statement] - def ClassDef_copy(original: ClassDef)(name: String, constr: DefDef, parents: List[Tree/* Term | TypeTree */], derived: List[TypeTree], selfOpt: Option[ValDef], body: List[Statement])(given ctx: Context): ClassDef + def ClassDef_copy(original: Tree)(name: String, constr: DefDef, parents: List[Tree/* Term | TypeTree */], derived: List[TypeTree], selfOpt: Option[ValDef], body: List[Statement])(given ctx: Context): ClassDef /** Tree representing a type (paramter or member) definition in the source code */ type TypeDef <: Definition @@ -249,7 +249,7 @@ trait CompilerInterface { def TypeDef_rhs(self: TypeDef)(given ctx: Context): Tree /*TypeTree | TypeBoundsTree*/ def TypeDef_apply(symbol: Symbol)(given ctx: Context): TypeDef - def TypeDef_copy(original: TypeDef)(name: String, rhs: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): TypeDef + def TypeDef_copy(original: Tree)(name: String, rhs: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): TypeDef /** Tree representing a method definition in the source code */ type DefDef <: Definition @@ -273,7 +273,7 @@ trait CompilerInterface { def ValDef_rhs(self: ValDef)(given ctx: Context): Option[Term] def ValDef_apply(symbol: Symbol, rhs: Option[Term])(given ctx: Context): ValDef - def ValDef_copy(original: ValDef)(name: String, tpt: TypeTree, rhs: Option[Term])(given ctx: Context): ValDef + def ValDef_copy(original: Tree)(name: String, tpt: TypeTree, rhs: Option[Term])(given ctx: Context): ValDef /** Tree representing an expression in the source code */ type Term <: Statement @@ -355,7 +355,7 @@ trait CompilerInterface { def NamedArg_value(self: NamedArg)(given ctx: Context): Term def NamedArg_apply(name: String, arg: Term)(given ctx: Context): NamedArg - def NamedArg_copy(tree: NamedArg)(name: String, arg: Term)(given ctx: Context): NamedArg + def NamedArg_copy(original: Tree)(name: String, arg: Term)(given ctx: Context): NamedArg /** Tree an application of arguments. It represents a single list of arguments, multiple argument lists will have nested `Apply`s */ type Apply <: Term @@ -563,7 +563,7 @@ trait CompilerInterface { def TypeIdent_name(self: TypeIdent)(given ctx: Context): String - def TypeIdent_copy(original: TypeIdent)(name: String)(given ctx: Context): TypeIdent + def TypeIdent_copy(original: Tree)(name: String)(given ctx: Context): TypeIdent /** Type tree representing a selection of definition with a given name on a given term prefix */ type TypeSelect <: TypeTree @@ -574,7 +574,7 @@ trait CompilerInterface { def TypeSelect_name(self: TypeSelect)(given ctx: Context): String def TypeSelect_apply(qualifier: Term, name: String)(given ctx: Context): TypeSelect - def TypeSelect_copy(original: TypeSelect)(qualifier: Term, name: String)(given ctx: Context): TypeSelect + def TypeSelect_copy(original: Tree)(qualifier: Term, name: String)(given ctx: Context): TypeSelect /** Type tree representing a selection of definition with a given name on a given type prefix */ type Projection <: TypeTree @@ -584,7 +584,7 @@ trait CompilerInterface { def Projection_qualifier(self: Projection)(given ctx: Context): TypeTree def Projection_name(self: Projection)(given ctx: Context): String - def Projection_copy(original: Projection)(qualifier: TypeTree, name: String)(given ctx: Context): Projection + def Projection_copy(original: Tree)(qualifier: TypeTree, name: String)(given ctx: Context): Projection /** Type tree representing a singleton type */ type Singleton <: TypeTree @@ -594,7 +594,7 @@ trait CompilerInterface { def Singleton_ref(self: Singleton)(given ctx: Context): Term def Singleton_apply(ref: Term)(given ctx: Context): Singleton - def Singleton_copy(original: Singleton)(ref: Term)(given ctx: Context): Singleton + def Singleton_copy(original: Tree)(ref: Term)(given ctx: Context): Singleton /** Type tree representing a type refinement */ type Refined <: TypeTree @@ -604,7 +604,7 @@ trait CompilerInterface { def Refined_tpt(self: Refined)(given ctx: Context): TypeTree def Refined_refinements(self: Refined)(given ctx: Context): List[Definition] - def Refined_copy(original: Refined)(tpt: TypeTree, refinements: List[Definition])(given ctx: Context): Refined + def Refined_copy(original: Tree)(tpt: TypeTree, refinements: List[Definition])(given ctx: Context): Refined /** Type tree representing a type application */ type Applied <: TypeTree @@ -615,7 +615,7 @@ trait CompilerInterface { def Applied_args(self: Applied)(given ctx: Context): List[Tree /*TypeTree | TypeBoundsTree*/] def Applied_apply(tpt: TypeTree, args: List[Tree /*TypeTree | TypeBoundsTree*/])(given ctx: Context): Applied - def Applied_copy(original: Applied)(tpt: TypeTree, args: List[Tree /*TypeTree | TypeBoundsTree*/])(given ctx: Context): Applied + def Applied_copy(original: Tree)(tpt: TypeTree, args: List[Tree /*TypeTree | TypeBoundsTree*/])(given ctx: Context): Applied /** Type tree representing an annotated type */ type Annotated <: TypeTree @@ -626,7 +626,7 @@ trait CompilerInterface { def Annotated_annotation(self: Annotated)(given ctx: Context): Term def Annotated_apply(arg: TypeTree, annotation: Term)(given ctx: Context): Annotated - def Annotated_copy(original: Annotated)(arg: TypeTree, annotation: Term)(given ctx: Context): Annotated + def Annotated_copy(original: Tree)(arg: TypeTree, annotation: Term)(given ctx: Context): Annotated /** Type tree representing a type match */ type MatchTypeTree <: TypeTree @@ -638,7 +638,7 @@ trait CompilerInterface { def MatchTypeTree_cases(self: MatchTypeTree)(given ctx: Context): List[TypeCaseDef] def MatchTypeTree_apply(bound: Option[TypeTree], selector: TypeTree, cases: List[TypeCaseDef])(given ctx: Context): MatchTypeTree - def MatchTypeTree_copy(original: MatchTypeTree)(bound: Option[TypeTree], selector: TypeTree, cases: List[TypeCaseDef])(given ctx: Context): MatchTypeTree + def MatchTypeTree_copy(original: Tree)(bound: Option[TypeTree], selector: TypeTree, cases: List[TypeCaseDef])(given ctx: Context): MatchTypeTree /** Type tree representing a by name parameter */ type ByName <: TypeTree @@ -648,7 +648,7 @@ trait CompilerInterface { def matchByName(tree: Tree)(given ctx: Context): Option[ByName] def ByName_apply(result: TypeTree)(given ctx: Context): ByName - def ByName_copy(original: ByName)(result: TypeTree)(given ctx: Context): ByName + def ByName_copy(original: Tree)(result: TypeTree)(given ctx: Context): ByName /** Type tree representing a lambda abstraction type */ type LambdaTypeTree <: TypeTree @@ -659,7 +659,7 @@ trait CompilerInterface { def Lambdabody(self: LambdaTypeTree)(given ctx: Context): Tree /*TypeTree | TypeBoundsTree*/ def Lambdaapply(tparams: List[TypeDef], body: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): LambdaTypeTree - def Lambdacopy(original: LambdaTypeTree)(tparams: List[TypeDef], body: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): LambdaTypeTree + def Lambdacopy(original: Tree)(tparams: List[TypeDef], body: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): LambdaTypeTree /** Type tree representing a type binding */ type TypeBind <: TypeTree @@ -669,7 +669,7 @@ trait CompilerInterface { def TypeBind_name(self: TypeBind)(given ctx: Context): String def TypeBind_body(self: TypeBind)(given ctx: Context): Tree /*TypeTree | TypeBoundsTree*/ - def TypeBind_copy(original: TypeBind)(name: String, tpt: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): TypeBind + def TypeBind_copy(original: Tree)(name: String, tpt: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): TypeBind /** Type tree within a block with aliases `{ type U1 = ... ; T[U1, U2] }` */ type TypeBlock <: TypeTree @@ -680,7 +680,7 @@ trait CompilerInterface { def TypeBlock_tpt(self: TypeBlock)(given ctx: Context): TypeTree def TypeBlock_apply(aliases: List[TypeDef], tpt: TypeTree)(given ctx: Context): TypeBlock - def TypeBlock_copy(original: TypeBlock)(aliases: List[TypeDef], tpt: TypeTree)(given ctx: Context): TypeBlock + def TypeBlock_copy(original: Tree)(aliases: List[TypeDef], tpt: TypeTree)(given ctx: Context): TypeBlock /** Type tree representing a type bound written in the source */ type TypeBoundsTree <: Tree /*TypeTree | TypeBoundsTree*/ @@ -711,7 +711,7 @@ trait CompilerInterface { def CaseDef_rhs(self: CaseDef)(given ctx: Context): Term 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 + def CaseDef_module_copy(original: Tree)(pattern: Tree, guard: Option[Term], body: Term)(given ctx: Context): CaseDef /** Branch of a type pattern match */ type TypeCaseDef <: Tree @@ -722,7 +722,7 @@ trait CompilerInterface { def TypeCaseDef_rhs(self: TypeCaseDef)(given ctx: Context): TypeTree def TypeCaseDef_module_apply(pattern: TypeTree, body: TypeTree)(given ctx: Context): TypeCaseDef - def TypeCaseDef_module_copy(original: TypeCaseDef)(pattern: TypeTree, body: TypeTree)(given ctx: Context): TypeCaseDef + def TypeCaseDef_module_copy(original: Tree)(pattern: TypeTree, body: TypeTree)(given ctx: Context): TypeCaseDef // // PATTERNS @@ -737,7 +737,7 @@ trait CompilerInterface { def Tree_Bind_pattern(self: Bind)(given ctx: Context): Tree - def Tree_Bind_module_copy(original: Bind)(name: String, pattern: Tree)(given ctx: Context): Bind + def Tree_Bind_module_copy(original: Tree)(name: String, pattern: Tree)(given ctx: Context): Bind /** Tree representing an unapply pattern `Xyz(...)` */ type Unapply <: Tree @@ -750,7 +750,7 @@ trait CompilerInterface { def Tree_Unapply_patterns(self: Unapply)(given ctx: Context): List[Tree] - def Tree_Unapply_module_copy(original: Unapply)(fun: Term, implicits: List[Term], patterns: List[Tree])(given ctx: Context): Unapply + def Tree_Unapply_module_copy(original: Tree)(fun: Term, implicits: List[Term], patterns: List[Tree])(given ctx: Context): Unapply /** Tree representing pattern alternatives `X | Y | ...` */ type Alternatives <: Tree @@ -760,7 +760,7 @@ trait CompilerInterface { def Tree_Alternatives_patterns(self: Alternatives)(given ctx: Context): List[Tree] 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 Tree_Alternatives_module_copy(original: Tree)(patterns: List[Tree])(given ctx: Context): Alternatives // diff --git a/library/src/scala/tasty/reflect/TreeOps.scala b/library/src/scala/tasty/reflect/TreeOps.scala index ced2ac45a032..8a7eeb22936c 100644 --- a/library/src/scala/tasty/reflect/TreeOps.scala +++ b/library/src/scala/tasty/reflect/TreeOps.scala @@ -20,7 +20,7 @@ trait TreeOps extends Core { object PackageClause { def apply(pid: Ref, stats: List[Tree])(given ctx: Context): PackageClause = internal.PackageClause_apply(pid, stats) - def copy(original: PackageClause)(pid: Ref, stats: List[Tree])(given ctx: Context): PackageClause = + def copy(original: Tree)(pid: Ref, stats: List[Tree])(given ctx: Context): PackageClause = internal.PackageClause_copy(original)(pid, stats) def unapply(tree: Tree)(given ctx: Context): Option[(Ref, List[Tree])] = internal.matchPackageClause(tree).map(x => (x.pid, x.stats)) @@ -39,7 +39,7 @@ trait TreeOps extends Core { object Import { def apply(expr: Term, selectors: List[ImportSelector])(given ctx: Context): Import = internal.Import_apply(expr, selectors) - def copy(original: Import)(expr: Term, selectors: List[ImportSelector])(given ctx: Context): Import = + def copy(original: Tree)(expr: Term, selectors: List[ImportSelector])(given ctx: Context): Import = internal.Import_copy(original)(expr, selectors) def unapply(tree: Tree)(given ctx: Context): Option[(Term, List[ImportSelector])] = internal.matchImport(tree).map(x => (x.expr, x.selectors)) @@ -74,7 +74,7 @@ trait TreeOps extends Core { object ClassDef { // TODO def apply(name: String, constr: DefDef, parents: List[TermOrTypeTree], selfOpt: Option[ValDef], body: List[Statement])(given ctx: Context): ClassDef - def copy(original: ClassDef)(name: String, constr: DefDef, parents: List[Tree /* Term | TypeTree */], derived: List[TypeTree], selfOpt: Option[ValDef], body: List[Statement])(given ctx: Context): ClassDef = + def copy(original: Tree)(name: String, constr: DefDef, parents: List[Tree /* Term | TypeTree */], derived: List[TypeTree], selfOpt: Option[ValDef], body: List[Statement])(given ctx: Context): ClassDef = internal.ClassDef_copy(original)(name, constr, parents, derived, selfOpt, body) def unapply(tree: Tree)(given ctx: Context): Option[(String, DefDef, List[Tree /* Term | TypeTree */], List[TypeTree], Option[ValDef], List[Statement])] = internal.matchClassDef(tree).map(x => (x.name, x.constructor, x.parents, x.derived, x.self, x.body)) @@ -119,7 +119,7 @@ trait TreeOps extends Core { object ValDef { def apply(symbol: Symbol, rhs: Option[Term])(given ctx: Context): ValDef = internal.ValDef_apply(symbol, rhs) - def copy(original: ValDef)(name: String, tpt: TypeTree, rhs: Option[Term])(given ctx: Context): ValDef = + def copy(original: Tree)(name: String, tpt: TypeTree, rhs: Option[Term])(given ctx: Context): ValDef = internal.ValDef_copy(original)(name, tpt, rhs) def unapply(tree: Tree)(given ctx: Context): Option[(String, TypeTree, Option[Term])] = internal.matchValDef(tree).map(x => (x.name, x.tpt, x.rhs)) @@ -139,7 +139,7 @@ trait TreeOps extends Core { object TypeDef { def apply(symbol: Symbol)(given ctx: Context): TypeDef = internal.TypeDef_apply(symbol) - def copy(original: TypeDef)(name: String, rhs: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): TypeDef = + def copy(original: Tree)(name: String, rhs: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): TypeDef = internal.TypeDef_copy(original)(name, rhs) def unapply(tree: Tree)(given ctx: Context): Option[(String, Tree /*TypeTree | TypeBoundsTree*/ /* TypeTree | TypeBoundsTree */)] = internal.matchTypeDef(tree).map(x => (x.name, x.rhs)) @@ -379,7 +379,7 @@ trait TreeOps extends Core { def apply(name: String, arg: Term)(given ctx: Context): NamedArg = internal.NamedArg_apply(name, arg) - def copy(original: NamedArg)(name: String, arg: Term)(given ctx: Context): NamedArg = + def copy(original: Tree)(name: String, arg: Term)(given ctx: Context): NamedArg = internal.NamedArg_copy(original)(name, arg) /** Matches a named argument ` = ` */ @@ -854,7 +854,7 @@ trait TreeOps extends Core { object TypeIdent { // TODO def apply(name: String)(given ctx: Context): TypeIdent - def copy(original: TypeIdent)(name: String)(given ctx: Context): TypeIdent = + def copy(original: Tree)(name: String)(given ctx: Context): TypeIdent = internal.TypeIdent_copy(original)(name) def unapply(tree: Tree)(given ctx: Context): Option[String] = internal.matchTypeIdent(tree).map(_.name) @@ -869,7 +869,7 @@ trait TreeOps extends Core { object TypeSelect { def apply(qualifier: Term, name: String)(given ctx: Context): TypeSelect = internal.TypeSelect_apply(qualifier, name) - def copy(original: TypeSelect)(qualifier: Term, name: String)(given ctx: Context): TypeSelect = + def copy(original: Tree)(qualifier: Term, name: String)(given ctx: Context): TypeSelect = internal.TypeSelect_copy(original)(qualifier, name) def unapply(tree: Tree)(given ctx: Context): Option[(Term, String)] = internal.matchTypeSelect(tree).map(x => (x.qualifier, x.name)) @@ -888,7 +888,7 @@ trait TreeOps extends Core { object Projection { // TODO def apply(qualifier: TypeTree, name: String)(given ctx: Context): Project - def copy(original: Projection)(qualifier: TypeTree, name: String)(given ctx: Context): Projection = + def copy(original: Tree)(qualifier: TypeTree, name: String)(given ctx: Context): Projection = internal.Projection_copy(original)(qualifier, name) def unapply(tree: Tree)(given ctx: Context): Option[(TypeTree, String)] = internal.matchProjection(tree).map(x => (x.qualifier, x.name)) @@ -908,7 +908,7 @@ trait TreeOps extends Core { object Singleton { def apply(ref: Term)(given ctx: Context): Singleton = internal.Singleton_apply(ref) - def copy(original: Singleton)(ref: Term)(given ctx: Context): Singleton = + def copy(original: Tree)(ref: Term)(given ctx: Context): Singleton = internal.Singleton_copy(original)(ref) def unapply(tree: Tree)(given ctx: Context): Option[Term] = internal.matchSingleton(tree).map(_.ref) @@ -926,7 +926,7 @@ trait TreeOps extends Core { object Refined { // TODO def apply(tpt: TypeTree, refinements: List[Definition])(given ctx: Context): Refined - def copy(original: Refined)(tpt: TypeTree, refinements: List[Definition])(given ctx: Context): Refined = + def copy(original: Tree)(tpt: TypeTree, refinements: List[Definition])(given ctx: Context): Refined = internal.Refined_copy(original)(tpt, refinements) def unapply(tree: Tree)(given ctx: Context): Option[(TypeTree, List[Definition])] = internal.matchRefined(tree).map(x => (x.tpt, x.refinements)) @@ -946,7 +946,7 @@ trait TreeOps extends Core { object Applied { def apply(tpt: TypeTree, args: List[Tree /*TypeTree | TypeBoundsTree*/])(given ctx: Context): Applied = internal.Applied_apply(tpt, args) - def copy(original: Applied)(tpt: TypeTree, args: List[Tree /*TypeTree | TypeBoundsTree*/])(given ctx: Context): Applied = + def copy(original: Tree)(tpt: TypeTree, args: List[Tree /*TypeTree | TypeBoundsTree*/])(given ctx: Context): Applied = internal.Applied_copy(original)(tpt, args) def unapply(tree: Tree)(given ctx: Context): Option[(TypeTree, List[Tree /*TypeTree | TypeBoundsTree*/])] = internal.matchApplied(tree).map(x => (x.tpt, x.args)) @@ -966,7 +966,7 @@ trait TreeOps extends Core { object Annotated { def apply(arg: TypeTree, annotation: Term)(given ctx: Context): Annotated = internal.Annotated_apply(arg, annotation) - def copy(original: Annotated)(arg: TypeTree, annotation: Term)(given ctx: Context): Annotated = + def copy(original: Tree)(arg: TypeTree, annotation: Term)(given ctx: Context): Annotated = internal.Annotated_copy(original)(arg, annotation) def unapply(tree: Tree)(given ctx: Context): Option[(TypeTree, Term)] = internal.matchAnnotated(tree).map(x => (x.arg, x.annotation)) @@ -986,7 +986,7 @@ trait TreeOps extends Core { object MatchTypeTree { def apply(bound: Option[TypeTree], selector: TypeTree, cases: List[TypeCaseDef])(given ctx: Context): MatchTypeTree = internal.MatchTypeTree_apply(bound, selector, cases) - def copy(original: MatchTypeTree)(bound: Option[TypeTree], selector: TypeTree, cases: List[TypeCaseDef])(given ctx: Context): MatchTypeTree = + def copy(original: Tree)(bound: Option[TypeTree], selector: TypeTree, cases: List[TypeCaseDef])(given ctx: Context): MatchTypeTree = internal.MatchTypeTree_copy(original)(bound, selector, cases) def unapply(tree: Tree)(given ctx: Context): Option[(Option[TypeTree], TypeTree, List[TypeCaseDef])] = internal.matchMatchTypeTree(tree).map(x => (x.bound, x.selector, x.cases)) @@ -1007,7 +1007,7 @@ trait TreeOps extends Core { object ByName { def apply(result: TypeTree)(given ctx: Context): ByName = internal.ByName_apply(result) - def copy(original: ByName)(result: TypeTree)(given ctx: Context): ByName = + def copy(original: Tree)(result: TypeTree)(given ctx: Context): ByName = internal.ByName_copy(original)(result) def unapply(tree: Tree)(given ctx: Context): Option[TypeTree] = internal.matchByName(tree).map(_.result) @@ -1026,7 +1026,7 @@ trait TreeOps extends Core { object LambdaTypeTree { def apply(tparams: List[TypeDef], body: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): LambdaTypeTree = internal.Lambdaapply(tparams, body) - def copy(original: LambdaTypeTree)(tparams: List[TypeDef], body: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): LambdaTypeTree = + def copy(original: Tree)(tparams: List[TypeDef], body: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): LambdaTypeTree = internal.Lambdacopy(original)(tparams, body) def unapply(tree: Tree)(given ctx: Context): Option[(List[TypeDef], Tree /*TypeTree | TypeBoundsTree*/)] = internal.matchLambdaTypeTree(tree).map(x => (x.tparams, x.body)) @@ -1045,7 +1045,7 @@ trait TreeOps extends Core { object TypeBind { // TODO def apply(name: String, tree: Tree)(given ctx: Context): TypeBind - def copy(original: TypeBind)(name: String, tpt: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): TypeBind = + def copy(original: Tree)(name: String, tpt: Tree /*TypeTree | TypeBoundsTree*/)(given ctx: Context): TypeBind = internal.TypeBind_copy(original)(name, tpt) def unapply(tree: Tree)(given ctx: Context): Option[(String, Tree /*TypeTree | TypeBoundsTree*/)] = internal.matchTypeBind(tree).map(x => (x.name, x.body)) @@ -1065,7 +1065,7 @@ trait TreeOps extends Core { object TypeBlock { def apply(aliases: List[TypeDef], tpt: TypeTree)(given ctx: Context): TypeBlock = internal.TypeBlock_apply(aliases, tpt) - def copy(original: TypeBlock)(aliases: List[TypeDef], tpt: TypeTree)(given ctx: Context): TypeBlock = + def copy(original: Tree)(aliases: List[TypeDef], tpt: TypeTree)(given ctx: Context): TypeBlock = internal.TypeBlock_copy(original)(aliases, tpt) def unapply(tree: Tree)(given ctx: Context): Option[(List[TypeDef], TypeTree)] = internal.matchTypeBlock(tree).map(x => (x.aliases, x.tpt)) @@ -1127,7 +1127,7 @@ trait TreeOps extends Core { 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: Tree, guard: Option[Term], rhs: Term)(given ctx: Context): CaseDef = + def copy(original: Tree)(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[(Tree, Option[Term], Term)] = @@ -1148,7 +1148,7 @@ trait TreeOps extends Core { def apply(pattern: TypeTree, rhs: TypeTree)(given ctx: Context): TypeCaseDef = internal.TypeCaseDef_module_apply(pattern, rhs) - def copy(original: TypeCaseDef)(pattern: TypeTree, rhs: TypeTree)(given ctx: Context): TypeCaseDef = + def copy(original: Tree)(pattern: TypeTree, rhs: TypeTree)(given ctx: Context): TypeCaseDef = internal.TypeCaseDef_module_copy(original)(pattern, rhs) def unapply(tree: Tree)(given ctx: Context): Option[(TypeTree, TypeTree)] = @@ -1164,7 +1164,7 @@ trait TreeOps extends Core { 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 = + def copy(original: Tree)(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)) @@ -1182,7 +1182,7 @@ trait TreeOps extends Core { 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 = + def copy(original: Tree)(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)) @@ -1202,7 +1202,7 @@ trait TreeOps extends Core { 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 = + def copy(original: Tree)(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)