获取定义宏的类的字段成员

时间:2014-06-02 14:01:26

标签: scala macros scala-2.10 scala-macros

我正在尝试在特征中定义一个宏。例如,

trait Macro {
  val magic: Int = 1001
  def doMagic(x: Int): Int = macro Impl.doMagic
}

object Impl {
  def doMagic(c: Context)(x: c.Expr[Int]): c.Expr[Int] = ???
}

我在这里要做的是,doMagic实现应该能够引用特征magic中的字段Macro,安全地输入。

我试图通过This(c.enclosingClass.asModule.moduleClass)来引用它,但它似乎引用了宏应用程序的树,这导致了一个名为$ iw的匿名类。所以在我的理解中,Enclosures是应用宏的地方,而不是它被定义的地方。

无论如何我能做到吗?

2 个答案:

答案 0 :(得分:1)

这不直接回答问题,但也许它有所帮助。您可以将实例作为参数传递给宏,并将其隐藏在调用者中,您可以添加委托给doMagic的相应方法,如下所示:

trait Macro {
  val magic: Int = 1001
  def doMagic(m: Macro, x: Int): Int = macro Impl.doMagic
}

object Impl {
  def doMagic(context: Context)(m: context.Expr[Macro], x: context.Expr[Int]): context.Expr[Int] = {
    import context.universe._
    reify(m.splice.magic + x.splice)
  }
}

wrapper-trait:

trait Macro2 extends Macro {
  def doMagic2(x: Int): Int = doMagic(this, x)
}

和来电者:

val z = new Macro2 {}
println(z.doMagic2(5))

答案 1 :(得分:0)

我整理出来了。我们应该使用c.prefix,比如

val self = TermName(c.freshName("self"))

c.Expr[T] {
  q"""
    val $self = ${c.prefix.tree}
    ...
  """
}

并且可以使用自变量来捕获前缀,因此它只被评估一次。