Scala宏获取封闭线

Scala宏获取封闭线,scala,scala-macros,Scala,Scala Macros,我有以下宏 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的行,而不是?,以检查是否使用了该方法的结果(在赋值、方法调用或任何情况下

我有以下宏

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!

有没有一种简单的方法可以得到整条线的树?

为了完整起见,这里是我上面提到的一个稍加修改的版本:

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.")
    )
  }
}
现在回复:

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") }
                          ^
scala>objecttest2{doIt(“foo”)}
:13:错误:不是有效的应用程序。
对象Test2{doIt(“foo”)}
^

正如所料。有关一些注意事项,请参见上面链接的问题的注释,但除非您的实际用例更加复杂,否则这种方法应该可以正常工作。

请参见此处的注释,还有一些想法。@TravisBrown我将在这个圣诞夜熬夜,试图抓住Travis给所有好女孩和男孩带来宏观答案。这解决了部分问题。我的目标是类似于键入
1+2
时得到的警告(纯表达式在语句位置不起任何作用;您可能省略了必要的括号)。这很难用
ValDef
之类的提取器实现。我想没有别的办法了吧?