scalaabstract-syntax-treeanonymous-functionscala-macrosinspection

Scala macro inspect tree for anonymous function


I'm just getting started with macros and feel like I'm missing something really painfully obvious...

I want to inspect the AST for an anonymous lambda function passed to my macro, ultimately I want to do things to it, but I've fallen at the first hurdle.

My code looks like this;

object Test extends App {
  doIt(() => "bar")

  def doIt(f: () => String) = {
    Builder.build(f)
  }
}

object Builder {
  def build[R](func: () => R): String = macro builder_impl[R]

  def builder_impl[R](c: blackbox.Context)(func: c.Expr[() => R]): c.Expr[String] = {
    import c.universe._

    println(showRaw(func))

    reify {
      println("hello yeah")
      "foo"
    }
  }
}

I'm expecting showRaw to print something like;

Expr(Function(List(), Literal(Constant("bar"))))

However, instead I get;

Expr(Ident(TermName("f")))

I can get what I want by defining my anonymous function at the call site to Builder.build like this;

Builder.build(() => "bar")

However, this doesn't help me do what I need.

Can some please explain what I'm misunderstanding, how can I achieve my goal?

Also, is there some awesome Scala macro cookbook that I should read?

Regards,

Ryan.


Solution

  • You only get AST of what you passed to a macro (in this case the only macro involved is build, and you call it with argument f, so you get the AST of f). So if you want to get the AST of () => "bar" in doIt(() => "bar"), doIt itself must be a macro.