Scala 宏获取封闭行 [英] Scala macro get enclosing line

查看:49
本文介绍了Scala 宏获取封闭行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下宏

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 的行,以检查是否使用了该方法的结果(在赋值中,方法调用或其他).如果结果没有被使用,我会回复一条错误消息.

Instead of the ??? I would like to inspect the line where the method doIt was called to check if the result of the method was used (in an assignment, method call or whatever). If the result is not used I respond with an error-message.

调用示例:

val s: String = doIt("Hallo") // alright
doIt("Hallo") // ERROR!

有没有简单的方法可以得到整行的Tree?

Is there a simple way to get the Tree of the whole line?

推荐答案

为了完整起见,这里是解决方案的轻微改编版本 我上面提到过:

For completeness, here's a lightly adapted version of the solution I mention above:

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 中:

Now in a 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") }
                          ^

正如预期的那样.请参阅上面链接的问题的评论以了解一些注意事项,但除非您的实际用例更加复杂,否则这种方法应该可以正常工作.

As expected. See the comments on the question linked above for some caveats, but unless your real use case is much more complicated, this approach should work fine.

这篇关于Scala 宏获取封闭行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆