我正在使用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中声明宏注释旨在允许创建伴随对象。与此相关的是使用类上的宏注释创建或扩展伴随对象,它展示了在不使用准引号的情况下创建伴随对象。