0__
0__

Reputation: 67330

Scala macros: how to pass additional arguments

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

Answers (1)

0__
0__

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

Related Questions