我正在使用宏注释来检测代码。如何获得某些表达式的范围位置?
@ScalaKata object SHA {
val foo = "foo"
val bar = "bar"
foo; bar
// ...
}
// result: Map((75, 78) -> "foo", (80, 83) -> "bar")
仪表宏:
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
}
我启用了范围选项scalacOptions += "-Yrangepos"
我目前只获得起始位置:result: Map((75, 75) -> "foo", (80, 80) -> "bar")
答案 0 :(得分:1)
天堂里有一个破坏宏观争论的范围位置的错误。它现在已在新发布的2.1.0-SNAPSHOT中修复。
然而,Scala 2.11.0和2.11.1中的回归也会破坏范围位置。因此,您只能在2.10.x中的宏注释或即将到来的2.11.2(计划在7月底)中访问范围位置。