我有以下宏
object Example {
def doIt(s: String): String = macro doItImpl
def doItImpl(c: Context)(s: c.Expr[String]): c.Expr[String] = {
import c.{ universe => u }
import u._
???
}
}
而不是???
我想检查调用方法doIt
的行,以检查方法的结果是否被使用(在赋值,方法调用或其他方面)。如果未使用结果,我会回复错误消息。
呼叫-示例:
val s: String = doIt("Hallo") // alright
doIt("Hallo") // ERROR!
有没有一种简单的方法可以获得整条线的树?
答案 0 :(得分:4)
为了完整起见,这是我在上面提到的the solution的轻微改编版本:
import scala.language.experimental.macros
import scala.reflect.macros.Context
object Example {
def doIt(s: String): String = macro doItImpl
def doItImpl(c: Context)(s: c.Expr[String]): c.Expr[String] = {
import c.universe._
c.enclosingClass.collect {
case ValDef(_, name, _, rhs) if rhs.pos == c.macroApplication.pos =>
c.literal(s"Okay, defining a variable named ${name.decoded}.")
}.headOption.getOrElse(
c.abort(c.enclosingPosition, "Not a valid application.")
)
}
}
现在在REPL中:
scala> import Example._
import Example._
scala> object Test1 { val x = doIt("foo") }
defined module Test1
scala> Test1.x
res0: String = Okay, defining a variable named x.
如果我们没有定义:
scala> object Test2 { doIt("foo") }
<console>:13: error: Not a valid application.
object Test2 { doIt("foo") }
^
正如所料。有关一些警告,请参阅上面链接的问题的评论,但除非您的实际用例更复杂,否则此方法应该可以正常工作。