scala - How to get range position from macro annotation? -
i'm using macro annotation instrument code. how can range position of expressions ?
@scalakata object sha { val foo = "foo" val bar = "bar" foo; bar // ... } // result: map((75, 78) -> "foo", (80, 83) -> "bar")
the instrumenting macro:
package com.scalakata.eval import scala.reflect.macros.blackbox.context import scala.language.experimental.macros import scala.annotation.staticannotation object scalakatamacro { def impl(c: context)(annottees: c.expr[any]*): c.expr[any] = { import c.universe._ val result: tree = { val eval = newtermname("eval$") annottees.map(_.tree).tolist match { case q"object $name { ..$body }" :: nil => { val instr = newtermname("instr$") implicit def lift = liftable[c.universe.position] { p => q"(${p.start}, ${p.end})" } def instrument(rhs: tree): tree = { q""" { val t = $rhs ${instr}(${rhs.pos}) = t t } """ } val bodyi = body.map { case ident: ident => instrument(ident) case otherwise => otherwise } q""" object $name { val $instr = scala.collection.mutable.map.empty[(int, int), any] def $eval() = { ..$bodyi $instr } } """ } } } c.expr[any](result) } } class scalakata extends staticannotation { def macrotransform(annottees: any*) = macro scalakatamacro.impl }
i have range option enabled scalacoptions += "-yrangepos"
i'm getting starting position: result: map((75, 75) -> "foo", (80, 80) -> "bar")
there bug in paradise corrupts range positions of macro arguments. it's fixed in freshly published 2.1.0-snapshot.
however, there's regression in scala 2.11.0 , 2.11.1 corrupts range positions. therefore able access range positions in macro annotations in 2.10.x or in upcoming 2.11.2 (scheduled end of july).
Comments
Post a Comment