Creating a method definition tree from a method symbol and a body
macros, reflection, scala, scala-2.10, scala-macros
Solution
To the best of my knowledge, there's no standard way to go from a symbol to a defining tree.
Your best bet would probably be to iterate through `c.enclosingRun.units`, recursing into each of the `unit.body` trees as you go. If you see a `DefDef`, which has a `symbol` equal to your symbol, then you've reached your destination. upd. Don't forget to `duplicate` the defining tree before reusing it!
This technique is far from being the most convenient thing in the world, but it should work.
Problem
Is there a convenient way to turn a `MethodSymbol` into the left-hand side of a method definition tree (i.e., a `DefDef`) in Scala 2.10? For example, suppose I want to create a macro that will take an instance of a trait and wrap all of that trait's methods with some debugging functionality. I can write the following: ``` import scala.language.experimental.macros import scala.reflect.macros.Context object WrapperExample { def wrap[A](a: A): A = macro wrap_impl[A] def wrap_impl[A: c.WeakTypeTag](c: Context)(a: c.Expr[A]) = { import c.universe._ val wrapped = weakTypeOf[A] val f = Select(reify(Predef).tree, "println") val methods = wrapped.declarations.collect { case m: MethodSymbol if !m.isConstructor => DefDef( Modifiers(Flag.OVERRIDE), m.name, Nil, Nil, TypeTree(), Block( Apply(f, c.literal("Calling: " + m.name.decoded).tree :: Nil), Select(a.tree, m.name) ) ) }.toList //... } ``` I've elided the boring business of sticking these methods in a new anonymous class that implements the trait and then instantiating that class—you can find a complete working example here if you're interested. Now I can write this, for example: ``` scala> trait X { def foo = 1; def bar = 'a } defined trait X scala> val x = new X {} x: X = $anon$1@15dd533 scala> val w: X = WrapperExample.wrap[X](x) w: X = $1$$1@27c3a4a3 scala> w.foo Calling: foo res0: Int = 1 scala> w.bar Calling: bar res1: Symbol = 'a ``` So it works, but only in very simple cases—it won't if the trait has methods with parameter lists, with access modifiers, annotations, etc. What I really want is a function that will take a method symbol and a tree for the new body and return a `DefDef`. I've started writing one by hand, but it involves a lot of fiddly stuff like this: ``` List(if (method.isImplicit) Some(Flag.IMPLICIT) else None, ...) ``` Which is annoying, verbose, and error-prone. Am I missing some nicer way to do this in the new Reflection API?