使用quasiquotes从头生成伴侣类的正确方法是什么?

时间:2014-03-21 03:37:09

标签: scala scala-macros scala-quasiquotes

我正在使用macroparadise 2.0.0-M3在Scala 2.10.3中尝试宏注释。我试图了解如何使用quasiquotes生成带注释的类的伴随对象。到目前为止我发现的是如何在已经声明的情况下生成伴随对象。令人费解的是,即使使用始终发出相同结构的代码也是如此。例如:

import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.Context

class testThing extends StaticAnnotation {
  def macroTransform(annottees: Any*) = macro testThing.impl
}

object testThing {
  def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
    import c.universe._
    val toEmit = c.Expr(q"""
class Thingy(i: Int) {
  def stuff = println(i)
}

object Thingy {
  def apply(x: Int) = new Thingy(x)
}
""")
    annottees.map(_.tree) match {
      case Nil => {
        c.abort(c.enclosingPosition, "No test target")
      }
      case (classDeclaration: ClassDef) :: Nil => {
        println("No companion provided")
        toEmit
      }
      case (classDeclaration: ClassDef) :: (companionDeclaration: ModuleDef) :: Nil => {
        println("Companion provided")
        toEmit
      }
      case _ => c.abort(c.enclosingPosition, "Invalid test target")
    }
  }
}

这是一个示例REPL会话,显示预先声明伴侣对象与不这样做之间的行为差​​异:

scala> @testThing class Thingy { }
No companion provided
defined class Thingy

scala> :paste
// Entering paste mode (ctrl-D to finish)

@testThing class Thingy { }
object Thingy { }

// Exiting paste mode, now interpreting.

Companion provided
defined class Thingy
defined module Thingy

scala> 

我是否错误地认为应该在两种情况下都创建一个伴侣物体?在http://docs.scala-lang.org/overviews/macros/annotations.html处声明宏注释旨在允许创建伴随对象。与此相关的是Create or extend a companion object, using a macro annotation on the class,它展示了不使用quasiquotes创建伴随对象。

1 个答案:

答案 0 :(得分:1)

看起来像REPL特定的错误:https://github.com/scalamacros/paradise/issues/18