吸血鬼方法,类型提供者宏和缺少runtime.VolatileObjectRef

时间:2017-10-13 11:21:48

标签: scala scala-macros scala-macro-paradise

我正在尝试编写一个类型提供程序宏,它使用描述为in this gist的吸血鬼方法技巧;这是我实现的最小模型:

object DeriveFamily {
  def minimal: Any = macro DeriveFamilyMacros.minimal
}

object DeriveFamilyMacros {
  class body(tree: Any) extends StaticAnnotation

  def bodyImpl(c: Context) = {
    import c.universe._

    val field = c.macroApplication.symbol
    val bodyAnn = field.annotations.filter(_.tree.tpe <:< typeOf[body]).head
    bodyAnn.tree.children.tail.head
  }

  def minimal(c: Context): c.Tree = {
    import c.universe._
    q"""object Foobar { val _x = "X"; @DeriveFamilyMacros.body(Foobar._x) def x: String = macro DeriveFamilyMacros.bodyImpl }; Foobar"""
  }
}

这是一个愚蠢的例子,真正的实现尝试使用这个技巧来创建可以在没有反射调用的情况下访问的派生类型类实例的捆绑。真正的版本和这个版本都存在的问题是,如果我在函数中使用它们它们会正常工作但是如果我尝试在classobject的根处使用它们会使编译器崩溃定义:

object Working {
  def x = {
    val foobar = DeriveFamily.minimal
    println(foobar.x)
  }

  x // Prints "X"
}

object NotWorking {
  val foobar = DeriveFamily.minimal
  println(foobar.x)
  /*
  [trace] Stack trace suppressed: run last common/test:compileIncremental for the full output.
  [error] (common/test:compileIncremental) java.lang.IllegalArgumentException: Could not find proxy for var Foobar$module: runtime.VolatileObjectRef in List(variable Foobar$module, value foobar, Object NotWorking, package <root>) (currentOwner= value <local NotWorking> )
  */
}

非常欢迎任何帮助解决这个问题,谢谢。

0 个答案:

没有答案