Scala macro / toolbox for basic scala source code parsing

0
down vote
favorite
I am trying to perform some basic parsing to get the parameter passed to a function (as is) using compile time macros / Toolbox So far, I can get the entire AST for a piece of code using Toolbox.parse(). Instead I just want the parameter / function passed as is.

For the piece of code -
obj.someDef( x => x+1 )

I just want x=> x+1 as the output. Not the AST of x => x+1. My understanding is that it is not possible to generate the sourcecode back from the AST. So how do I just get the original source code for a node in the AST (in this case the function passed to someDef) ?

This would be trivial in something like Antlr and a visitor pattern using -
ctx.getText()
But the scala grammer for Antlr is completely broken with no planned fix in sight.

Usually you use range positions (-Yrangepos) to find the original source.

By default you get offset positions:

scala> import reflect.runtime._,universe._,tools.reflect.ToolBox
import reflect.runtime._
import universe._
import tools.reflect.ToolBox

scala> val tb = currentMirror.mkToolBox()
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@2c719bd4

scala> val t = tb.parse("v.f(x => x + 1)")
t: tb.u.Tree = v.f(((x) => x.$plus(1)))

scala> t.pos
res0: tb.u.Position = source-<toolbox>,line-1,offset=3

But it looks like you can:

scala> val tbf = ToolBox(currentMirror)
tbf: scala.tools.reflect.ToolBoxFactory[reflect.runtime.universe.type] = scala.tools.reflect.package$$anon$2@103bcc9f

scala> val tb = tbf.mkToolBox(options = "-Yrangepos")
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@7e615c6a

scala> val t = tb.parse("v.f(x => x + 1)")
t: tb.u.Tree = v.f(((x) => x.$plus(1)))

scala> show(t.pos)
res5: String = [0:15]

scala> val q"$_.$_($arg)" = t
arg: reflect.runtime.universe.Tree = ((x) => x.$plus(1))

scala> show(arg.pos)
res7: String = [4:14]

scala> arg.pos.source.content.slice(arg.pos.start, arg.pos.end)
res13: Array[Char] = Array(x,  , =, >,  , x,  , +,  , 1)

scala> .mkString
res14: String = x => x + 1