diff --git a/tests/run-macros/quote-matching-optimize-4.check b/tests/run-macros/quote-matching-optimize-4.check new file mode 100644 index 000000000000..f542f07ca660 --- /dev/null +++ b/tests/run-macros/quote-matching-optimize-4.check @@ -0,0 +1,20 @@ +Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((`x₂`: scala.Int) => `x₂`.>(1))) +Optimized: ls.filter(((x: scala.Int) => ((`x₂`: scala.Int) => `x₂`.<(3)).apply(x).&&(((`x₃`: scala.Int) => `x₃`.>(1)).apply(x)))) +Result: List(2) + +Original: ls2.filter(((x: scala.Char) => x.<('c'))).filter(((`x₂`: scala.Char) => `x₂`.>('a'))) +Optimized: ls2.filter(((x: scala.Char) => ((`x₂`: scala.Char) => `x₂`.<('c')).apply(x).&&(((`x₃`: scala.Char) => `x₃`.>('a')).apply(x)))) +Result: List(b) + +Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((`x₂`: scala.Int) => `x₂`.>(1))).filter(((`x₃`: scala.Int) => `x₃`.==(2))) +Optimized: ls.filter(((x: scala.Int) => ((`x₂`: scala.Int) => `x₂`.<(3)).apply(x).&&(((`x₃`: scala.Int) => ((`x₄`: scala.Int) => `x₄`.>(1)).apply(`x₃`).&&(((`x₅`: scala.Int) => `x₅`.==(2)).apply(`x₃`))).apply(x)))) +Result: List(2) + +Original: ls.map[scala.Long](((a: scala.Int) => a.toLong)).map[java.lang.String](((b: scala.Long) => b.toString())) +Optimized: ls.map[java.lang.String](((x: scala.Int) => ((b: scala.Long) => b.toString()).apply(((a: scala.Int) => a.toLong).apply(x)))) +Result: List(1, 2, 3) + +Original: ls.map[scala.Char](((a: scala.Int) => a.toChar)).map[java.lang.String](((b: scala.Char) => b.toString())) +Optimized: ls.map[java.lang.String](((x: scala.Int) => ((b: scala.Char) => b.toString()).apply(((a: scala.Int) => a.toChar).apply(x)))) +Result: List(, , ) + diff --git a/tests/run-macros/quote-matching-optimize-4/Macro_1.scala b/tests/run-macros/quote-matching-optimize-4/Macro_1.scala new file mode 100644 index 000000000000..86ea8cd6160f --- /dev/null +++ b/tests/run-macros/quote-matching-optimize-4/Macro_1.scala @@ -0,0 +1,31 @@ +import scala.quoted._ + +object Macro { + + inline def optimize[T](inline x: List[T]): List[T] = ${ Macro.impl[T]('x) } + + def impl[T: Type](x: Expr[List[T]])(using Quotes): Expr[List[T]] = { + val res = optimize(x) + '{ + val result = $res + val originalCode = ${Expr(x.show)} + val optimizeCode = ${Expr(res.show)} + println("Original: " + originalCode) + println("Optimized: " + optimizeCode) + println("Result: " + result) + println() + result + } + } + + def optimize[T: Type](x: Expr[List[T]])(using Quotes): Expr[List[T]] = x match { + case '{ ($ls: List[T]).filter($f).filter($g) } => + optimize('{ $ls.filter(x => $f(x) && $g(x)) }) + + case '{ type u; type v; ($ls: List[`u`]).map($f: `u` => `v`).map($g: `v` => T) } => + optimize('{ $ls.map(x => $g($f(x))) }) + + case _ => x + } +} + diff --git a/tests/run-macros/quote-matching-optimize-4/Test_2.scala b/tests/run-macros/quote-matching-optimize-4/Test_2.scala new file mode 100644 index 000000000000..abce7c9ca7d3 --- /dev/null +++ b/tests/run-macros/quote-matching-optimize-4/Test_2.scala @@ -0,0 +1,14 @@ +object Test { + import Macro._ + + def main(args: Array[String]): Unit = { + val ls = List(1, 2, 3) + val ls2 = List('a', 'b', 'c') + optimize(ls.filter(x => x < 3).filter(x => x > 1)) + optimize(ls2.filter(x => x < 'c').filter(x => x > 'a')) + optimize(ls.filter(x => x < 3).filter(x => x > 1).filter(x => x == 2)) + optimize(ls.map(a => a.toLong).map(b => b.toString)) + optimize(ls.map(a => a.toChar).map(b => b.toString)) + } + +} diff --git a/tests/run-macros/quote-matching-optimize-5.check b/tests/run-macros/quote-matching-optimize-5.check new file mode 100644 index 000000000000..f542f07ca660 --- /dev/null +++ b/tests/run-macros/quote-matching-optimize-5.check @@ -0,0 +1,20 @@ +Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((`x₂`: scala.Int) => `x₂`.>(1))) +Optimized: ls.filter(((x: scala.Int) => ((`x₂`: scala.Int) => `x₂`.<(3)).apply(x).&&(((`x₃`: scala.Int) => `x₃`.>(1)).apply(x)))) +Result: List(2) + +Original: ls2.filter(((x: scala.Char) => x.<('c'))).filter(((`x₂`: scala.Char) => `x₂`.>('a'))) +Optimized: ls2.filter(((x: scala.Char) => ((`x₂`: scala.Char) => `x₂`.<('c')).apply(x).&&(((`x₃`: scala.Char) => `x₃`.>('a')).apply(x)))) +Result: List(b) + +Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((`x₂`: scala.Int) => `x₂`.>(1))).filter(((`x₃`: scala.Int) => `x₃`.==(2))) +Optimized: ls.filter(((x: scala.Int) => ((`x₂`: scala.Int) => `x₂`.<(3)).apply(x).&&(((`x₃`: scala.Int) => ((`x₄`: scala.Int) => `x₄`.>(1)).apply(`x₃`).&&(((`x₅`: scala.Int) => `x₅`.==(2)).apply(`x₃`))).apply(x)))) +Result: List(2) + +Original: ls.map[scala.Long](((a: scala.Int) => a.toLong)).map[java.lang.String](((b: scala.Long) => b.toString())) +Optimized: ls.map[java.lang.String](((x: scala.Int) => ((b: scala.Long) => b.toString()).apply(((a: scala.Int) => a.toLong).apply(x)))) +Result: List(1, 2, 3) + +Original: ls.map[scala.Char](((a: scala.Int) => a.toChar)).map[java.lang.String](((b: scala.Char) => b.toString())) +Optimized: ls.map[java.lang.String](((x: scala.Int) => ((b: scala.Char) => b.toString()).apply(((a: scala.Int) => a.toChar).apply(x)))) +Result: List(, , ) + diff --git a/tests/run-macros/quote-matching-optimize-5/Macro_1.scala b/tests/run-macros/quote-matching-optimize-5/Macro_1.scala new file mode 100644 index 000000000000..463c30f74eb3 --- /dev/null +++ b/tests/run-macros/quote-matching-optimize-5/Macro_1.scala @@ -0,0 +1,31 @@ +import scala.quoted._ + +object Macro { + + inline def optimize[T](inline x: List[T]): List[T] = ${ Macro.impl[T]('x) } + + def impl[T: Type](x: Expr[List[T]])(using Quotes): Expr[List[T]] = { + val res = optimize(x) + '{ + val result = $res + val originalCode = ${Expr(x.show)} + val optimizeCode = ${Expr(res.show)} + println("Original: " + originalCode) + println("Optimized: " + optimizeCode) + println("Result: " + result) + println() + result + } + } + + def optimize[T: Type](x: Expr[List[T]])(using Quotes): Expr[List[T]] = x match { + case '{ ($ls: List[T]).filter($f).filter($g) } => + optimize('{ $ls.filter(x => $f(x) && $g(x)) }) + + case '{ ($ls: List[u]).map[v]($f).map[T]($g) } => + optimize('{ $ls.map(x => $g($f(x))) }) + + case _ => x + } +} + diff --git a/tests/run-macros/quote-matching-optimize-5/Test_2.scala b/tests/run-macros/quote-matching-optimize-5/Test_2.scala new file mode 100644 index 000000000000..abce7c9ca7d3 --- /dev/null +++ b/tests/run-macros/quote-matching-optimize-5/Test_2.scala @@ -0,0 +1,14 @@ +object Test { + import Macro._ + + def main(args: Array[String]): Unit = { + val ls = List(1, 2, 3) + val ls2 = List('a', 'b', 'c') + optimize(ls.filter(x => x < 3).filter(x => x > 1)) + optimize(ls2.filter(x => x < 'c').filter(x => x > 'a')) + optimize(ls.filter(x => x < 3).filter(x => x > 1).filter(x => x == 2)) + optimize(ls.map(a => a.toLong).map(b => b.toString)) + optimize(ls.map(a => a.toChar).map(b => b.toString)) + } + +}