Reputation: 67330
So I have a method in an extension method that should expand as macro. The problem I have is how to include the receiver of the extension method in the macro implementation call?
implicit class ExtensionTest(xs: List[Int]) {
def foo(fun: Int => Int)(implicit ord: Ordering[Int]): List[Int] =
macro ExtensionTest.fooImpl // how to pass `xs`?
}
object ExtensionTest {
def fooImpl(c: blackbox.Context)
(fun: c.Expr[Int => Int])
(ord: c.Expr[Ordering[B]]): c.Expr[List[Int]] = ???
}
Upvotes: 3
Views: 898
Reputation: 67330
The solution here is to "find" xs
through c.prefix
which points to the instance of ExtensionTest
:
implicit class ExtensionTest(val xs: List[Int]) {
def foo(fun: Int => Int)(implicit ord: Ordering[Int]): List[Int] =
macro ExtensionTest.fooImpl
}
object ExtensionTest {
def fooImpl(c: blackbox.Context)(fun: c.Expr[Int => Int])
(ord: c.Expr[Ordering[Int]]): c.Expr[List[Int]] = {
import c.universe._
reify {
c.prefix.splice.asInstanceOf[ExtensionTest].xs.map(fun.splice).sorted(ord.splice)
}
}
}
Test:
assert(List(6, 1, 7, 4).foo(_ + 2) == List(3, 6, 8, 9))
Upvotes: 3