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